JWT令牌过期时间在.NET Core中失败了。

7

我正在尝试通过刷新令牌和JWT在.NET Core 2.1中实现基于令牌的身份验证。

这是我如何实现JWT令牌的:

Startup.cs

services.AddAuthentication(option =>
    {
        option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(options =>
    {
        options.SaveToken = true;
        options.RequireHttpsMetadata = true;
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidAudience = Configuration["Jwt:Site"],
            ValidIssuer = Configuration["Jwt:Site"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SigningKey"]))
        };

        options.Events = new JwtBearerEvents
        {
            OnAuthenticationFailed = context =>
            {
                if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                {
                    context.Response.Headers.Add("Token-Expired", "true");
                }
                return Task.CompletedTask;
            }
        };
    });

令牌生成:

var jwt = new JwtSecurityToken(
                issuer: _configuration["Jwt:Site"],
                audience: _configuration["Jwt:Site"],
                expires: DateTime.UtcNow.AddMinutes(1),
                signingCredentials: new SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
                );

        return new TokenReturnViewModel()
        {
            token = new JwtSecurityTokenHandler().WriteToken(jwt),
            expiration = jwt.ValidTo,
            currentTime = DateTime.UtcNow
        };

我在响应中获得了正确的值。

enter image description here

但是一分钟后,我在Postman中设置相同的令牌进行授权,它能够工作。 如果令牌已过期,则不应该这样。

我正在使用Bearer令牌进行身份验证。

我做错了什么?需要指导。


你是否已经检查了本地日期时间值而不是UTC值? - Sonal Borkar
我有本地时间遇到了以下问题:
  • 过期时间自动使用UTC时间,无论我使用什么时间。
- Abhilash Gopalakrishna
2
@AbhilashGopalakrishna 使用UTC时间和令牌,而不是本地时间。 - Divyang Desai
1个回答

37

有一个令牌验证参数叫做ClockSkew,它在验证时间时获取或设置要应用的时钟偏差。 ClockSkew的默认值为5分钟。这意味着如果您没有设置它,则您的令牌仍将有效,最多可达5分钟。

如果您想在精确时间过期您的令牌,则需要将ClockSkew设置为零,如下所示:

options.TokenValidationParameters = new TokenValidationParameters()
{
    //other settings
    ClockSkew = TimeSpan.Zero
};

另一种方法是创建自定义的AuthorizationFilter并手动检查它。

var principal = ApiTokenHelper.GetPrincipalFromToken(token);
var expClaim = principal.Claims.First(x => x.Type == "exp").Value;
var tokenExpiryTime = Convert.ToDouble(expClaim).UnixTimeStampToDateTime();
if (tokenExpiryTime < DateTime.UtcNow)
{
  //return token expired
} 

在这里,GetPrincipalFromTokenApiTokenHelper类的自定义方法,它将返回您在发出令牌时存储的ClaimsPrincipal值。


1
.NET Framework 的这个超级烦人的破坏性变更 :( - Ewan
这个有其他的文档吗?300秒是一个相当高的数字。 - Ashwin Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接