JWT BearerHandler令牌失败,但请求仍在处理中

时间:2019-07-02 10:28:33

标签: jwt identityserver4 asp.net-authorization

我遇到了一个非常奇怪的问题,我猜想我的设置中缺少某些东西。

我有一个由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()方法中,但是它没有帮助,猜想我写错了。

最佳问候 马格努斯

2 个答案:

答案 0 :(得分:0)

花了一天时间弄清楚为什么它不起作用后,我决定逐步研究Microsoft代码,并在AuthenticationMiddleware中找到了它。

公共类AuthenticationMiddleware {     私有只读RequestDelegate _next;

lucy

}

基本上,发生的事情是结果具有包含我的身份验证异常的“失败”属性,但是由于在代码中没有对此进行检查,因此它将继续向管道中的下一个中间件发出请求。因此,我基本上写了我自己的AuthenticationMiddleware,添加了一个检查Failure是否具有值的检查,然后返回403。

lucy

但是,除了我之外,别无他法,因此,如果有人知道我为什么需要这样做,我将很高兴获得这些信息。

答案 1 :(得分:0)

在遇到同一问题后,我遇到了这篇文章。经过一番敲打,我发现这是由于使用services.AddMvcCore()(在我的情况下为.AddJsonFormatters()。AddDataAnnotations())而不是使用services.AddMvc()引起的。只有使用.AddMvcCore(),我才能获得401令牌验证失败的消息。

似乎在使用.AddMvcCore时需要将.AddAuthorization()添加到混合中,因为默认情况下未添加它。如果没有它,令牌验证将失败,但是请求管道会相当愉快地继续。