Invalidating JSON Web Tokens (JWT)
August 01, 2021 10:12Securing APIs is best practice to protect the integrity of application. JWT authentication has become the standard way for protecting APIs. It is an open standard to pass data between client and server, and enables you to transmit data back and forth between server and consumers in a secure manner.
Asp.Net core provides services to authenticate incoming requests by determining user’s identity. To validate custom logic middleware could be added to pipeline. JWT access token is only valid for a finite period of time. The caveat comes only when you need to invalidate the token based on your business needs. If you need to invalidate a JWT token you will need to wait for the token to expire.
You could store JWT token in database and remove when it needs to be invalidated. This would force the user with valid JWT to login again. Consideration should be done to maintain huge list of user JWT token in datastore and seeking time to locate specific token. There are articles mentioning how to invalidate JWT tokens and this is one which extends to invalidate specific user token with custom logic.
Asp.net core distributed cache supports different datastores to persist information. MySQL is used as datastore in this article, we will need quite a few tools to be installed to create datastore, create cache tables
dotnet tool install --global dotnet-ef
Pomelo MySQL tools
dotnet tool install --local Pomelo.Extensions.Caching.MySqlConfig.Tools --version 2.1.0
For this article let consider scenario user log in
public async TaskLogin([FromBody] LoginRequest request) { User user = await userService.AuthenticateUserAsync(request.Email, request.Password); if (user == null) { return Unauthorized(); } string token = GenerateJwtToken(user); LoginResponse response = new() { Id = user.Id, UserName = user.Username, Token = token }; return Ok(response); }
For some purpose admin decides to inactivate users subscription, for clarity purpose the sample prevents user access to website after inactivation. Real scenario will user can login to website but cannot access pages that needs active subscription.
public async TaskDeactivateSubscription(string email) { User user = await userService.GetUser(email); if (user == null) { return BadRequest(); } await userService.DeactivateSubscription(user); await tokenManager.DeactivateCurrentAsync(); return Accepted(); }
Deactivation will make an entry to cache table with userid included in the key. If user navigates to another page middleware will be called which would verify if current user has active subscription by checking the database table for any deactivated key. If key is found user will not be allowed to access web page with unauthorized response code.
public async TaskIsActiveAsync(string token) { string key = GetKey(token); string tokenvalue = await cache.GetStringAsync(key); return tokenvalue == null; }
Conclusion If there are no identity servers available and we are limited to JWT token we could use distributed cache and implement our own logic to invalidate tokens. You could refer the sample code available in Github
Comments are closed.