.NET Core 2中JWT令牌验证失效,调用授权接口返回401未授权
兄弟,我之前也碰到过一模一样的问题!能生成JWT但带Bearer令牌调用授权接口返回401,大概率是配置顺序、参数匹配或者细节上的小疏漏,咱们一步步来排查:
先检查中间件注册顺序
这是最容易踩的坑!在Startup.cs的Configure方法里,UseAuthentication()必须放在UseAuthorization()前面,而且要夹在UseRouting()和UseEndpoints()之间,正确顺序应该是这样:app.UseRouting(); app.UseAuthentication(); // 这个一定要在UseAuthorization前面! app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });如果顺序搞反了,认证逻辑根本没机会执行,直接就返回401了。
验证JWT生成与验证的参数完全匹配
生成令牌和验证令牌的**密钥、颁发者(Issuer)、受众(Audience)**必须完全一致,差一个字符都不行!
先看ConfigureServices里的JWT验证配置:services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], // 和生成令牌时的Issuer必须一模一样 ValidAudience = Configuration["Jwt:Audience"], // 受众也要完全匹配 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) // 密钥不能错 }; });再检查你生成令牌的代码,必须用相同的参数:
var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]); var tokenDescriptor = new SecurityTokenDescriptor { Issuer = Configuration["Jwt:Issuer"], Audience = Configuration["Jwt:Audience"], Expires = DateTime.UtcNow.AddHours(1), // 这里要用UtcNow,避免时区问题导致提前过期 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor);确认Postman的Authorization头格式正确
别小看这个细节!Postman里的Authorization头必须是Bearer <你的JWT令牌>,Bearer后面一定要有一个空格。最稳妥的方式是直接在Postman的「Authorization」选项卡选择「Bearer Token」,然后粘贴令牌,这样就不会手动输入出错了。检查令牌是否过期或无效
把你的JWT令牌复制出来,自己解码看看exp字段对应的时间是不是已经过期了。另外生成令牌时一定要用DateTime.UtcNow设置过期时间,别用本地时间,不然可能因为时区差导致令牌提前失效。给授权接口加上正确的
[Authorize]属性
确保你调用的接口控制器或方法上标注了[Authorize]属性,而且没有指定和默认认证方案不一致的方案:[ApiController] [Route("api/[controller]")] [Authorize] // 必须加上这个,不然接口不会触发认证逻辑 public class ProtectedController : ControllerBase { // 你的授权接口方法 }启用日志看具体错误原因
如果上面的步骤都排查了还是不行,那就给JWT中间件加个日志事件,看看认证失败的具体原因:options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { Console.WriteLine($"认证失败细节: {context.Exception.Message}"); return Task.CompletedTask; }, OnTokenValidated = context => { Console.WriteLine("令牌验证成功啦!"); return Task.CompletedTask; } };运行程序后看控制台输出,就能知道是密钥不匹配、颁发者错误还是令牌过期之类的具体问题了。
内容的提问来源于stack exchange,提问作者Reza Del

