我正在设置自己的 OAuth2 服务器。到目前为止,我已经成功实现GrantResourceOwnerCredentials
了OAuthAuthorizationServerProvider
. 现在,因为我正在为我们的业务开发应用程序,所以我想实现 OAuth2 授权代码授权。
我试图按照这里的指示https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server但在我的实施中,我没有找到了如何到达(我在 中设置的)的Create
调用。AuthorizationCodeProvider
OAuthAuthorizationServerOptions
我已经简要检查了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);
}
现在,当我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 中看到了三种方法:
- CreateAuthorizeUrl
- CreateCodeFlowUrl
- RequestAuthorizationCodeAsync
似乎都没有做我想做的事。如何继续调用我的 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);
}
我想我在 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);
}
如果我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"));
}
任何调用都使用查询参数/authorize
重定向到!:Dredirect_uri
code=<THE_RANDOM_GUID>
显然,这个实现不是它应该在的地方,所以我的问题还没有解决。剩下的问题:
- 现在,任何人都可以请求授权码,client_id 被忽略。
ValidateClientAuthentication
显然没有作为AuthorizeEndpoint
. 如何在 AuthorizeEndpoint 中获取 ClientId? - 授权码不耦合到客户端。任何截获代码的人都可以使用它。如何获取 ClientId
AuthorizationCodeProvider.Create
以便可以将其与代码一起存储? - 授权代码根本不与用户耦合,它是一个空的 ClaimsIdentity。如何在 AuthorizeEndpoint 之间放置一个用户登录页面,并在其中获取
ClaimsIdentity
已登录用户的登录用户?