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);
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);
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);
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.
Authentication is implemented through JWT access tokens along with refresh tokens. The API returns a short-lived token (JWT), which expires in 15 minutes, and in HTTP cookies, the refresh token expires in 7 days.
Using an expired JWT will cause operations to fail. As you saw above, we are told how long a token is valid through expires_in . This value is normally 1200 seconds or 20 minutes. Expired tokens are not refreshed.
So in summary when authorization is successful you need to issue two token ACCESS_TOKEN and REFRESH_TOKEN. When ACCESS_TOKEN expires you need to call another api with REFRESH_TOKEN to get new ACCESS_TOKEN. The client application can get a new access token as long as the refresh token is valid and unexpired.
You can use a lib(like jwt_decode) to decode your JWT token, where it's most likely contains an expiration timestamp that you can check(compare it with the current timestamp for this moment) and if it exceeded(expired) just delete it from local storage and redirect user to login page.
The problem is related ClockSkew
. Normally, the validation libraries (at least the MS one) compensate for clock skew. ClockSkew
default value is 5 minutes. See some answer here
You can change ClockSkew
in TokenValidationParameters
:
var tokenValidationParameters = new TokenValidationParameters { //...your setting // set ClockSkew is zero ClockSkew = TimeSpan.Zero }; app.UseJwtBearerAuthentication(new JwtBearerOptions { AutomaticAuthenticate = true, AutomaticChallenge = true, TokenValidationParameters = tokenValidationParameters });
Happy coding!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With