当未直接获取访问令牌时,使用 .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并将其设置为后续请求的一部分后,它工作正常。
服务器是一个 .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并将其设置为后续请求的一部分后,它工作正常。