.NET中JWT令牌验证遇无效签名及格式错误问题求助
解决ASP.NET Core JWT认证的签名无效及格式错误问题
核心问题分析
1. 密钥不一致导致invalid signature
你的令牌生成逻辑和验证逻辑使用的密钥不匹配:
- 生成令牌时,优先从配置项
_configuration["Jwt:Key"]读取密钥,仅当配置不存在时才使用<key>作为 fallback - 验证逻辑中直接硬编码使用
<key>,如果appsettings.json中配置了其他密钥,两端密钥不一致必然导致签名验证失败
2. 同步调用异步方法可能引发IDX14100格式错误
你在生成令牌时使用_userService.GetIdentityRole(user).Result同步等待异步方法,这种写法可能导致线程阻塞、死锁,进而引发令牌生成过程异常,产出格式不完整(无分隔点)的JWT,触发IDX14100错误。
修正方案
步骤1:统一验证端的密钥来源
修改Program.cs中的JWT验证配置,读取与生成端一致的配置密钥:
// Configure JWT Authentication var key = Encoding.ASCII.GetBytes(builder.Configuration["Jwt:Key"] ?? "<key>"); builder.Services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false }; });
步骤2:修复异步方法调用方式
修改AuthController中的GenerateJwtToken方法,改用await异步等待角色获取,避免同步阻塞:
private async Task<string> GenerateJwtToken(ApplicationUser user) { var tokenHandler = new JwtSecurityTokenHandler(); var key = _configuration["Jwt:Key"] ?? "<key>"; var keyBytes = Encoding.ASCII.GetBytes(key); var userRoles = await _userService.GetIdentityRole(user); var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.Email ?? string.Empty), new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()) }; claims.AddRange(userRoles.Select(role => new Claim(ClaimTypes.Role, role))); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddHours(1), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(keyBytes), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); }
额外注意事项
- 确保
appsettings.json中的Jwt:Key是至少32位的随机字符串(HmacSha256算法需要足够长度的密钥保证安全性) - 生产环境禁用硬编码密钥,使用环境变量或专业密钥管理服务存储密钥
- 生产环境设置
RequireHttpsMetadata = true,防止令牌在传输过程中被窃听
内容的提问来源于stack exchange,提问作者simon sjöö
相关产品推荐
相关产品推荐

