JWT Token Expiration time failing .net core

16,306

There is a token validation parameter called ClockSkew, it gets or sets the clock skew to apply when validating a time. The default value of ClockSkew is 5 minutes. That means if you haven't set it, your token will be still valid for up to 5 minutes.

If you want to expire your token on the exact time; you'd need to set ClockSkew to zero as follows,

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

Another way, create custom AuthorizationFilter and check it manually.

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
} 

Here, GetPrincipalFromToken is a custom method of the ApiTokenHelper class, and it will return the ClaimsPrincipal value that you've stored while issuing a token.

Share:
16,306
Abhilash Gopalakrishna
Author by

Abhilash Gopalakrishna

Student pursuing a degree in Information Science. Love to code,always ready to learn.

Updated on June 12, 2022

Comments

  • Abhilash Gopalakrishna
    Abhilash Gopalakrishna almost 2 years

    I am trying to implement Token Based Authentication through refresh tokens and JWT in .NET Core 2.1.

    This is how I am implementing the JWT Token:

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

    Token Generation:

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

    I am getting he correct values in Response.

    enter image description here

    But after a minute I set the same token for authorization in Postman and it works. If the token has expired it shouldn't.

    I am using bearer tokens as authentication.

    What am I doing wrong? Need direction.

  • Ewan
    Ewan over 4 years
    super annoying breaking change from .net framework :(
  • Ashwin Kumar
    Ashwin Kumar almost 3 years
    Any additional documentation for this ? 300 secs is quite a high number.