【发布时间】:2019-06-05 20:00:11
【问题描述】:
我遇到了 .NET Core 如何在我的生产环境中处理 JSON Web Token (JWT) 身份验证的问题。我正在使用 Postman 进行测试。如果我使用有效令牌调用我的 API,它可以正常工作并从 API 端点返回预期的响应。但是,如果令牌过期,我不会得到预期的 HTTP 401。事实上,我没有得到任何响应,它只是悄悄地失败了。这似乎是我的生产配置不起作用。如果我在本地开发环境中对此进行测试,我没有任何问题,并且过期的令牌会像预期的那样得到 401 未授权的 HTTP 响应。
我的网络应用对通过网站登录的用户使用 cookie 身份验证,对连接到 API 的用户使用 JWT 身份验证。这是 JWT 身份验证的配置。这是在 Startup.cs 中。这是 services.Authentication 的 JWT 配置部分。 cookie 身份验证是首先设置的,是默认的身份验证方案。
.AddJwtBearer(options =>{
options.RequireHttpsMetadata = !_hostingEnvironment.IsDevelopment();
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Settings.Api.JwtBearer.TokenValidation.ValidIssuer,
ValidAudience = Settings.Api.JwtBearer.TokenValidation.ValidAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Settings.Api.JwtBearer.TokenValidation.IssuerSigningKey))
};
options.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
context.Response.ContentType = "application/json; charset=utf-8";
var message = _hostingEnvironment.IsDevelopment() ? context.Exception.ToString() : "An error occurred processing your authentication.";
var result = JsonConvert.SerializeObject(new { message });
return context.Response.WriteAsync(result);
}
};});
这里是 Startup.cs 中的其他相关配置:
public void Configure(IApplicationBuilder app, IHostingEnvironment env){
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error/Exception");
app.UseStatusCodePagesWithReExecute("/Error/{0}");
app.UseHsts();
app.UseHttpsRedirection();
}
app.UseStaticFiles();
app.UseCors(Constants.Security.Cors.PolicyName);
app.UseAuthentication();
app.UseMvc(ConfigureRoutes);}
` 我已经使用了很多配置设置并在生产中进行了测试,但是当令牌身份验证失败时,我总是没有得到任何响应。由于它在我的本地开发环境中运行良好,这一定意味着我的生产配置有问题,但我被难住了,没有想法。有关更多信息,这里是错误日志中的错误示例:
信息: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1] 无法验证令牌。 Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223:生命周期验证失败。令牌已过期。有效: '[PII 已隐藏]',当前时间:'[PII 已隐藏]'。在 Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable
1 notBefore, Nullable1 过期, SecurityToken securityToken, TokenValidationParameters 验证参数)在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable1 notBefore, Nullable1 过期, JwtSecurityToken jwtToken, TokenValidationParameters 验证参数)在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters 验证参数)在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(字符串 令牌、TokenValidationParameters 验证参数、SecurityToken& 验证令牌)在 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.d__6.MoveNext() 信息: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7] 承载未通过身份验证。失败消息:IDX10223:生命周期验证失败。令牌已过期。 ValidTo: '[PII 是 hidden]', 当前时间:'[PII is hidden]'。信息: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 授权失败。信息:Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3] 过滤器“Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter”处的请求授权失败。信息: Microsoft.AspNetCore.Mvc.ChallengeResult[1] 使用身份验证方案(承载)执行 ChallengeResult。信息:Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] 在 109.4625 毫秒内执行操作 Web.Controllers.ApiController.Users (Web) 信息:Microsoft.AspNetCore.Routing.EndpointMiddleware[1] 执行端点“Web.Controllers.ApiController.Users (Web)”失败:Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1] 执行请求时发生未处理的异常。 System.InvalidOperationException:无法设置 StatusCode,因为 响应已经开始。在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 值)在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 值)在 Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode(Int32 值)在 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.d__7.MoveNext()
提前感谢您提供有关如何解决此问题的任何想法。
【问题讨论】:
-
这是您的错误:失败:Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1] 执行请求时发生未处理的异常。 System.InvalidOperationException:无法设置 StatusCode,因为响应已经开始。
-
我只有在覆盖响应的状态码时才会发生这种情况,换句话说,当通过中间件放置响应并且该中间件更改了响应的状态码时,您会收到此错误。希望这能帮助您找到问题。
-
是的,这似乎是问题所在。但是,我仍然存在如何使用 401 返回自定义错误消息的问题。
标签: authentication asp.net-core jwt http-status-code-401