REST Authentication using Spring Security & Spring Session

In this post, I will try to demonstrate how easily we can implement an authentication mechanism for REST services using Spring Security and Spring Session with the help of Redis.

The authentication scheme that we will use:

  1. Client requests an authenticated URL with its credentials. (first request to the server)
  2. Server gives some unique string besides the normal response.
    (unique string is session id in our case)
  3. Client has to send this string with every request using an HTTP header.
  4. Server recognizes this unique string and logs client in.

Let’s start implementing the scheme above.

For this application to work, you must install Redis 2.8+ on localhost and run it with the default port (6379).

We will create very simple Spring Boot application which you can get source code and dependencies here.

Our security configuration looks like:

configureGlobal method is pretty straightforward, we just create a user with username sedooe and password password.

configure method is also straightforward but I want to emphasize two things here.

  1. We are using HTTP Basic Authentication since it is simplest way to deal with authentication. As you probably know, Basic Authentication is just a standard HTTP header with the username:password encoded in base64:
    Authorization: Basic c2Vkb29lOnBhc3N3b3Jk
    Keep in mind that encoding is not encrypting. Therefore, you must use HTTPS instead of HTTP to make sure that user credentials are sent securely.

  2. NullRequestCache prevents creation of session when user is not authenticated so that we have only authenticated users’ session ids stored in Redis.

In httpSessionStrategy method, Spring Session comes into play.
Thanks to HeaderHttpSessionStrategy, when a session is created, the HTTP response will have a response header of the specified name and the value of the session id. Default header name is x-auth-token and we will use it.

Here is our simple controller:

There is nothing to mention about this controller specifically so let’s start trying things out.

$ curl -v http://localhost:8080/api/resource

Yeah, authentication is required to access this resource. So try:
$ curl -v http://localhost:8080/api/resource -u sedooe:password

Now you are authenticated and you have access to the resource. Take a look at response headers and you will see that:
x-auth-token: 00661f53-8453-4daf-89f1-e748a3326040

For further requests, we can use x-auth-token instead of username and password.
$ curl -v http://localhost:8080/api/resource -H "x-auth-token: 00661f53-8453-4daf-89f1-e748a3326040"

If you want to see all stored tokens:
$ redis-cli keys '*'

To invalidate the session and delete it from Redis:
$ curl -v http://localhost:8080/api/logout -H "x-auth-token: 00661f53-8453-4daf-89f1-e748a3326040"

Note:

You may wonder how our application connected to Redis without writing any code for that.

Since we use Spring Boot 1.3.3 in this project and Spring Session and Spring Data Redis are both on the classpath, Spring Boot will auto-configure Spring Session to connect to Redis.

If you use earlier Spring Boot versions than 1.3.1 or don’t use it at all, you should add @EnableRedisHttpSession to your configuration class.