.NET 7 API携带有效JWT Token仍返回401问题排查与解决
问题场景
配置.NET 7 API启用JWT令牌认证时,未添加[Authorize]特性的端点可正常响应,但添加该特性的端点始终返回401 Unauthorized。已尝试关闭Issuer和Audience验证,且确认app.UseAuthentication()与app.UseAuthorization()的调用顺序无误,生成的Token格式看似正常,但用Postman请求受保护端点始终无法通过认证。
相关配置代码
JWT扩展配置类
public static class AuthenticationExtension { public static void AddAuthentication(this IServiceCollection services, IConfiguration configuration) { var jwtAppSettingOptions = configuration.GetSection(nameof(JwtOptions)); var securityKey = jwtAppSettingOptions[(nameof(JwtOptions.SecurityKey))]?.Trim() ?? string.Empty; var jwtSecurityKey = Encoding.ASCII.GetBytes(securityKey); var symmetricSecurityKey = new SymmetricSecurityKey(jwtSecurityKey); var tokenValidationsParameters = new TokenValidationParameters() { ValidateIssuerSigningKey = true, IssuerSigningKey = symmetricSecurityKey, ValidateIssuer = false, ValidIssuer = jwtAppSettingOptions[(nameof(JwtOptions.Issuer))]?.Trim() ?? string.Empty, ValidateAudience = false, ValidAudience = jwtAppSettingOptions[(nameof(JwtOptions.Audiance))]?.Trim() ?? string.Empty, ValidateLifetime = true, RequireExpirationTime = true, ClockSkew = TimeSpan.FromMinutes(10), }; services.Configure<JwtOptions>(options => { options.Issuer = jwtAppSettingOptions[(nameof(JwtOptions.Issuer))]?.Trim() ?? string.Empty; options.Audiance = jwtAppSettingOptions[(nameof(JwtOptions.Audiance))]?.Trim() ?? string.Empty; options.SigningCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature); options.AccessTokenExpiration = uint.Parse(jwtAppSettingOptions[nameof(JwtOptions.AccessTokenExpiration)] ?? "0"); options.RefreshTokenExpiration = uint.Parse(jwtAppSettingOptions[nameof(JwtOptions.RefreshTokenExpiration)] ?? "0"); }); services.Configure<IdentityOptions>(options => { options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireUppercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequiredLength = 6; }); services .AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = tokenValidationsParameters; }); } }
Program.cs配置
public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddCors(); builder.Services.AddControllers(); builder.Services.AddRouting(options => options.LowercaseUrls = true); builder.Services.AddSwagger(); builder.Services.AddAuthentication(builder.Configuration); builder.Services.RegisterDependencies(builder.Configuration); var app = builder.Build(); app.UseSwaggerUI(); app.UseHttpsRedirection(); app.UseCors(builder => builder .SetIsOriginAllowed(orign => true) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); } }
受保护端点代码
[HttpGet] [Authorize] public IActionResult Ping() => Ok("Success");
Token生成代码
private async Task<UsuarioDTO.AutenticarRetorno> ObterRetornoAutenticadoAsync(string email) { var usuario = await ObterUsuarioAsync(email); var claims = await ObterClaimsAsync(usuario); var dataExpiracao = DateTime.Now.AddHours(_options.AccessTokenExpiration); var securityTokenDescriptior = new SecurityTokenDescriptor() { Subject = new ClaimsIdentity(claims), Issuer = _options.Issuer, Audience = _options.Audiance, Expires = dataExpiracao, NotBefore = DateTime.Now, SigningCredentials = _options.SigningCredentials, }; var jwt = _handler.CreateToken(securityTokenDescriptior); var token = _handler.WriteToken(jwt); return new UsuarioDTO.AutenticarRetorno(token, dataExpiracao); }
排查与解决方案
通过给AddJwtBearer配置添加JwtBearerEvents并设置断点调试,发现认证过程中存在底层依赖缺失的错误。最终在Web API项目中安装System.IdentityModel.Tokens.Jwt NuGet包后,问题得到解决,带[Authorize]特性的端点可正常通过JWT认证并返回响应。
内容的提问来源于stack exchange,提问作者Juliano Maciel
相关产品推荐
相关产品推荐

