The benefits of stateless authentication are many.
Imagine that your little web app suddenly becomes a worldwide hit. Now thousands… no, hundreds of thousands of persons are accessing it simultaneously.
Your little virtual server won’t cope with all that traffic, but it’s okay because you can add servers and distribute the traffic around. Just put a load balancer to make sure nothing overloads, right?
Ah, except that if your users are identified by server-side sessions (as it is the case with stateful, session-based authentication) then their requests must always be redirected to the same server they were authenticated on, because that session info is not shared by all servers in your cluster.
“No problem, I’ll just tell our load balancer to do sticky sessions.“
Okay, but if your web application is a true hit you will soon notice that it is not optimal for a whole lot of reasons: the load is not being balanced evenly, there’s an impact on the servers memory…
Imagine that one of your servers in the cluster goes down: oops, a bunch of users just got disconnected. And boy, they’re not happy…
To be totally fair, sticky sessions can actually be a good fit in many cases. It is relatively easy to set up and does not require any modifications on the application side. If your traffic is moderate, you should be good. But wouldn’t it be great if sessions didn’t need to be stored on the server?
If credentials were not stored on the server, then no matter where the load balancer would direct traffic the user would still remain authenticated. If a server went down, the user’s requests would just be redirected to a working machine without any interruption. As soon as traffic spikes would be detected you would be able to add some virtual machines and voilà: the overload issue is resolved. Finally, although session objects do not necessarily take a lot of space (especially when using them strictly for authentication), we would not need the server to save some precious memory to store these session objects.
How cool would that be!
Okay I’m sold, how can I make my authentication stateless?
The most obvious idea would be to send our session object’s content back to the client and have them stored in, say, a cookie. They would of course be encrypted by the server before, so that no prying eyes would be able to read them.
When querying the server, the client would send that encrypted cookie along with the intended request. The server would then decrypt the cookie’s content and consequently verify the obtained credentials. Since the server had previously encrypted the cookie’s content using its own secret key, we are pretty sure that the credentials obtained are authentic… unless the secret key is leaked, that is.
This approach has been made pretty much straightforward thanks to contributions like this one, which allows you to intercept the session’s content, encrypt it and send it to the browser as a cookie. Essentially, you should be able to add something such as “HTTP Stateless Session” to your project and happily keep using all the cool features provided by Spring Security or similar frameworks.
JSON Web Tokens
JWT (JSON Web Tokens) is the open standard version of that concept: a JSON-based solution for creating secure tokens that contain a certain amount of claims, such as “I am indeed logged”, “I have administration rights” or “I have small hands and a sorry-looking orange rag on my head”. These tokens are standard, compact, encrypted and signed by the emitting entity so that whoever receives them can ensure they are legitimate.
As such, they can be perfectly used for authenticating a web or mobile application to a server exposing a RESTful API.
Table of contents
So this is my proposal: we are going to revisit authentication for Spring-based RESTful APIs from a stateless perspective. We’ll proceed step by step:
- First we’ll go for a Basic, stateful authentication scenario using Spring Boot and Spring Security: we’ll set up a project and aim at the known “basics”, while setting up the testing environment to make sure our security implementation actually works.
- Token-based authentication will gradually replace sessions as the holders of authentication credentials. We will take our first steps towards statelessness.
- We will then bring JWTs to the equation and end up with a fully-usable solution of stateless authentication for RESTful APIs.
- Finally, we will examine stateless CSRF protection for that extra layer of protection.
At the end, we should have a good starting point for securing our RESTful projects in a stateless fashion.
So next time we’ll start by setting up our initial project. Until then…