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; });'