ASP.NET Core自定义登录代码下JWT认证授权失败问题
问题解决:JWT授权失败(Unprotected token failed)
问题分析
你遇到的Unprotected token failed错误,本质是JWT验证环节无法正确解析或验证Token,核心原因是JWT的签名配置不匹配——你生成Token时用的密钥、算法等参数,和后端验证时的配置不一致,或者验证端根本没配置必要的验证参数。
解决方案
1. 补全JWT验证配置
修改你的ConfigAuth方法,给AddJwtBearer添加完整的验证参数,确保和生成Token时的参数一致:
void ConfigAuth(WebApplicationBuilder builder) { // 从配置文件读取JWT参数(建议存到appsettings.json) var jwtSettings = builder.Configuration.GetSection("JwtSettings"); var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["SecretKey"])); builder.Services.AddIdentityApiEndpoints<User>().AddEntityFrameworkStores<MyDBContext>(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtSettings["Issuer"], ValidAudience = jwtSettings["Audience"], IssuerSigningKey = key }; }); builder.Services.AddAuthorization(); builder.Services.AddAuthorizationBuilder() .AddPolicy("admin", policy => policy.RequireRole("admin")) .AddDefaultPolicy("user", policy => policy.RequireAuthenticatedUser()); }
同时在appsettings.json中添加JWT配置项:
"JwtSettings": { "SecretKey": "你的安全密钥(建议至少32位随机字符串)", "Issuer": "你的后端域名", "Audience": "你的前端应用标识", "ExpiresInMinutes": 60 }
2. 确保中间件顺序正确
在Program.cs中,中间件必须按以下顺序添加:
app.UseAuthentication(); // 先认证 app.UseAuthorization(); // 再授权 // 其他中间件... app.MapNotesEndpoints();
3. 同步登录接口的Token生成逻辑
检查你登录接口生成JWT的代码,确保使用和验证端一致的密钥、颁发者、受众和算法:
// 示例:正确的JWT生成代码(参考你的登录逻辑调整) var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.UTF8.GetBytes(builder.Configuration["JwtSettings:SecretKey"]); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), new Claim(ClaimTypes.Role, user.Role) // 其他需要的Claim }), Expires = DateTime.UtcNow.AddMinutes(Convert.ToDouble(builder.Configuration["JwtSettings:ExpiresInMinutes"])), Issuer = builder.Configuration["JwtSettings:Issuer"], Audience = builder.Configuration["JwtSettings:Audience"], SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token);
4. 排查IdentityApiEndpoints的冲突
AddIdentityApiEndpoints会自动添加一套默认的JWT认证配置,如果你自行实现了登录接口,可能会导致配置冲突。如果不需要Identity默认的登录/注册端点,可以移除AddIdentityApiEndpoints,改用AddIdentityCore:
// 替换原有的AddIdentityApiEndpoints builder.Services.AddIdentityCore<User>(options => { // 配置Identity选项(如密码规则等) }) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<MyDBContext>();
关键说明
Unprotected token failed通常意味着验证端无法找到正确的密钥来验证Token的签名,所以核心是生成和验证的签名参数必须完全一致。- 永远不要硬编码密钥,建议用配置文件管理,生产环境使用环境变量存储敏感信息。
内容的提问来源于stack exchange,提问作者Omid.N
相关产品推荐
相关产品推荐

