gpt4 book ai didi

authentication - OWIN/OAuth2 3rd 方登录 : Authentication from Client App, 来自 Web API 的授权

转载 作者:行者123 更新时间:2023-12-04 01:11:19 24 4
gpt4 key购买 nike

我正在尝试创建一个 Web API,允许 API 的客户端( native 移动应用程序)使用 3rd 方云存储提供商登录。我正在使用来自 Microsoft 的以下一般流程:



这是我想要实现的目标:



我使用带有外部身份验证的默认 ASP.NET Web API Visual Studio 模板以及 OWin.Security.Providers用于 Dropbox 登录功能的 Nuget 包,以及适用于 Google (Drive) 和 Microsoft (OneDrive) 的现有内置登录功能。

我遇到的问题是,所有内置功能似乎都将身份验证和授权作为一个流程的一部分。例如,如果我在 Startup.Auth.cs 中设置以下内容:

DropboxAuthenticationOptions dropboxAuthOptions = new DropboxAuthenticationOptions
{
AppKey = _dropboxAppKey,
AppSecret = _dropboxAppSecret
};
app.UseDropboxAuthentication(dropboxAuthOptions);

...并从我的网络浏览器导航到此网址:
http://<api_base_url>/api/Account/ExternalLogin?provider=Dropbox&response_type=token&client_id=self&redirect_uri=<api_base_url>

我已成功重定向到 Dropbox 以登录:
https://www.dropbox.com/1/oauth2/authorize?response_type=code&client_id=<id>&redirect_uri=<redirect_uri>

...然后在我授予访问权限后,被重定向回:
http://<api_base_url>/Help#access_token=<access_token>&token_type=bearer&expires_in=1209600

...如您所见, token 是其中的一部分,因此可以提取。问题是客户端需要导航到 Dropbox 并将授权代码返回给 Web API,Web API 会将授权代码发送回第三方以获取 token ,然后将 token 返回给客户端...如上图所示。我需要 AccountController 中的 ExternalLogin 操作以某种方式检索 Dropbox url 并将其返回给客户端(它只是一个 json 响应),但我没有看到检索它的方法(它只返回一个 ChallengeResult,并且实际的 Dropbox 网址被埋在某处)。另外,我想我需要一种方法来根据授权码从第三方单独请求 token 。

这篇文章似乎与我想要做的有点相似:

Registering Web API 2 external logins from multiple API clients with OWIN Identity

...但那里的解决方案似乎要求客户端是一个 MVC 应用程序,这对我来说不一定如此。我希望在客户端尽可能简单,按照上图中的流程进行操作,但也不要重新发明轮子(尽可能多地重用 OWIN/OAuth2 实现中已经存在的内容)。理想情况下,我不希望客户端必须引用任何 OWIN/OAuth 库,因为我真正需要客户端做的就是访问 API(在我的示例中为 Dropbox)提供的外部 URL,让用户输入他们的凭据并给予许可,并将生成的授权码发送回 api。

从概念上讲,这听起来并不难,但我不知道如何实现它,并且仍然尽可能多地使用现有的 OAuth 代码。请帮忙!

最佳答案

需要明确的是,我在您发布的链接中提到的示例可以与任何 OAuth2 客户端一起使用,使用任何受支持的流程(隐式、代码或自定义)。在与自己的授权服务器通信时,如果您想使用 JS 或移动应用程序,当然可以使用隐式流程:您只需要使用 response_type=token 构建授权请求即可。并从 JS 端的 URI 片段中提取访问 token 。

http://localhost:55985/connect/authorize?client_id=myClient&redirect_uri=http%3a%2f%2flocalhost%3a56854%2f&response_type=token

作为引用,这里是示例:https://github.com/aspnet-security/AspNet.Security.OpenIdConnect.Server/tree/dev/samples/Mvc/Mvc.Server

如果您更喜欢更简单的方法(不涉及自定义 OAuth2 授权服务器),这里有另一种选择,使用 OAuth2 承载身份验证中间件并实现自定义 IAuthenticationTokenProvider手动验证由 Dropbox 发出的不透明 token 。与上面提到的示例(充当 Dropbox 和 MVC 客户端应用程序之间的授权代理服务器)不同,JS 应用程序直接向 Dropbox 注册。

您必须使用收到的 token 向 Dropbox 配置文件端点 ( https://api.dropbox.com/1/account/info ) 发出请求以对其进行验证并构建适当的 ClaimsIdentity您的 API 收到的每个请求的实例。这是一个示例(但请不要按原样使用它,它还没有经过测试):

public sealed class DropboxAccessTokenProvider : AuthenticationTokenProvider {
public override async Task ReceiveAsync(AuthenticationTokenReceiveContext context) {
using (var client = new HttpClient()) {
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.dropbox.com/1/account/info");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.Token);

var response = await client.SendAsync(request);
if (response.StatusCode != HttpStatusCode.OK) {
return;
}

var payload = JObject.Parse(await response.Content.ReadAsStringAsync());

var identity = new ClaimsIdentity("Dropbox");
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, payload.Value<string>("uid")));

context.SetTicket(new AuthenticationTicket(identity, new AuthenticationProperties()));
}
}
}

您可以通过 AccessTokenProvider 轻松插入它属性(property):
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions {
AccessTokenProvider = new DropboxAccessTokenProvider()
});

它有其自身的缺点:它需要缓存以避免淹没 Dropbox 端点,如果您想接受不同提供商(例如 Dropbox、Microsoft、Google、Facebook)发布的 token ,这不是正确的方法。

更不用说如果提供 极低的安全级别 :由于您无法验证访问 token 的受众(即 token 颁发给的一方),您无法确保将访问 token 颁发给您完全信任的客户端应用程序,这允许任何第三方开发人员在您的 API 中使用他自己的 Dropbox token ,而无需征得用户同意。

这显然是一个主要的安全问题,这就是您 的原因。应该 更喜欢链接示例中使用的方法。您可以在此线程上阅读有关混淆副攻击的更多信息: https://stackoverflow.com/a/17439317/542757 .

祝你好运,如果您仍然需要帮助,请不要犹豫。

关于authentication - OWIN/OAuth2 3rd 方登录 : Authentication from Client App, 来自 Web API 的授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28487586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com