目前,我正在编写一个使用JWT-承载-身份验证的ASP.Net核心WebApi。
为了能够从不同的时区访问该应用程序接口,我使用以下模式将我的JWT中的字段nbf (notBefore)和exp (过期)设置为UTC-Timestamp:
var utcNow = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified);
...
var tokenOptions = new JwtSecurityToken(
notBefore: utcNow,
expires: utcNow.AddSeconds(3600),
);
...对于令牌生成,一切都运行得很好,nbf和exp包含代表当前UTC时间的UNIX时间戳。
但在进行令牌验证时,所有操作都会在5分钟内生效(我的时钟偏差设置),然后我只能从API获得401,因为令牌验证是使用我当前在德国的时区完成的。
有没有办法在.NET-Core中设置JwtAuthentication-Middleware来使用UTC-Time进行令牌验证?或者,有没有其他方法来解决这个问题?
发布于 2019-05-03 23:54:16
一种解决方案是在没有过期时间的情况下验证令牌。这将返回有效的令牌,即使令牌已过期。然后在您的代码中手动检查令牌的过期时间。以下是代码片段:
var validationParameters = new TokenValidationParameters()
{
RequireExpirationTime = false, // we can check manually
ValidateIssuer = true,
ValidateAudience = true,
.
.
IssuerSigningKey = new SymmetricSecurityKey(symmetricKey)
};然后,当token通过验证时,使用以下命令检查过期时间:
public bool IsExpired(DateTime now)
{
return JwtSecurityToken.ValidTo < Date.UtcNow;
}我希望这个答案能对某些人有所帮助。
发布于 2019-09-25 13:30:41
要获得更完整的答案,请在您的Startup.cs中
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
// ...
ValidateLifetime = true,
LifetimeValidator = (DateTime? notBefore, DateTime? expires, SecurityToken securityToken,
TokenValidationParameters validationParameters) =>
{
return notBefore <= DateTime.UtcNow &&
expires >= DateTime.UtcNow;
}
};
});发布于 2020-09-30 18:31:24
事实已经是这样了。System.IdentityModel.Tokens.Jwt包确实针对UTC时间验证了JWT生存期。下面是源码中的the relevant bit:
public static void ValidateLifetime(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
{
...
if (notBefore.HasValue && expires.HasValue && (notBefore.Value > expires.Value))
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidLifetimeException(LogHelper.FormatInvariant(LogMessages.IDX10224, notBefore.Value, expires.Value))
{ NotBefore = notBefore, Expires = expires });
DateTime utcNow = DateTime.UtcNow;
if (notBefore.HasValue && (notBefore.Value > DateTimeUtil.Add(utcNow, validationParameters.ClockSkew)))
throw LogHelper.LogExceptionMessage(new SecurityTokenNotYetValidException(LogHelper.FormatInvariant(LogMessages.IDX10222, notBefore.Value, utcNow))
{ NotBefore = notBefore.Value });
if (expires.HasValue && (expires.Value < DateTimeUtil.Add(utcNow, validationParameters.ClockSkew.Negate())))
throw LogHelper.LogExceptionMessage(new SecurityTokenExpiredException(LogHelper.FormatInvariant(LogMessages.IDX10223, expires.Value, utcNow))
{ Expires = expires.Value });
// if it reaches here, that means lifetime of the token is valid
LogHelper.LogInformation(LogMessages.IDX10239);
}https://stackoverflow.com/questions/55341414
复制相似问题