Spring boot JWT Authentication and authorization- A Review

source: JWT

Recently I started a small project which required authentication and authorization. As a Java developer familiar with spring boot, I decided to leverage on spring boot to deliver the goods.

One key decision I made early on was to use JWT for authentication and authorization as I have read about the stateless capacity of JWTs.

However, along the line, I encountered some issues and made some personal findings that form the core of this article.

Disclaimer: As the title suggests, the views expressed here are based on my experience with JWTs which is meant to elicit opinions and expand the discussion about JWTs and it’s inherent capacities.

I will begin by explaining how I set up the authentication and authorization in spring boot as well as the modifications made to circumvent the issues faced.

Note this project uses a Postgres data source

The code below shows the initial JWT filter.

vanilla JWT filter

Challenges
1. User Log out

One of the challenges I faced during this implementation was how to securely log out a user.

The Scenario

In this case, when a user logs out of the client app, the token is still valid if it’s not expired before logout. This poses a security threat as the valid token can be “hijacked” and used to access resources from an unknown client.
With this flaw, the whole idea of stateless authentication and authorization was defeated as there is no clear way of invalidating a token.

Remediation

To circumvent this issue, I had to make do with popular opinions and suggestions on this matter. Create an in-memory data source to store the token as part of blacklisted JWTs when the user logs out, authenticate against them for each request to the server and routinely delete expired tokens from the data source to reduce the sample size, hence improving search time for each request.

I achieved this seamlessly by checking if the token is already in the list of blacklisted tokens maintained. This is shown below although I used the Postgres database.

JWT Blacklist Check
Delete Expired Token

No doubt this works fine, but could potentially increase the response time for every request as the JWT blacklist is queried for every request. This was a cost I had to make do with.

2. Database Authentication not done for each request

Another funny behaviour I noticed whilst moving from my test environment to the UAT environment was that while requesting a resource, database authentication is not done. That is, only the validity of the token is checked and once a token is valid, voila! a resource is granted to the client. This may not be the usual case as the secret key used in the generation of the token should be securely protected but what if in extreme cases, the secret key is exposed. The attacker can easily generate a signed token and would be able to access a resource on your server.

The Scenario

In my case, the token I used for the test was able to access resources from my UAT server although both used the same secret for the token generation which should not have been. The point I’m trying to make here is that for each request there’s no authentication against the database to ascertain the validity of the principal in the token.

Remediation

To circumvent this, I added another layer of check to the JWT filter to do a check against the database for every request to the server. This again added another complexity as it may potentially lead to a lag in the server owing to the routine authentication against the database.

See below the code for the above implementation.

Questions

Considering the aforementioned scenarios, I would like to pose the following questions to my audience and developers experienced using JWTs.

1. What is the ideal use case of JWTs?
2. What security measures apart from the aforementioned can be used to safely secure apps using JWTs without compromising the stateless nature of JWTs?

Conclusion
Like I said ab initio, the opinions expressed herein are mine and based on the scenarios that played out whilst working with JWTs in spring boot.

Feel free to expand these issues so we can get a clearer perspective of the modus operandi of JWTs and potential pitfalls to avoid.

Thanks :)

Software Developer | imokhaiikhiloya@gmail.com | https://github.com/Ikhiloya | open to exciting projects