.NET Core 6中JWT验证通过但Postman调用授权接口返回401求助
.NET Core 6 JWT认证401未授权问题排查与修复
问题情景
使用.NET Core 6创建的API项目,添加[Authorize]特性实现JWT权限控制后,jwt.io验证Token签名通过,但Postman调用受保护接口始终返回401未授权。
相关代码实现
API端点代码
[Authorize] [HttpGet] public async Task<ActionResult<IEnumerable<User>>> GetUsers() { if (_context.Users == null) { return NotFound(); } return await _context.Users.ToListAsync(); }
Program.cs配置代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidateAudience = true, ValidAudience = builder.Configuration["Jwt:Audience"], ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes( builder.Configuration["Jwt:Key"])) }; }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // 配置HTTP请求管道 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseCors(); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
Token生成方法代码
private string GetToken() { var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, _configuration["Jwt:Subject"]), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, "1516239022"), new Claim("userId" , "1"), new Claim("name", "Jason"), new Claim("userName", "Jason"), new Claim("email", "jason@gmail.com") }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("lectureTest12345")); var singIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( _configuration["Jwt: Issuer"], _configuration["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddHours(1), signingCredentials: singIn ); return new JwtSecurityTokenHandler().WriteToken(token); }
问题排查与修复方案
1. 修复Issuer配置键的空格问题
Token生成代码中,Issuer的配置键_configuration["Jwt: Issuer"]多了一个空格,导致读取的Issuer值与Program.cs中验证用的Jwt:Issuer不匹配,直接引发验证失败。
修复后代码:
var token = new JwtSecurityToken( _configuration["Jwt:Issuer"], // 去掉键名中的空格 _configuration["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddHours(1), signingCredentials: singIn );
2. 统一签名密钥配置
当前生成Token时硬编码了密钥"lectureTest12345",但Program.cs中使用的是配置文件里的Jwt:Key值,两者必须完全一致才能通过签名验证。
推荐方案:
- 在
appsettings.json中配置Jwt:Key为"lectureTest12345" - 或修改Token生成代码,读取配置项而非硬编码:
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
3. 修正Iat声明的硬编码值
JwtRegisteredClaimNames.Iat被硬编码为固定字符串"1516239022",虽然默认Token验证不强制校验Iat的合理性,但建议改为当前时间的Unix时间戳,避免潜在的验证逻辑冲突:
修复后代码:
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()),
4. 确认Postman请求头格式
确保Postman中请求头的Authorization格式正确:
- 选择
Bearer Token类型,填入生成的完整Token - 或手动添加请求头:
Authorization: Bearer <你的Token字符串>
内容的提问来源于stack exchange,提问作者user19927732
相关产品推荐
相关产品推荐

