【发布时间】:2019-11-12 23:33:00
【问题描述】:
我遇到了一个非常奇怪的问题,我猜我的设置中遗漏了一些东西。
我有一个由 IdentityServer4 保护的 WebAPI。它仅使用 Client_credentials。如果我写了错误的 ClientId och ClientSecret 该用户未通过身份验证,并且我无法连接到我的 WebAPI。但是如果我写了错误的范围名称,请求仍然被处理并且我得到了我的响应,奇怪的是抛出了一个异常,但由于某种原因它被 .NET Core Framework 忽略了。
这是我的输出窗口中的一些调试信息。
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: 请求开始 HTTP/1.1 GET https://localhost:44360/v1/bookings
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.
at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateAudience(IEnumerable`1 audiences, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Bearer was not authenticated. Failure message: IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'.
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executing endpoint 'TRS.BookingService.Api.Controllers.BookingsController.Get (TRS.BookingService.Api)'
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "Get", controller = "Bookings"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.ActionResult`1[System.Collections.Generic.IEnumerable`1[System.String]]] Get() on controller TRS.BookingService.Api.Controllers.BookingsController (TRS.BookingService.Api).
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method TRS.BookingService.Api.Controllers.BookingsController.Get (TRS.BookingService.Api) - Validation state: Valid
TRS.BookingService.Api.Controllers.BookingsController:Information: Getting all bookings
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action method TRS.BookingService.Api.Controllers.BookingsController.Get (TRS.BookingService.Api), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 96.2159ms.
Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor:Information: Executing ObjectResult, writing value of type 'System.String[]'.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action TRS.BookingService.Api.Controllers.BookingsController.Get (TRS.BookingService.Api) in 280.2344ms
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executed endpoint 'TRS.BookingService.Api.Controllers.BookingsController.Get (TRS.BookingService.Api)'
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 1345.3829ms 200 application/json; charset=utf-8
因此,即使抛出了表示令牌未验证的异常,仍然允许请求继续并执行并将响应发送回客户端。
这是 ConfigureServices 的样子:
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = "https://localhost:44392/";
options.Audience = "FAKE_SCOPE";
});
还有 Configure() 方法
app.UseAuthentication();
app.UseMvc();
这是 JWT 令牌的样子:
{
"nbf": 1562062882,
"exp": 1562066482,
"iss": "https://localhost:44392",
"aud": [
"https://localhost:44392/resources",
"bookingApi"
],
"client_id": "clientId",
"scope": [
"bookingApi"
]
}
这是调用 API 的客户端代码。
var idpUrl = "https://localhost:44392/";
var clientId = "clientId";
var clientSecret = "secret";
var scope = "bookingApi";
var accessToken = await GetAccessTokenAsync(new Uri(idpUrl), clientId, clientSecret, scope);
string content = await GetContent(new Uri("https://localhost:44360/v1/bookings"), accessToken);
我想我在授权方面错过了一些东西,我尝试了不同的
services.Authorization()
在 ConfigureServices() 方法中但是没有用,估计是我写错了。
最好的问候 马格努斯
【问题讨论】:
-
您是否在
BookingsController.Get()上方添加了Authorize属性? -
是的,否则没有进行任何授权。
-
我看到了你的答案。这一定不是预期的行为。过滤器(即)属性必须中断流程。而且我很确定它按预期对我有用。将重新检查。你用的是什么版本的asp.net core?它们的行为都略有不同
-
是的,我知道,这不应该是预期的行为。我用的是2.2版本。
-
从默认模板创建 API 解决方案。 “按原样”开始:从localhost:57358/api/values 得到
200。补充:services.AddAuthentication(options => {options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(options =>{options.Authority = "https://login.dev.xxx.com/"; //options.Audience = "FAKE_SCOPE";});+Authorize在Values控制器上——得到401+WWW-Authenticate: Bearer error="invalid_token", error_description="The audience is invalid"。
标签: jwt identityserver4 asp.net-authorization