Angular17+ASP.NET Core8中JWT刷新时Audience重复追加问题
JWT刷新时Audience字段重复追加的问题解决
问题描述
我正在开发一个基于Angular 17前端、ASP.NET Core 8后端的Web应用,实现了包含Refresh Token(存储于数据库)的JWT认证功能。创建Token环节无异常,但每次执行Token刷新操作时,JWT中的Audience字段会持续重复追加相同值。多次刷新后,Audience数组如下:
{ "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "[Removed]", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "[Removed]", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": "[Removed]", "exp": 1718882692, "iss": "https://localhost:4200", "aud": [ "https://localhost:4200", "https://localhost:4200", "https://localhost:4200", "https://localhost:4200", "https://localhost:4200", "https://localhost:4200", "https://localhost:4200", "https://localhost:4200", "https://localhost:4200" ] }
原因分析
问题出在Token刷新流程的两个关键环节:
- 调用
GetPrincipalFromExpiredToken验证过期Token后,返回的principal.Claims已经包含了原Token中的aud(audience)声明。 - 调用
GenerateAccessToken生成新Token时,既传入了包含aud声明的claims集合,又在JwtSecurityToken构造函数中指定了audience参数。JWT处理逻辑会将这两个来源的audience合并,导致每次刷新都新增一个相同的audience值,最终形成重复数组。
解决方案
修改TokenService中的GenerateAccessToken方法,在传入claims时过滤掉已有的aud声明,避免重复添加:
public string GenerateAccessToken(IEnumerable<Claim> claims) { var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); var jwtSettings = _configuration.GetSection("JwtSettingsCommon"); var environment = _configuration.GetSection("Production"); if (env == "Development") { environment = _configuration.GetSection("Development"); } var JwtSecret = jwtSettings["SigningKey"]; var Issuer = environment["URI"]; var Audience = environment["URI"]; var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSecret)); var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256); int expiry; try { expiry = Int32.Parse(jwtSettings["Expires"]); } catch (FormatException) { expiry = 10; } // 过滤掉claims中的aud声明,避免重复添加 var filteredClaims = claims.Where(c => c.Type != JwtRegisteredClaimNames.Aud).ToList(); var tokenOptions = new JwtSecurityToken( issuer: Issuer, audience: Audience, claims: filteredClaims, expires: DateTime.Now.AddMinutes(expiry), signingCredentials: signinCredentials ); var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions); return tokenString; }
补充说明
JwtRegisteredClaimNames.Aud是系统定义的audience声明常量(值为"aud"),使用它比硬编码字符串更可靠。- 过滤操作确保新生成的Token中,audience仅来自构造函数指定的
Audience参数,不会重复追加。
内容的提问来源于stack exchange,提问作者Jason Williams
相关产品推荐
相关产品推荐

