当未直接获取访问令牌时,使用 .Net HttpClient 使用 Rest API 会导致授权失败

Consuming Rest API with .Net HttpClient fails Authorization when Access Token is not gotten directly

服务器是一个 .net 核心 API,它使用 Identity authentication/authorization 和 SimpleTokenProvider 来生成 JWT 令牌。特定端点需要角色授权。

[Authorize(Roles = "Admin")]

当我从不同的控制器操作方法获取令牌时,将令牌保存在会话中并尝试使用该令牌调用 API,或者当我对从 Postman 获取的令牌进行硬编码并且将其传递给 API,用户在服务器上获得身份验证,但无法授权。

用户获得授权的唯一方法是我在同一控制器操作方法中请求令牌。它也适用于 Postman。

客户端代码如下:

    string token = "ew0KICAiYWxnIjogIkhTMjU2IiwNCiAg...";

    HttpClient client = new HttpClient(handler);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));    
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
    HttpResponseMessage httpResponse = client.GetAsync("http://localhost:5001/api/dashboard").Result;
          if (httpResponse.IsSuccessStatusCode)
          {
             Console.Write(httpResponse.Content.ReadAsStringAsync().Result);
          }  

根据服务器日志,对同一端点的授权调用如下:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5001/api/dashboard     
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware:Information: HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Identity.Application.
    Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: Successfully validated the token.
    Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Bearer.
    Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization was successful for user: xxxxx.
    Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization was successful for user: xxxxx.

而未经授权的调用有以下日志:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5001/api/dashboard  
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: Successfully validated the token.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: HttpContext.User merged via AutomaticAuthentication from authenticationScheme: Bearer.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization was successful for user: xxxxx.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: xxxxx.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware:Information: AuthenticationScheme: Bearer was forbidden.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware:Information: AuthenticationScheme: Identity.Application was challenged.

我不知道需要向 HttpClient 添加什么其他选项才能使授权生效。

在使用 wireshark 跟踪来自 HttpClient 和 Postman 的请求的差异后,我发现 .Net Identity 在用户登录后设置了一个名为 .AspNetCore.Identity.Application 的 Cookie,它必须作为请求的一部分发送工作授权。

获取cookie并将其设置为后续请求的一部分后,它工作正常。