首页 > 解决方案 > User is authenticated but where is the access token?

问题描述

I have a web Application which authenticates a user to an Identity Server 4, using an implicit client. I need the access token for this user so that I can make a call to another API.

To be clear:

  1. I have an identity Server. Created using Identity server 4.
  2. I have the web app in question created in Asp .net core mvc.
  3. API created in .net core.

The Web application authenticates the user against the identity server. Once they are authenticated we use bearer tokens to access the 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";
            });

The user is authenticating fine and i am able to access the controller below. I need an access token for this user so that i can make a request to another 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();
    }

The following does contain a header called cookie. Is there a way of getting the access token out of that?

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

How can i find an access token for the current authenticated user? Using Implicit login.

Note on Hybrid vs implicit login: I cant use hybrid login due to the issue posted here Authentication limit extensive header size As i have not been able to find a solution to that problem a suggestion was to switch to an implicit login rather than hybrid. Implicit does not appear to create the giant cooking the hybrid did.

I have been following this to create the implicit client Getting started with Identityserver 4

标签: c#asp.net-core-mvcidentityserver4

解决方案


默认情况下,OpenID Connect 中间件仅请求身份令牌(a response_typeof id_token)。

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

options.ResponseType = "id_token token";

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

options.SaveTokens = true;

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

await HttpContext.GetTokenAsync("access_token");

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


推荐阅读