gpt4 book ai didi

oauth-2.0 - AuthorizationCodeProvider : Create is never called, 如何生成授权码?

转载 作者:行者123 更新时间:2023-12-01 04:28:52 35 4
gpt4 key购买 nike

我正在设置我自己的 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使用(错误的)代码参数有效,并且在调试器中我看到我的 AuthorizationCodeProviderReceive调用被击中。当然没有成功,因为我发送的代码是“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);
}

现在,当我调用我的 AuthorizeEndpointPathredirect_uri ,我立即被送到那个乌里。我知道这是错误的:我应该被发送到一个单独的登录页面。稍后我将修复我的 Web API 以重定向到正确的 Uri。

我的问题的重点是:我现在正在实现登录页面,但我不知道如何在用户登录后从我的 WebAPI 获取授权码。(我跳过了同意部分现在并假设如果用户已登录他们可以接受,我稍后会添加同意。)

我的流程基于此处共享的图表 https://docs.apigee.com/api-platform/security/oauth/oauth-v2-policy-authorization-code-grant-type

我正在使用 Thinktecture IdentityModel 在 MVC Controller 中创建登录页面。现在我需要从我的 MVC Controller 中的 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重定向到 redirect_uri 带有查询参数 code=<THE_RANDOM_GUID> ! :D

    显然,这个实现不是它应该的地方,所以我的问题还没有解决。遗留问题:
  • 现在,任何人 可以请求授权码,client_id 被忽略。 ValidateClientAuthentication显然不是 AuthorizeEndpoint 的一部分.如何在 AuthorizeEndpoint 中获取 ClientId?
  • 授权码不耦合到客户端。任何拦截代码的人都可以使用它。如何在 AuthorizationCodeProvider.Create 中获取 ClientId以便我可以将其与代码一起存储?
  • 授权代码根本不与用户耦合,它是一个空的 ClaimsIdentity。如何在 AuthorizeEndpoint 之间和中放置用户登录页面获取 ClaimsIdentity对于登录用户?
  • 最佳答案

    所以,在网上搜索了一些之后,我通过搜索github获得了一些成功。显然,OAuthAuthorizationServerProvider提供 AuthorizeEndpoint并且该方法应该用于“嘿,你没有被授权,去登录你!”以及“啊,好吧,你很酷,这是一个授权码。”。我原以为OAuthAuthorizationServerProvider将有两个单独的方法,但它没有。这就解释了为什么在 github 上,我找到了一些实现 AuthorizeEndpoint 的项目。以一种相当奇特的方式。我采用了这个。下面是一个例子:

    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();
    }

    来源: https://github.com/wj60387/WebApiOAUthBase/blob/master/OwinWebApiBase/WebApiOwinBase/Providers/OAuthServerProvider.cs

    至于我剩下的三个问题:
  • 现在,任何人都可以请求授权码,client_id 被忽略。 ValidateClientAuthentication 显然不是 AuthorizeEndpoint 的一部分。如何在 AuthorizeEndpoint 中获取 ClientId?

  • 答:您必须实现“ValidateClientAuthentication”。
  • 授权码不耦合到客户端。任何拦截代码的人都可以使用它。如何在 AuthorizationCodeProvider.Create 中获取 ClientId 以便我可以将它与代码一起存储?

  • 答案: OAuthAuthorizationServerProvider照顾这个。只要您在票证中设置“client_id”,它就会检查为授权码请求访问 token 的客户端是否相同。
  • 授权代码根本不与用户耦合,它是一个空的 ClaimsIdentity。如何在 AuthorizeEndpoint 之间和中放置用户登录页面以获取登录用户的 ClaimsIdentity?

  • 答:您创建一个单独的登录页面。这样做是让用户登录。如果您的 WebAPI 使用基于 cookie 的身份验证,您可以将用户重定向到 AuthorizeEndpoint。再次。如果您使用访问 token ,您的登录页面必须使用访问 token 向“AuthorizeEndpoint”发出请求以获取授权代码。 (不要将访问 token 提供给第三方。您的登录页面请求授权代码并将其发回。)换句话说,如果您使用访问 token ,则此流程中涉及两个客户端。

    关于oauth-2.0 - AuthorizationCodeProvider : Create is never called, 如何生成授权码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55722767/

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