.NET WebAPI中Bearer Token搭配[Authorize]始终返回401未授权问题
看起来你已经搞定了Token生成的环节,但API始终没法正确验证你的Bearer Token,导致返回401。这大概率是认证中间件没配置或配置不匹配导致的,我来帮你一步步排查解决:
1. 必须配置JWT认证服务(核心步骤!)
你只贴了控制器代码,但.NET WebAPI需要在Program.cs(.NET 6+)或Startup.cs中配置JWT认证中间件,才能识别并验证Token。
添加以下配置,注意参数要和你生成Token时的设置完全一致:
// .NET 6+ Program.cs 示例代码 var builder = WebApplication.CreateBuilder(args); // 添加控制器服务 builder.Services.AddControllers(); // 配置JWT认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { // 开启核心验证项 ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, // 和你生成Token时的Issuer完全匹配 ValidIssuer = "imarh.Security.Bearer", // 和你生成Token时的Audience完全匹配 ValidAudience = "imarh.Security.Bearer", // 密钥必须和生成Token时的一模一样 IssuerSigningKey = JwtSecurityKey.Create("imarh-secret-key") }; }); // 添加授权服务 builder.Services.AddAuthorization(); var app = builder.Build(); // 中间件顺序不能乱!认证必须在授权之前执行 app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
⚠️ 重点提醒:ValidIssuer、ValidAudience、IssuerSigningKey这三个参数的内容、大小写、特殊字符都要和生成Token时完全一致,差一个字符都会导致验证失败。
2. 检查请求头格式是否正确
发送请求时,Authorization请求头的格式必须是:
Bearer {你的Token字符串}
注意Bearer和Token之间有一个空格,很多新手会漏掉这个空格,导致服务端无法识别Token。你可以用Postman或浏览器开发者工具(Network标签)检查请求头是否符合要求。
3. 验证Token本身的有效性
你可以用jwt.io(本地解码,不会上传数据)把生成的Token贴进去,检查以下几点:
iss字段是否等于imarh.Security.Beareraud字段是否等于imarh.Security.Bearerexp字段的过期时间是否在当前时间之后(你用了.AddExpiry(1),要确认这个参数是小时还是分钟,如果是分钟的话Token会很快过期)
4. 确认中间件顺序正确
在Program.cs中,中间件的顺序必须遵循:UseRouting() → UseAuthentication() → UseAuthorization() → MapControllers()
如果UseAuthentication()在UseAuthorization()之后,授权会先执行,此时还没完成认证,就会直接返回401。
5. 排查JwtTokenBuilder的实现
确保你的JwtTokenBuilder是基于标准JWT库(比如System.IdentityModel.Tokens.Jwt)实现的,默认算法是HS256,你的密钥"imarh-secret-key"长度是16字节,刚好满足HS256的最低要求(16字节),如果是其他算法可能需要更长的密钥。
按照以上步骤排查,应该能解决401的问题。如果还是不行,可以把Program.cs的配置代码贴出来,或者把解码后的Token内容(隐藏敏感信息)发出来,方便进一步定位问题。
内容的提问来源于stack exchange,提问作者iMarh

