SecurityTokenExpiredException:IDX10223:生命周期验证失败。令牌已过期。 ValidTo:'System.DateTime',当前时间:'System.DateTi
Posted
技术标签:
【中文标题】SecurityTokenExpiredException:IDX10223:生命周期验证失败。令牌已过期。 ValidTo:\'System.DateTime\',当前时间:\'System.DateTime\'【英文标题】:SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo: 'System.DateTime', Current time: 'System.DateTime'SecurityTokenExpiredException:IDX10223:生命周期验证失败。令牌已过期。 ValidTo:'System.DateTime',当前时间:'System.DateTime' 【发布时间】:2021-11-11 22:52:54 【问题描述】:在带有 RestAPI 的 ASP.NET Core 5 项目中,我将 JWT Bearer 与令牌和刷新令牌一起使用。我这样配置启动:
var jwtSecretKey = Configuration.GetValue<string>("Jwt:Key");
var key = Encoding.UTF8.GetBytes(jwtSecretKey);
var tokenValidationParameters = new TokenValidationParameters
SaveSigninToken = true,
ValidateActor = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(key),
// set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
ClockSkew = TimeSpan.Zero
;
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 = tokenValidationParameters;
);
为了生成令牌,我使用了这段代码(需要注意的是我使用了 UTC 日期):
string validIssuer = _configuration["Jwt:Issuer"];
string validAudience = _configuration["Jwt:Audience"];
var jwtSecretKey = _configuration.GetValue<string>("Jwt:Key");
var issuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecretKey));
var accessTimeout = _configuration.GetValue<int>("Jwt:MinutosExpiracionTokenAcceso");
DateTime fechaHoy = DateTime.UtcNow;
DateTime fechaExpiracionToken = DateTime.UtcNow.AddMinutes(accessTimeout);
var userRoles = await _userManager.GetRolesAsync(user);
var claims = new List<Claim>
new Claim(ClaimTypes.Sid, user.Id),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) // (JWT ID) Unique Identifier for JWT, can be used to prevent the JWT from being replayed. Is best suited for refresh tokens
;
foreach (var userRole in userRoles)
claims.Add(new Claim(ClaimTypes.Role, userRole));
var token = new JwtSecurityToken(
validIssuer,
validAudience,
claims,
fechaHoy,
fechaExpiracionToken,
new SigningCredentials(issuerSigningKey, SecurityAlgorithms.HmacSha256)
);
var refreshTimeout = _configuration.GetValue<int>("Jwt:MinutosExpiracionTokenAutorizacion");
var refreshToken = new RefreshToken()
JwtId = token.Id,
IsUsed = false,
UserId = user.Id,
AddedDate = DateTime.UtcNow,
ExpiryDate = DateTime.UtcNow.AddMinutes(refreshTimeout),
IsRevoked = false,
Token = RandomString(25) + Guid.NewGuid()
;
await _unitOfWork.GetRepository<RefreshToken>().AddAsync(refreshToken);
await _unitOfWork.SaveChangesAsync();
var tokensDto = new TokensResponseDto
Token = new JwtSecurityTokenHandler().WriteToken(token),
RefreshToken = refreshToken.Token
;
return tokensDto;
我在验证令牌时遇到问题(_tokenValidationParameters 与启动时使用的相同):
var jwtTokenHandler = new JwtSecurityTokenHandler();
ClaimsPrincipal principal = null;
SecurityToken validatedToken = null;
principal = jwtTokenHandler.ValidateToken(tokenRequest.Token, _tokenValidationParameters, out validatedToken);
无论我是否使用本地时间(例如 DateTime.Now 而不是 UTC),它都会抛出没有特定日期的上述异常。
我尝试在启动时在 TokenValidationParameters 中添加 LifetimeValidator,如下所示:
LifetimeValidator = (DateTime? notBefore,
DateTime? expires,
SecurityToken securityToken,
TokenValidationParameters validationParameters
) =>
if (expires != null)
if (DateTime.UtcNow < expires.Value.ToUniversalTime())
return true; // Still valid
return false; // Expired
但是,ValidateToken 失败并出现以下异常:
IDX10230:生命周期验证失败。委托返回 false,securitytoken: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'。
感谢您的帮助
【问题讨论】:
【参考方案1】:我遇到了类似的问题。我的服务器(生成令牌)时间和我的客户端(消耗令牌)时间不同。同步并完美运行。
【讨论】:
【参考方案2】:你试试:
/*
ClaimsPrincipal principal = null;
principal = jwtTokenHandler.ValidateToken(tokenRequest.Token, _tokenValidationParameters, out validatedToken);
*/
validatedToken = jwtTokenHandler.ReadJwtToken(token);
/*Your own validation logic*/
【讨论】:
以上是关于SecurityTokenExpiredException:IDX10223:生命周期验证失败。令牌已过期。 ValidTo:'System.DateTime',当前时间:'System.DateTi的主要内容,如果未能解决你的问题,请参考以下文章