Dia*_*adt 6 oauth-2.0 thinktecture-ident-model asp.net-web-api2
我正在设置我自己的 OAuth2 服务器。到目前为止,我已经成功地实现GrantResourceOwnerCredentials了我的OAuthAuthorizationServerProvider. 现在,因为我正在为我们的业务开发应用程序,所以我想实施 OAuth2 授权代码授权。
我试图按照这里的指示https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server但在我的实施中,我没有找到了如何达到(我在 中设置的)的Create调用。AuthorizationCodeProviderOAuthAuthorizationServerOptions
我已经简要检查了TokenEndpointPath使用(错误的)代码参数访问 是否有效,并且在调试器中我看到我AuthorizationCodeProvider的Receive调用被击中。当然没有成功,因为我发送的代码是“sometestcode”而不是真正的代码,但是代码被命中了,这意味着我走在正确的道路上。
这是我到目前为止所拥有的:
public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
{
if (OAuthRepository.GetClient(context.ClientId) != null)
{
var expectedRootUri = new Uri(context.Request.Uri, "/");
if (context.RedirectUri.StartsWith(expectedRootUri.AbsoluteUri))
{
context.Validated();
return Task.FromResult<object>(null);
}
}
context.Rejected();
return Task.FromResult<object>(null);
}
public override Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
// I know this is wrong but it's just a start and not the focus of this SO question.
context.Response.Redirect(context.AuthorizeRequest.RedirectUri);
context.RequestCompleted();
return Task.FromResult<object>(null);
}
public override Task GrantAuthorizationCode(OAuthGrantAuthorizationCodeContext context)
{
// Needs additional checks, not the focus of my question either
var newTicket = new AuthenticationTicket(context.Ticket.Identity, context.Ticket.Properties);
context.Validated(newTicket);
return Task.FromResult<object>(null);
}
Run Code Online (Sandbox Code Playgroud)
现在,当我AuthorizeEndpointPath用 a调用 my时redirect_uri,我会立即被发送到那个Uri。我知道这是错误的:我应该被发送到一个单独的登录页面。稍后我将修复我的 Web API 以重定向到正确的 Uri。
我的问题的重点是:我现在正在实现登录页面,但我不知道如何在用户登录后从我的 WebAPI 获取授权码。(我跳过了同意部分现在并假设如果用户已登录他们可以接受,我稍后会添加同意。)
我的流程基于此处共享的图表https://docs.apigee.com/api-platform/security/oauth/oauth-v2-policy-authorization-code-grant-type
我正在使用 Thinktecture IdentityModel 在 MVC 控制器中创建登录页面。现在我需要从我的 MVC 控制器中的 Web API 检索授权代码。之后,我可以将用户重定向回请求授权代码流的原始客户端(应用程序)。
为了从我的 Web API 获取授权码,我在 Thinktecture 的 OAuth2Client 中看到了三个方法:
两者似乎都没有做我想做的。如何进行以便调用我的 WebAPI 来生成代码?
[HttpGet]
[ImportModelStateFromTempData]
public ActionResult Authorize(string clientId, string returnUrl, string responseType)
{
AuthorizeViewModel viewModel = new AuthorizeViewModel();
...
...
...
return View(viewModel);
}
[HttpPost]
[ExportModelStateToTempData]
public async Task<ActionResult> Authorize(AuthorizeViewModel viewModel)
{
// NOTE: This is in MVC and is postback from *.cshtml View.
OAuth2Client.?????? // <=== How to obtain authorization code from WebAPI?
...
return Redirect(returnUrl);
}
Run Code Online (Sandbox Code Playgroud)
我想我在 Web API 端正确设置了它。我只是不知道如何击中Create流程的一部分。我希望有人能帮助我理解我没有看到的东西。我有一个盲点,我认为...
我如何让 OAuth2Client 从我的 WebAPI 获取授权码?
我也在使用 Postman 来测试我的 Web API。如果有人可以帮助我获取 Web API 2.0 中返回授权码的 URL,我也会接受它作为答案。然后我可以自己在MVC中编写代码。
好的,所以我想我找到了我的盲点的一部分。首先,我将“AuthorizeEndpoint”标记为“不是这个 SO 问题的重点”,但这是一个很大的错误。
当我像这样调整 AuthorizeEndpoint 时:
public override Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
System.Security.Claims.ClaimsIdentity ci = new System.Security.Claims.ClaimsIdentity("Bearer");
context.OwinContext.Authentication.SignIn(ci);
context.RequestCompleted();
return Task.FromResult<object>(null);
}
Run Code Online (Sandbox Code Playgroud)
如果我AuthorizationCodeProvider.Create像这样调整我的实现:
public void Create(AuthenticationTokenCreateContext context)
{
context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;
context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddSeconds(60);
// Some random Guid
context.SetToken(Guid.NewGuid().ToString("n"));
}
Run Code Online (Sandbox Code Playgroud)
任何调用都/authorize被重定向到redirect_uri 一个查询参数code=<THE_RANDOM_GUID>!:D
显然,这个实现不是它应该的地方,所以我的问题还没有解决。遗留问题:
ValidateClientAuthentication显然不是作为 的一部分命中的AuthorizeEndpoint。如何在 AuthorizeEndpoint 中获取 ClientId?AuthorizationCodeProvider.Create以便我可以将其与代码一起存储?ClaimsIdentity登录用户的信息?于是,经过一番网上搜索,我通过搜索github获得了一些成功。显然,OAuthAuthorizationServerProvider优惠AuthorizeEndpoint和该方法应该用于“嘿,你没有获得授权,请登录你!” 以及“啊,好吧,你很酷,这是一个授权码。”。我原以为OAuthAuthorizationServerProvider会有两种单独的方法来实现这一点,但事实并非如此。AuthorizeEndpoint这就解释了为什么在 github 上,我发现一些项目以一种相当奇特的方式实现。我已经采用了这个。这是一个例子:
public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context)
{
if (context.Request.User != null && context.Request.User.Identity.IsAuthenticated)
{
var redirectUri = context.Request.Query["redirect_uri"];
var clientId = context.Request.Query["client_id"];
var authorizeCodeContext = new AuthenticationTokenCreateContext(
context.OwinContext,
context.Options.AuthorizationCodeFormat,
new AuthenticationTicket(
(ClaimsIdentity)context.Request.User.Identity,
new AuthenticationProperties(new Dictionary<string, string>
{
{"client_id", clientId},
{"redirect_uri", redirectUri}
})
{
IssuedUtc = DateTimeOffset.UtcNow,
ExpiresUtc = DateTimeOffset.UtcNow.Add(context.Options.AuthorizationCodeExpireTimeSpan)
}));
await context.Options.AuthorizationCodeProvider.CreateAsync(authorizeCodeContext);
context.Response.Redirect(redirectUri + "?code=" + Uri.EscapeDataString(authorizeCodeContext.Token));
}
else
{
context.Response.Redirect("/account/login?returnUrl=" + Uri.EscapeDataString(context.Request.Uri.ToString()));
}
context.RequestCompleted();
}
Run Code Online (Sandbox Code Playgroud)
至于我剩下的三个问题:
答案:您必须实施“ValidateClientAuthentication”。
答:OAuthAuthorizationServerProvider照顾这个。只要您在票证中设置“client_id”,它就会检查请求授权码的访问令牌的客户端是否相同。
答:您创建一个单独的登录页面。其作用是让用户登录。如果您的 WebAPI 使用基于 cookie 的身份验证,您只需将用户重定向到另一个即可AuthorizeEndpoint。如果您使用访问令牌,您的登录页面必须使用访问令牌向“AuthorizeEndpoint”发出请求以获取授权码。(不要将访问令牌提供给第三方。您的登录页面请求授权代码并将其发回。)换句话说,如果您使用访问令牌,则此流程中涉及两个客户端。
| 归档时间: |
|
| 查看次数: |
2415 次 |
| 最近记录: |