What is Stateless Authentication
When working web applications in java we usually keep authentication information or user identity inside the session scope. which is unique to the user. this works well if you have one single server.
when load on the server increase we do scaling out (also called horizontal scaling) means we will add multiple servers with the same application to serve the requests.
in-front of this we introduce load balancer. load balancer will uses round -robin algorithm kind of algorithms and divert user to different servers depending on the load. here comes the issues. if the user authenticated with into one systems. and load on that system increase load balancer send request to another server which fails authentication and asks for credentials again which is bad user experience. :(
Ah ! we have solution too here. we have concept called sticky sessions which gives you perfect solution. using sticky session load balancer will remember the user and send all requests from that user to specific server. here comes another problem called point of failure. means …..! what if that server crasher mid of serving some request ?. this is again bad user experience. (consider e-commerce application when user places order and proceed to payment which goes another server and he lost his order information)
in order to solve this kind of issues stateless authentication comes into picture. we don’t use session scope to store user authentication information rather we use separate persistence mechanism to store user identify which is accessible to all the App Servers. Here it works...
- Client sends its credentials to server. (i used simple HttpServlet along with spring security authenticationManager)
- Server authenticates them and generates fixed length token.
- Server stores previously generated token in some storage(here i’m using Hazelcast a powerful distributed cache) with user identifier.
- Server sends previously generated token to client in a response body (usually in JSON format we can also use JWT to prepare tokens ).
- Now, client sends that token in each request using the “Authorization” header.
- Server, in each request, extracts the token from the Authorization header and looks up the user identifier on its storage to query database to obtain the user information.
How can we achieve this with Spring Security
Spring comes with authentication managers which are useful to authenticate credentials. i introduces simple HttpServlet which does authentication for us. here is the code snippet. ( i customised spring security which uses hibernateAuthentication Managers and also supports dynamic roles with configurable access privileges dynamically)
once the user authenticated successfully it return JSON as response body which contains fixed length token.
This accessToken we send back to server to access the secure URLs. at this point you may have doubt how does it solves the problem. here is the answer. we are not saving this token in the session but we are saving this in the separate storage which is accessible to the all the servers. there are various implementations are available example AWS users can leverage DynamoDB. which is NoSQL implementation database which stores tokens in SSD drivers.
Picture : stateless authentication works in AWS .we can use our own implementation using HazelCast or some other cache mechanism
i’m using HazelCast a distributed cache implementation which also have backing storage with popular database like MongoDB, MySQL as per your choice. it gives low latency ,high performance and high throughput. watch this video if you want to know about dynamo DB.
configure your spring security configuration file as show below .
and we need our own implementation which store our AuthenticationTokens. below is complete implementation of SecurityTokenRepository which implements SecurityContextRepository which is part of spring security framework.
NOTE : Spring Security by default uses
to store data in the HttpSession
TokenStorageUtil contains Hazelcast add/read implementation which stores into cache with Time To Leave interval which pretty much similar session expiry time in the stateful session management.
subscribe this blog to get the full implementation code here.