【问题标题】:User is authenticated but where is the access token?用户已通过身份验证,但访问令牌在哪里?
【发布时间】:2018-11-07 01:04:15
【问题描述】:

我有一个 Web 应用程序,它使用隐式客户端向 Identity Server 4 验证用户。我需要此用户的访问令牌,以便调用另一个 API。

要明确:

  1. 我有一个身份服务器。使用身份服务器 4 创建。
  2. 我在 Asp .net core mvc 中创建了有问题的 Web 应用程序。
  3. 在 .net 核心中创建的 API。

Web 应用程序根据身份服务器对用户进行身份验证。一旦它们通过身份验证,我们就使用不记名令牌来访问 API。

 services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

 services.AddAuthentication(options =>
            {
                options.DefaultScheme = "cookie";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("cookie")
            .AddOpenIdConnect("oidc", options =>
            {
                options.Authority = Configuration["ServiceSettings:IdentityServerEndpoint"];
                options.ClientId = "f91ece52-81cf-4b7b-a296-26356f50841f";
                options.SignInScheme = "cookie";
            });

用户身份验证正常,我可以访问下面的控制器。我需要此用户的访问令牌,以便我可以向另一个 API 发出请求。

[Authorize]
public async Task<IActionResult> Index(int clientId, string error)
{
        ViewData["Title"] = "Secrets";

        if (User.Identity.IsAuthenticated)
        {

         // All of the below attempts result in either null or empty array
         var attempt1 = Request.Headers["Authorization"];
         var attempt2 = await HttpContext.GetTokenAsync("access_token");
         var attempt3 = _httpContextAccessor.HttpContext.Request.Headers["Authorization"];

         var attempt4 = await _httpContextAccessor.HttpContext.GetTokenAsync("access_token");

        }
        return View();
    }

以下确实包含一个名为 cookie 的标头。有没有办法从中获取访问令牌?

  var h = _httpContextAccessor.HttpContext.Request.Headers.ToList();

如何找到当前经过身份验证的用户的访问令牌?使用隐式登录。

关于混合登录与隐式登录的注意事项:由于Authentication limit extensive header size 此处发布的问题,我无法使用混合登录因为我无法找到该问题的解决方案,因此建议切换到隐式登录而不是混合登录。隐式似乎并没有创造出混合动力所做的巨大烹饪。

我一直在关注这个来创建隐式客户端Getting started with Identityserver 4

【问题讨论】:

  • 它应该是Authorization 而不是Authentication,这是传递令牌的默认约定。在尝试 1 中,您的标题名称不正确,在尝试 3 中,您有错字。
  • 改变但没有效果 _httpContextAccessor.HttpContext.Request.Headers.ToList();不包含授权标头。
  • 很可能它已经消失了。您已通过第三方提供商的身份验证,现在所需的所有信息都存储在 asp.net 创建的 cookie 中,并且访问令牌不再相关。
  • 它是我的身份服务器而不是第三方,我需要访问令牌来访问作为承载令牌发送的 api。那么无论如何要从cookie中获取访问令牌?
  • 它是你的,但在此应用程序的上下文中,它仍被视为第三方(外部)。我不认为访问令牌在 cookie 中的任何地方或此方案中的任何其他地方都可用。

标签: c# asp.net-core-mvc identityserver4


【解决方案1】:

默认情况下,OpenID Connect 中间件 only requests an identity tokenresponse_typeid_token)。

您需要先使用以下内容更新您的OpenIdConnectOptions

options.ResponseType = "id_token token";

然后您可以使用以下方法将令牌保存到您的 cookie:

options.SaveTokens = true;

最后,您可以使用以下方式访问令牌:

await HttpContext.GetTokenAsync("access_token");

请注意,使用隐式流时,您还需要在 IdentityServer 客户端配置中设置 AllowAccessTokensViaBrowser 标志。

【讨论】:

  • options.ResponseType = "id_token token";
  • (掌心)我认为添加任何 ResponseType 都会使其混合!我想我在某处读错了.....我明天试试看,谢谢
  • 好的,这是可行的,但是 HttpContext.User 不包含所有声明。这很奇怪,因为我可以看到 context.User 是在 AddOpenIdConnect 事件中设置的。
  • 您的身份令牌不再包含身份范围声明。您现在需要使用用户信息端点。在 OIDC 中间件中有一个选项可以做到这一点
【解决方案2】:

使用 options.SaveTokens = true 然后从声明中获取您的访问令牌或使用 HttpContext.GetTokenAsync 这是博客文章的链接,例如:https://www.jerriepelser.com/blog/accessing-tokens-aspnet-core-2/

【讨论】:

    【解决方案3】:

    我使用 IHttpContextAccessor 解决了:

     var token = _accessor.HttpContext.Request.Headers["Authorization"];
     return token.ToString().Replace("Bearer ", string.Empty);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-01
      • 2012-08-31
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多