我当前使用System.IdentityModels.Tokens命名空间中的JwtSecurityToken类。我使用以下命令创建令牌:
DateTime expires = DateTime.UtcNow.AddSeconds(10);
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var genericIdentity = new System.Security.Principal.GenericIdentity(username, "TokenAuth");
ClaimsIdentity identity = new ClaimsIdentity(claims);
string secret = ConfigurationManager.AppSettings["jwtSecret"].ToString();
var securityKey = new InMemorySymmetricSecurityKey(Encoding.Default.GetBytes(secret));
var signingCreds = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.HmacSha256Signature);
var securityToken = handler.CreateToken(
issuer: issuer,
audience: ConfigurationManager.AppSettings["UiUrl"].ToString(),
signingCredentials: signingCreds,
subject: identity,
expires: expires,
notBefore: DateTime.UtcNow
);
return handler.WriteToken(securityToken);
由于某种原因,即使过期时间设置为当前时间之后10秒,但在验证令牌时,直到大约5分钟后才会抛出异常。看到这个消息后,我想可能存在最短5分钟的过期时间,所以我将过期时间设置为:
DateTime.UtcNow.AddMinutes(5);
然后,它在10分钟后到期,但异常消息指出到期时间设置为预期的时间(用户登录后5分钟),而当它在异常中显示当前时间时,它是过期时间后5分钟。因此,它似乎知道它应该在什么时候过期,但实际上直到过期时间后5分钟才抛出异常。由于令牌似乎在我设置的到期时间基础上增加了5分钟,因此我将到期时间设置为:
DateTime.UtcNow.AddMinutes(-5).AddSecond(10);
我测试了这个,到目前为止它还没有过期(十多分钟后)。有人能解释一下为什么会发生这种情况,我做错了什么吗?另外,如果你看到我提供的代码有任何其他的地方,任何指导都将不胜感激,因为我是第一次使用JWT和这个库。
6条答案
按热度按时间nr7wwzry1#
这个问题与
ClockSkew
有关。通常,验证库(至少是MS库)会补偿时钟偏移。ClockSkew
默认值为5分钟。请参见here的一些答案您可以在
TokenValidationParameters
中更改ClockSkew
:w46czmvw2#
在阅读了@Denis Kucherov的回答之后,我发现我可以使用他发布的相同的自定义验证器,而不需要使用JwtBearerOptions类,因为JwtBearerOptions类需要我添加一个新库。
此外,由于有两个名称空间包含许多相同的类,因此我将确保提到所有这些都使用System.IdentityModels...名称空间。(而不是Microsoft.IdentityModels...)
下面是我最终使用的代码:
xuo3flqw3#
LifeTimeValidator似乎存在一些问题。您可以使用自定义委托重写其逻辑。此外,使用JwtBearerOptions类控制身份验证中间件行为。例如:
并分配LifetimeValidotor委托,以提供自己的超时验证逻辑:
nmpmafwu4#
.NET核心更新
在.NET Core中,处理方式略有不同,因为
TokenValidationParameters
是使用ConfigureServices()
方法在Startup.cs
中设置的,然后由中间件自动处理。还请注意,旧的
InMemorySymmetricSecurityKey
用于签署秘密is now deprecated,而支持SymmetricSecurityKey
,如下所示。所以我也在@tkd_aj的answer above中创建了我自己的令牌验证器版本,并将其放在一个静态类中:
0aydgbwb5#
我也刚刚实现了一个JWT令牌中间件,虽然互联网上的示例使用
UtcNow
,但我必须使用Now
,否则过期时间是关闭的。xn1cxnb46#
下面的链接给予你确切的答案,默认情况下MS有5分钟的到期时间。所以要么你必须使它自定义或时间,你会在到期:DateTime.Now.AddSeconds(30)上一行中的30秒将添加到过期时间中。因此,总过期时间将为5分30秒
https://github.com/IdentityServer/IdentityServer3/issues/1251
希望这会有帮助。