ASP.NET Core 2.0 JWTvalidation因“用户授权失败:(null)”错误而失败

我正在使用ASP.NET Core 2.0应用程序(Web API)作为JWT发行者来生成移动应用程序的令牌消费品。 不幸的是,这个令牌无法由一个控制器validation,而另一个控制器可以validation(在同一个asp.net核心2.0应用程序中使用相同的validation设置)。

所以我有一个有效且可以解码的令牌,具有所有必需的声明和时间戳。 但是一个端点接受它,而另一个端点给我401错误和调试输出:

Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:信息:用户授权失败:(null)。

[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed for user: (null). Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: (null). [40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. 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 (). [40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.ChallengeResult[1] Executing ChallengeResult with authentication schemes (). [40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12] AuthenticationScheme: Bearer was challenged. Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: Bearer was challenged. [40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] Executed action MyController.Get (WebApi) in 72.105ms Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action MyController.Get (WebApi) in 72.105ms Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 271.077ms 401 [40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 271.077ms 401 

我的validation设置如下:

 var secretKey = Configuration["Authentication:OAuth:IssuerSigningKey"]; var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = Configuration["Authentication:OAuth:Issuer"], ValidateAudience = true, ValidAudience = Configuration["Authentication:OAuth:Audience"], ValidateLifetime = true, ClockSkew = TimeSpan.Zero, }; services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.TokenValidationParameters = tokenValidationParameters; }); 

这两个端点是相同的,只存在于不同的控制器中,两者都标有Authorize属性。

怎么可能?

configure函数中add语句的顺序非常重要。 确保这一点

 app.UseAuthentication(); 

来之前

 app.UseMvc(); 

这可能是问题吗?

在您的startup.cs中,如果添加,则为ConfigureServices方法

 services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => ... 

说明:在控制器上使用[授权]时 ,它默认绑定到第一个授权系统。

 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 

有了这个,您将默认设置为JWT Bearer身份validation。

另外你可以添加

 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 

这一行是如何防止在使用Identity与JWT时发现404未找到的错误。 如果您使用身份,DefaultChallengeScheme将尝试将您重定向到登录页面,如果不存在将导致找不到404而不是未经授权的401。 通过在未经授权的情况下将DefaultChallengeScheme设置为JwtBearerDefaults.AuthenticationScheme,它将不再尝试将您重定向到登录页面

如果您在[授权]标记中使用带有JWT身份validation的Cookie身份validation,则可以指定所需的authenticationScheme。 例如

 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] 

在startup.cs中尝试这个

 services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(opts => ... 

我补充说:

 app.UseAuthentication(); 

Startup.Configure() ,我为我解决了这个错误。

参考: Auth 2.0迁移公告

这似乎是您未正确validationJWT时收到的行为。 由于在标题中输入“Bearer:(JWT)”而不是“Bearer(JWT)”,我遇到了这个问题

您可以尝试这样做:

 .AddJwtBearer(options => { AutomaticAuthenticate = true, AutomaticChallenge = true, options.RequireHttpsMetadata = false; options.TokenValidationParameters = tokenValidationParameters; });'