JwtSecurityToken 不会过期 [英] JwtSecurityToken doesn't expire when it should

查看:14
本文介绍了JwtSecurityToken 不会过期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在 System.IdentityModels.Tokens 命名空间中使用 JwtSecurityToken 类.我使用以下内容创建了一个令牌:

I am currently using the JwtSecurityToken class in System.IdentityModels.Tokens namespace. I create a token using the following:

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); 

由于某种原因,即使将 expires 设置为当前时间之后的 10 秒,在验证令牌时它实际上不会抛出异常,直到大约 5 分钟.看到这里,我想可能是最小过期时间为 5 分钟,所以我将过期时间设置为:

For some reason even though the expires is set to 10 seconds after the current time it doesn't actually throw an exception when the token is being validated until about 5 minutes. After seeing this, I thought maybe there was a minimum expire time of 5 minutes, so I set the expire time to:

DateTime.UtcNow.AddMinutes(5);

然后它在 10 分钟过期,但是异常消息说过期时间设置为应有的时间(用户登录后 5 分钟),当它在异常中显示当前时间时它是过期时间后 5 分钟.因此,它似乎知道它应该何时过期,但实际上直到过期时间后 5 分钟才抛出异常.然后,由于令牌似乎在我将其设置为过期的任何时间上增加了 5 分钟,因此我将过期时间设置为:

Then it expires at 10 minutes, but the exception message says that the expire time is set to what it is supposed to be (5 minutes after the user logs in), and when it shows the current time in the exception it is 5 minutes after the expire time. So, it seems to know when it SHOULD expire, but it doesn't actually throw the exception until 5 minutes after the expire time. Then, since the token seems to be adding 5 minutes to whatever time I set it to expire I set the expire time to:

DateTime.UtcNow.AddMinutes(-5).AddSecond(10);

我对此进行了测试,到目前为止它还没有过期(十多分钟后).有人可以解释为什么会发生这种情况以及我做错了什么吗?此外,如果您在我提供的代码中看到任何其他内容,我们将不胜感激,因为我是使用 JWT 和这个库的新手.

I tested this and so far it still hasn't expired (After more than ten minutes). Can someone please explain why this is happening and what I am doing wrong? Also, if you see anything else with the code I provided any guidance would be appreciated since I am new to using JWTs and this library.

推荐答案

阅读@Denis Kucherov 的回答后,我发现我可以使用他发布的同一个自定义验证器,而无需使用需要我添加的 JwtBearerOptions 类一个新的图书馆.

After reading through @Denis Kucherov's answer, I found out that I could use the same custom validator he posted without using the JwtBearerOptions class which would have required me to add a new library.

另外,由于有两个命名空间包含许多相同的类,我将确保提到所有这些都使用 System.IdentityModels... 命名空间.(不是 Microsoft.IdentityModels...)

Also, Since there are two namespaces which contain a lot of these same classes I will make sure to mention that all of these are using the System.IdentityModels... namespaces. (NOT Microsoft.IdentityModels...)

下面是我最终使用的代码:

Below is the code I ended up using:

private bool CustomLifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken tokenToValidate, TokenValidationParameters @param)
{
    if (expires != null)
    {
        return expires > DateTime.UtcNow;
    }
    return false;
}
private JwtSecurityToken ValidateJwtToken(string tokenString)
{
   string secret = ConfigurationManager.AppSettings["jwtSecret"].ToString();
   var securityKey = new InMemorySymmetricSecurityKey(Encoding.Default.GetBytes(secret));
   JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
   TokenValidationParameters validation = new TokenValidationParameters()
   {
       ValidAudience = "MyAudience",
       ValidIssuer = "MyIssuer",
       ValidateIssuer = true,
       ValidateLifetime = true,
       LifetimeValidator = CustomLifetimeValidator,
       RequireExpirationTime = true,
       IssuerSigningKey = securityKey,
       ValidateIssuerSigningKey = true,
   };
   SecurityToken token;
   ClaimsPrincipal principal = handler.ValidateToken(tokenString, validation, out token);
   return (JwtSecurityToken)token;
}

这篇关于JwtSecurityToken 不会过期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆