ASP.NET Core 8.0 JWT验证异常:有效令牌触发SecurityTokenNoExpirationException
ASP.NET Core 8.0 Web API JWT验证异常问题求助
问题概述
我正在开发一个分层架构的ASP.NET Core 8.0 Web API项目,这套JWT生成与验证逻辑迁移自已稳定运行3年的ASP.NET Core 6.0项目,服务器环境和配置未变,但在认证和注册端点的JWT验证过程中出现异常。调用GetPrincipalFromToken方法时提示令牌缺少过期时间,移除过期日期并禁用过期验证后,又会出现颁发者(issuer)和受众(audience)验证失败问题。但生成的令牌经jwt.io验证,exp、iss等字段均正确,怀疑问题与包版本或ValidateToken的处理逻辑有关。
Program.cs中的JWT验证参数配置
var tokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, ValidateAudience = true, ValidAudience = jwtSettings.ValidAudience, ValidIssuer = jwtSettings.ValidIssuer, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.Secret)), ClockSkew = jwtSettings.TokenLifetime }; builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.SaveToken = true; options.RequireHttpsMetadata = false; options.TokenValidationParameters = tokenValidationParameters; options.Events = new JwtBearerEvents { OnMessageReceived = context => { context.Token = context.Request.Cookies["authorization"]; return Task.CompletedTask; } }; }); builder.Services.AddSingleton(tokenValidationParameters);
令牌生成方法
public async Task<Response<RefreshTokenDto>> GenerateAuthResultForCustomAsync(Customer customer) { try { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_jwtSettings.Secret); var userRoles = await _userManager.GetRolesAsync(customer); var authClaims = new List<Claim> { new Claim(JwtRegisteredClaimNames.Sub, customer.Email), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim("customerId", customer.Id), new Claim("firstName", customer.FirstName), new Claim("lastName", customer.LastName), new Claim("countryId", customer.CountryId.ToString()), new Claim("phoneNumber", customer.PhoneNumber), new Claim("userName", customer.UserName) }; authClaims.AddRange(userRoles.Select(role => new Claim(ClaimTypes.Role, role))); var tokenDescriptor = new SecurityTokenDescriptor() { Subject = new ClaimsIdentity(authClaims), Issuer = _jwtSettings.ValidIssuer, Audience = _jwtSettings.ValidAudience, Expires = _dateTimeProvider.Now.Add(_jwtSettings.TokenLifetime).UtcDateTime, SigningCredentials = new SigningCredentials( new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); // 原代码返回逻辑未完整展示,此处省略 } catch { // 原代码异常处理逻辑未完整展示,此处省略 } }
令牌验证方法
public class PrincipalTokenService : IPrincipalTokenService { private readonly TokenValidationParameters _tokenValidationParameters; public PrincipalTokenService(TokenValidationParameters tokenValidationParameters) { _tokenValidationParameters = tokenValidationParameters; } public ClaimsPrincipal GetPrincipalFromToken(string token) { var tokenHandler = new JwtSecurityTokenHandler(); try { var handler = tokenHandler.ValidateToken( token, _tokenValidationParameters, out var validatedToken); return !IsJwtWithValid(validatedToken) ? null : handler; } catch { return null; } } // 原代码IsJwtWithValid方法实现未展示,此处省略 }
异常信息
Microsoft.IdentityModel.Tokens.SecurityTokenNoExpirationException: 'IDX10225: Lifetime validation failed. The token is missing an Expiration Time. Tokentype: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'
项目相关包版本
<PackageReference Include="Asp.Versioning.Mvc" Version="8.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.3" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.3"> <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" /> <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.4.1" />
补充说明
- jwtSettings是从配置文件填充验证参数的模型
- 即使硬编码验证参数,仍会出现相同问题
- 生成的令牌在jwt.io上显示所有必填字段均正确
有没有人遇到过ASP.NET Core 8.0中的类似JWT验证问题?求指点或建议。
内容的提问来源于stack exchange,提问作者Levan Amashukeli
相关产品推荐
相关产品推荐

