JWT Token authentication, expired tokens still working, .net core Web Api

If your expiry time is well over the default (5 mins) or over a set a time like I had and it still considers expired token as valid, and setting the ClockSkew to TimeSpan.Zero has no effect, make sure you have the property

ValidateLifetime 

set to true as I had mine set to false causing the problem, which totally make sense, but it was an easy oversight.

services.AddAuthentication(option =>
    {
        option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["JwtToken:Issuer"],
            ValidAudience = Configuration["JwtToken:Issuer"],
            IssuerSigningKey = new SymmetricSecurityKey(
               Encoding.UTF8.GetBytes(Configuration["JwtToken:SecretKey"]))
        };
    });

There is an additional delay of 5 minutes in the library itself.

If you are setting 1 minute as indicated for expiration, the total will be 6 minutes. If you set 1 hour the total will be 1 hour and 5 minutes.


I believe this has to do with ClockSkew in JwtBearerOptions.

Change to TimeSpan.Zero as I fhink the default is set to 5 minutes (not 100% sure though).

I have posted some sample code below that is to be placed in Startup.cs => Configure.

        app.UseJwtBearerAuthentication(new JwtBearerOptions()
        {
            AuthenticationScheme = "Jwt",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            TokenValidationParameters = new TokenValidationParameters()
            {
                ValidAudience = Configuration["Tokens:Audience"],
                ValidIssuer = Configuration["Tokens:Issuer"],
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
                ValidateLifetime = true,
                ClockSkew = TimeSpan.Zero
            }
        });