From stateful to stateless RESTful security using Spring and JWTs – Part 2 (session-based authentication)

We’re going to set up a RESTful API which we will secure using Spring Security and session-based (stateful) authentication. We will also write some JUnit tests to verify our application behavior. By the end of this chapter you will have a working, secured RESTful API which we will modify later to bring to its stateless incarnation.

So crack your joints and let’s start coding!

(or point your browser to this chapter’s code on GitHub. Whatever rocks your boat!)

Related posts

Booting up!

This being a Maven project, let’s start with our pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=""




        <!-- EMBEDDED SERVER -->

        <!-- WEB / REST -->

        <!-- SECURITY -->

        <!-- LOGGING -->

        <!-- TESTING -->




In essence, dependency management is used to import Spring Boot’s default dependencies. We then explicitly specify which parts (Spring Boot starters, libraries) we want to use.
For this project we will get everything we need by using five starters:

  • jetty: brings Jetty instead of Tomcat as an embedded server. This is purely a preference thing. Feel free to keep Tomcat if you want!
  • web: includes Spring MVC and all that’s needed to implement our RESTful API using Spring. Please note that the web starter also imports the Tomcat starter! You might want to exclude it, since we are working with Jetty anyway…
  • security: brings in Spring Security on-board
  • logging: sets Logback as the default logger.
  • test: yes, we will test our code. Because we’re professionals, hey!

Let’s not forget to set Java to 8, both in Maven’s properties and in Maven’s compiler plug-in. We also specify Spring Boot’s Maven plug-in so one can start the application from command-line should he need to:

$ mvn spring-boot:run

Being a Spring Boot application, we need to define our point-of-entry class, which we’ll name “Application“:

package be.codesandnotes;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

public class Application {
    public static void main(String[] args) {, args);

That neat @SpringBootApplication annotation enables Spring Boot’s auto-configuration, component scanning and makes this class a configuration class in case you want to start defining @Beans in there.

Because I’m API…

(OMG that was lame, sorry!)

Yeah… eeeh, let’s work on our RESTful API, shall we?

package be.codesandnotes.greetings;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.http.MediaType.*;
import static org.springframework.web.bind.annotation.RequestMethod.*;

public class GreetingsRest {

    @RequestMapping(path = "/unsecure/greetings", method = GET, produces = APPLICATION_JSON_VALUE)
    ResponseEntity<GreetingWebObject> unsecuredGreetings() {
        return ResponseEntity.ok(new GreetingWebObject("Greetings and salutations!"));

    @RequestMapping(path = "/secure/greetings", method = GET, produces = APPLICATION_JSON_VALUE)
    ResponseEntity<GreetingWebObject> securedGreetings(Principal principal) {
        return ResponseEntity.ok(new GreetingWebObject("Greetings and salutations, " + principal.getName() + "!"));

Nothing extraordinarily fancy in there:

  • The @RestController is another one of those very useful annotations which considers the class as @Controller and every @RequestMapping method as binding the method’s return object to the response’s body, exactly as if the methods were annotated with @ResponseBody.
  • We separate our two GET mappings by defining two paths: “secure” and “unsecure”. Every end point under the “unsecure” path will be made freely accessible, as opposed to every other path.
  • We return ResponseEntity objects carrying a GreetingWebObject. This will be automatically converted to an adequate JSON structure thanks to Jackson, which is imported by Spring boot’s web starter. Nothing else needs to be done, except specifying that we return a JSON value.
  • The secured greetings will be able to leverage the Principal object (aka the logged user’s details) to customize our greetings’ message. Obviously this only works when the user is authenticated.
  • Heads up! Don’t do the same mistake I regularly do: don’t specify a “consumes” property in @RequestMapping. These are GET methods, so we don’t need to have them consume anything. We’ll get 415 errors if we try it. If you need to pass parameters to a GET, you are free to use path variables or request params (aka query params).

Tests first

Normally I would go TDD/BDD and write these before implementing the API code. Then again this is a tutorial, so…

Okay, so we want our unsecured end point to return our message, no authentication needed. On the other hand, we want our secure end point to block our request if we are not logged in. In case we are logged in, then we need our secured end point to return a customized message… that’s the privileged greeting for authenticated users!

package be.codesandnotes.greetings;

import be.codesandnotes.TestRestClient;
import be.codesandnotes.IntegrationTestsApplication;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import static org.junit.Assert.*;

        classes = IntegrationTestsApplication.class,
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
public class GreetingsRestTest {

    private TestRestTemplate restTemplate;

    private TestRestClient restClient;

    public void init() {
        restClient = new TestRestClient(restTemplate);

    public void returnUnsecuredGreetings() {
        ResponseEntity<GreetingWebObject> response
                = restTemplate.getForEntity("/rest/unsecure/greetings", GreetingWebObject.class);

        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("Greetings and salutations!", response.getBody().getMessage());

    public void returnSecureGreetings() {
        TestRestClient.Credentials credentials = restClient.login("user", "user");
        ResponseEntity<GreetingWebObject> response = restClient.get("/rest/secure/greetings", credentials, GreetingWebObject.class);

        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("Greetings and salutations, user!", response.getBody().getMessage());

    public void protectAccessToSecureGreetingsWhenUserIsNotLogged() {
        ResponseEntity<GreetingWebObject> response = restTemplate.getForEntity("/rest/secure/greetings", GreetingWebObject.class);

        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());

We set up a Spring Boot context that relies on an IntegrationTestsApplication class. The tests use Spring Boot’s TestRestTemplate to query the unsecured REST end point, and a custom client class of mine to query the secured end point. That custom class simply allows to authenticate oneself through form-based logins and to leverage those credentials when performing requests on secured end points.

If we run these tests now, a couple of them will fail.
One will not be able to obtain credentials and as such will trigger an ugly NullPointerException on my client class (sorry, I guess I have been a tad lazy on that one!). That’s because by default Spring Boot configures Security to use basic authentication with a default user name and a random password. And yeah, our user/user profile does not exist yet either!
The other error we get happens when accessing our unsecured end point. By default, Spring Boot’s configuration will protect all paths! The mere fact of calling our path “/unsecure” won’t change a thing. We’ll have to tell Spring Security that everything under that path must be freely accessible.

In order to make those tests pass, we’ll have to dig into Spring Security’s configuration.

Security check

Since our Application class is enabling component scan, we can set up our security in a separate configuration class and have it picked up at start up.


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    private AuthenticationEntryPoint authenticationEntryPoint;

    private AuthenticationFailureHandler authenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler();

    private AuthenticationSuccessHandler authenticationSuccessHandler;

    private LogoutSuccessHandler logoutSuccessHandler;

    protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {

    protected void configure(HttpSecurity httpSecurity) throws Exception {





The SecurityConfiguration class extends WebSecurityConfigurerAdapter so that selected aspects can be overridden as needed.

The overridden method taking an AuthenticationManagerBuilder as a method parameter allows us to define where our users’ profiles are stored. Normally we would specify an implementation that fetches your users’ profiles from a JDBC database or an LDAP. Since we’re in a tutorial we can go for an in-memory manager, which allows us to define a test profile on-the-fly (“user”. Top marks for originality, right?).

The other overridden method takes an HttpSecurity instance, which allows us to configure our web security. Various aspects of security are being addressed there.

  • We start by disabling CSRF protection. In a few words: CSRF protection makes Spring Security generate and send a token to the browser. The browser has to send it back to prove that he, not someone else, is talking to the server. This is an extra layer of protection that is enabled by default by Spring Security. It can be easily implemented for stateful authentication, as described here. However we want to focus on the basics first, so we’ll disable it for now. Later on, we’ll see how to add CSRF protection in a stateless way.
  • We also tap on exceptions handling. Specifically, we want to redefine the authentication entry point which is going to come into play when an exception due to an unauthorized access is raised. Normally Spring Security would redirect to a login page, but since we’re talking RESTful here, we must return a 401.
  • We’re using the form-based login approach to submit our credentials. Again, we customize the handler that defines what happens in case of login success. The same is done for handling login failure, except that in this case we can get the job done by merely creating a SimpleUrlAuthenticationFailureHandler instance.
  • We redefine the logout, specifying the URL to be called for the logout to happen. Here again we customize what must happen when logging out. For RESTful APIs, it can be summarized to… “do nothing“.
  • Last but not least, we define which paths’ accesses must be restricted. Since we want to follow good practices, we think this the other way: we set everything to restricted access, and we define which paths are accessible without authentication. In our case, that would be everything under “/rest/unsecure/”.

With our security configuration set up, you can now try and run those tests again: they should all be green!


In this chapter we’ve merely set up the essential authentication mechanisms to secure your RESTful server application.
That’s not bad. But we still use a stateful, session-based approach: the server is still maintaining a session object to keep track of authenticated users!

So next time we’ll fix that and move to a token-based authentication implementation.

Until then,



0 comment

  1. Tom Reply
    30/04/2018 at 20:00

    I am new to api design/implementation, and at this point in time very confused as to what I should use/not (misc list: oauth/session, swagger, hateaos, rest-assured, etc… ). Anyway … we currently have a couple api calls, and we’re using spring session based security, which was very easy to implement 🙂 . So my question is, why go to a token based security, when session based seems to work well (for us)?

    • codesandnotes_ Reply
      30/04/2018 at 20:43

      Hi Tom!

      This is discussed in greater length in Part 6 of the series.
      To make it short: you may want to use tokens if you have to deal with a big distributed, multi-server architecture (that is, when you never know which of your servers your API call is going to hit) that needs to be scaled easily.
      Think Twitter-like applications. They grew up to have a lot of users, right? So instead of redirecting them all to the same server, which would quickly become overloaded, they send the API calls to whatever server is the least loaded. But then how can that server tell that the user is logged? Server-side session data would need to be shared across all the existing servers!
      Enter token-based authentication: instead of having 100 servers exchanging session data, you have your web/mobile client send a JWT with a signed payload (“I am Bob!”). Since JWTs are signed, the server can trust what they declare (“He’s Bob indeed!”). No need to share session data between servers.

      As far as you go: if you’re happy with session-based security… keep it! It’s reliable and it looks like it suits your needs. If you later need to scale to a 100 servers, you can always replace ye old sessions with a token-based solution. But for the moment, I’d say: stay with what works for you!

      (oh and if you scale to 100 servers, that means you’re successful. Remember to tip your favorite blogger… that’s me! 😉

Leave A Comment

Please be polite. We appreciate that. Your email address will not be published and required fields are marked

This site uses Akismet to reduce spam. Learn how your comment data is processed.