You want to build a scalable cloud ready application? Great! Let’s have a look how to build a server Spring Boot REST endpoint and secure it with stateless Spring Security. We want to authenticate every request with basic authentication OR with a token when the user has sent its credentials once. When a user authenticates with basic authentication we store a session ID in Redis with Spring Session and return it to the user to in the following requests.
If you haven’t heard of Spring Boot before, be sure to read up on it on: What are Microservices or Build your own Linkshortener API.
Standard HTTP Session in Java (JEE)
There are a quite a few shortcommings in Application Servers HTTP session implementations that we want to avoid:
- Have you ever tried to enable HTTP Sessions replication and clustering on Tomcat? It’s not an easy thing to do.
- Sessions are tightly coupled with the HTTP protocol, but there are other scenario’s where you’d like to access the session like when using JMS. Or keeping sessions alive when using WebSockets.
- How do you go about when you want to allow users to have multiple sessions, one for each tab (like in Gmail)?
Get started with Spring Session
With Spring Session all these issues are solved without any effort. This makes it easy to scale your cloud application since it doesn’t need to store sessions on disk anymore. As long as your Application Server uses a HttpSession, you can get started in a couple of easy steps. Let’s get started with a simple Spring Boot application with Spring Security for securing a RESTful service and store sessions in Redis:
Application.java
pom.xml
This would give us a working web application, that is secured by default because we include the Spring Boot Security Starter dependency. For ease of use we’ll start an in-memory database with one user present to use for authentication. We will authenticate every request with Basic Authentication and also create a HeaderHttpSessionStrategy
to tell Spring to use a X-Auth-Token
header for retrieving the session.
SecurityConfiguration.java
Hello Redis - a NoSQL key-value database
We don’t want to to reauthenticate every request by going to the database, this is why we will store a Session ID in Redis. This Session ID will be passed to the client after authenticating the first time, and from then on it can send this as a request header for all subsequent requests which will verify the user is authenticated.
If you look at the Spring Session documentation you’ll see that they always use an @EmbeddedRedisConfiguration
to start an embedded Redis instance, it’s pretty unclear that this is NOT yet available in Spring Session. They included some addtional classes in all their examples to get this to work, we’ll have to wait for Spring Session GitHub ticket until this will actually be implemented in Spring itself. For now I have a simple Configuration class that starts an instance without any customization, by using the Embedded redis depdency.
pom.xml
EmbeddedRedisConfiguration.java
And to finish it off we’ll expose one endpoint to actually verify the outcome of our security configuration.
UserController.java
We can verify the behaviour of our application by using curl:
curl -v http://localhost:8080/api/users
Now let’s do that again, but this time add Basic Authentication with our in-memory database user:
curl -v http://localhost:8080/api/users -u user:password
We send our credentials and received a x-auth-token
in the response, which we can use in the following requests to authenticate:
curl -v http://localhost:8080/api/users -H "x-auth-token: ef555ceb-1c77-4fdd-8e42-e04399fe5b95"
That’s all there is too it. If you have any questions or suggestions do let me know on any of the social links below.