我遇到了一个非常奇怪的问题,我猜想我的设置中缺少某些东西。
我有一个由IdentityServer4保护的WebAPI。它仅使用Client_credentials。如果我输入了错误的ClientId和ClientSecret,则该用户未通过身份验证,并且无法连接到我的WebAPI。但是,如果我输入了错误的作用域名称,则请求仍会被处理,并且会返回响应,奇怪的是抛出了异常,但是由于某种原因,.NET Core Framework忽略了该异常。
这是我输出窗口中的一些调试信息。
Microsoft.AspNetCore.Hosting.Internal.WebHost:信息:请求启动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()方法中,但是它没有帮助,猜想我写错了。
最佳问候 马格努斯
答案 0 :(得分:0)
花了一天时间弄清楚为什么它不起作用后,我决定逐步研究Microsoft代码,并在AuthenticationMiddleware中找到了它。
公共类AuthenticationMiddleware { 私有只读RequestDelegate _next;
lucy
}
基本上,发生的事情是结果具有包含我的身份验证异常的“失败”属性,但是由于在代码中没有对此进行检查,因此它将继续向管道中的下一个中间件发出请求。因此,我基本上写了我自己的AuthenticationMiddleware,添加了一个检查Failure是否具有值的检查,然后返回403。
lucy
但是,除了我之外,别无他法,因此,如果有人知道我为什么需要这样做,我将很高兴获得这些信息。
答案 1 :(得分:0)
在遇到同一问题后,我遇到了这篇文章。经过一番敲打,我发现这是由于使用services.AddMvcCore()(在我的情况下为.AddJsonFormatters()。AddDataAnnotations())而不是使用services.AddMvc()引起的。只有使用.AddMvcCore(),我才能获得401令牌验证失败的消息。
似乎在使用.AddMvcCore时需要将.AddAuthorization()添加到混合中,因为默认情况下未添加它。如果没有它,令牌验证将失败,但是请求管道会相当愉快地继续。