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

We previously managed to move to statelessness, which is a good step forward. We managed to get rid of Session objects!

However we did it by adopting a very naive (shall we even say: pretty much unusable!) solution for identifying a user. We still need to find a system to make those tokens secure, tamper-proof and bearing a verifiable origin. Lucky us, JWTs will be our salvation!

So suit up and get ready to dive into the fantastic world of JSON Web Tokens! (or click on this link to get that GitHub code. It’s a free world, right? 😉 )

Related posts

So, what’s a JWT anyway?

Authenticating against a RESTful API actually implies having a server recognize a given user and save that proof-of-authentication somehow (in a Session object or in a token). If we think “stateless” then the server can’t keep that proof-of-authentication, so it needs to transmit it to the user’s browser.
We certainly don’t want the user (or any other malevolent entity!) to mess with that proof-of-authentication, so it has to be secured against anyone but the server itself. This way, when the user sends that proof-of-authentication back to the server to access a REST endpoint, the server can be 100% sure of the authenticity of the client.

A JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object (quoted from

Compact is nice, but we’ll later see that it’s not as compact as a JSESSIONID. Food for thought for a forthcoming post…
Self-contained: it’d better be, since we’ve giving up on keeping a state on the server-side.
Securely transmits information between parties? We hit the jackpot!
JWTs are also digitally signed, so no tampering allowed there.

A JWT is composed of three parts:

  1. A header, which indicates the type of the token being exchanged (and we set that to… “JWT”, correct!) and the hashing algorithm applied on it.
  2. A payload (body) carrying a series of claims, aka statements about the authenticated user (full name, admin or not…), who issued the JWT, when it expires, etc.
  3. A signature, which allows us to verify that the JWT emitter is indeed who it says he is and that the message hasn’t been tampered with.

In practice, JWTs are typically exchanged in the Authorization header, using the Bearer schema. They are meant to be stored by the client, usually in the browser’s local storage or in a cookie (more on that in a forthcoming post).

Give me a JWT

Since we don’t want to reinvent the wheel, let’s start by importing a library to generate those JWTs. I’ve decided to go with jjwt, by there are plenty of other great projects for that purpose. Just check the list on


Beyond a few constants, our SecurityConfiguration stays the same:

static final long TOKEN_LIFETIME = 604_800_000; // That's 7 days
static final String TOKEN_PREFIX = "Bearer ";
static final String TOKEN_SECRET = "ThisIsOurSecretKeyToSignOurTokens";

That secret key will be used to sign our emitted token: that’s essential to ensure that no one has tampered with the token’s listed claims!

Moving on to the TokenBasedAuthenticationFilter class, we will now generate a real token at user authentication, using the jjwt library:


import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.http.HttpHeaders;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.UUID;

import static*;

public class TokenBasedAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    TokenBasedAuthenticationFilter(AuthenticationManager authenticationManager) {

    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                            Authentication authentication) throws IOException, ServletException {
        String token = Jwts.builder()
                .setSubject(((User) authentication.getPrincipal()).getUsername())
                .setExpiration(new Date(System.currentTimeMillis() + TOKEN_LIFETIME))
                .signWith(SignatureAlgorithm.HS512, TOKEN_SECRET)

        response.addHeader(HttpHeaders.AUTHORIZATION, TOKEN_PREFIX + token);

By using the Jwts builder, we specify three reserved claims: the token ID (“jti“), its subject (“sub“) used to identify the principal (in our context, that’s the user’s username), and an expiration time (“exp“) that indicates the time at which the token ceases to be valid.

The important bit here is the token ID, which we generate randomly. By adding entropy (aka randomness) to the token, we can mitigate replay attacks by generating new tokens (with new IDs) at short intervals. Of course for this to make any sense the expiration claim, set by the TOKEN_LIFETIME constant, should be lowered from 7 days to, say, 15 or 30 minutes.

The library then allows us to sign the token with a specified algorithm and a secret which, it goes without saying, is only effective if not leaked.

Finally the compact() method generates our token while also compacting it according to the official specifications.

Leeloo Dallas multipass

So now a client needs to access our RESTful API and sends his/her token on the Authorization HTTP header. The back end needs to verify the token signature and extract the claims from it. In our case, the only claims we’ll get is the subject (the user’s username) and the expiration time. Let’s reexamine our TokenBasedAuthorizationFilter from last time:


import io.jsonwebtoken.Jwts;
import org.springframework.http.HttpHeaders;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;

import static*;

public class TokenBasedAuthorizationFilter extends BasicAuthenticationFilter {

    TokenBasedAuthorizationFilter(AuthenticationManager authenticationManager) {

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        String authorizationToken = request.getHeader(HttpHeaders.AUTHORIZATION);

        if (authorizationToken != null && authorizationToken.startsWith(TOKEN_PREFIX)) {
            authorizationToken = authorizationToken.replaceFirst(TOKEN_PREFIX, "");

            String username = Jwts.parser()

                    .setAuthentication(new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList()));

        chain.doFilter(request, response);

After retrieving it from the HTTP request, the submitted token is parsed to extract the claims from its body section. In the process, the secret key is used to verify the token’s signature and make sure it has not been tampered with.

In our tutorial, we merely want to know who that user pretending he’s logged is, so we obtain the subject (username) from the token’s claims and pass it to the SecurityContextHolder. Later in the flow of events, a @Controller‘s method will be able to leverage the Principal object to obtain that username. You can also provide the user’s roles, to be fed to the security context as the “authorities” parameter (currently set to an empty collection).

Just make sure you leave that credentials parameter to null: you sure don’t want to carry the user’s password around in that token! Don’t forget that, although the token is signed to make sure it’s authentic, it is NOT encrypted. The reason it looks unreadable is because it is base64-encoded, but anyone with a bit of knowledge can read its claims.
Try pasting the JWT below on this website for decoding:


The moral of the story is: never pass sensitive data into a JWT!!!

Are we done then?

Congratulations, you now have the basics to implement stateless JWT authentication on your Spring-based RESTful API!

Before you rush out and add token-based security to your new application, we still have a couple of things to discuss.
One of those is the storage of that token on the client side. If you decide to store it in a cookie, you might want to review the options in terms of defending against CSRF attacks. I will also provide you with a list of useful web resources I used to write this tutorial. There are people out there who have really studied the subject and explained the core of it in simple terms, they should definitely be thanked for that!

Finally, there’s an important question we need to answer: should you actually use JWT-based authentication?
This is definitely a tricky decision to make, and I’ll try to expose as clearly as possible my thoughts on the pros and cons of going stateless.

Until next time,




  1. Martin Reus Reply
    30/07/2018 at 18:06


    First of all thanks for this comprehensive tutorial!
    After having finished this part, I successfully authenticate with my Server. The problem I see now is that the JSESSIONID is being set again, meaning that I could use only the session to get hold on server protected resources without passing in the Authorization headers, which pretty much renders this tutorial useless =)

    Any clues on how to resolve this little problem? I saw that at this point in the tutorial you removed the AuthenticationSuccessHandler which previously disabled sessions…


  2. Martin Reus Reply
    30/07/2018 at 19:40

    Uh! I got it.


    did the trick.

    • Diego Reply
      30/07/2018 at 20:43

      Wow that was fast!
      I was about to respond something like, even when a JSESSIONID is being set (as part of Spring Security’s CSRF mechanism) it doesn’t mean that the JWT authentication and authorization mechanisms are thwarted.
      But you were faster AND taught me something in the process!
      Thank you, Sir!

      • Martin Reus Reply
        31/07/2018 at 16:32

        I have to admit I was a bit dramatic when saying that the JWT authentication was rendered useless when having a JSESSIONID. Sorry about that hah! What I meant was that the whole point of having JWT was to enable completely stateless servers, and in my humble opinion not even present the possibility of using sessions. Hope this helps others! Cheers!

  3. Chris Wiles Reply
    12/03/2019 at 15:40

    I can implement stateless security using JWT, but my stateless pages still produce a JSESSION cookie, despite implementing .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).

    As I have JWT, I would like to simply disable cookies from my entire system. How can this be done?

    • Diego Reply
      12/03/2019 at 16:52

      Hi Chris,

      I’m honestly not quite sure how to help you, as configuring the session creation policy is the one method I’m aware of to stop generating JSESSIONID cookies… That’s the method I use on my projects anyway.
      With that said: I know it sounds silly, but have you made sure to clear all browser cookies before testing? Moving to STATELESS doesn’t actually delete old JSESSIONID cookies…

  4. Alex Reply
    28/09/2020 at 16:49

    Since you disabled httpBasic(), how does the client perform the initial login in order to generate the token?

    • Diego Reply
      29/09/2020 at 11:07

      Hi Alex! Oh boy, I haven’t looked at that code for a while!
      In short: the TokenBasedAuthenticationFilter takes over the initial login.

      The trick is in the SecurityConfiguration class. A few important things to note:

      1. We use the default Spring Security login path, which is “/login”
      2. We define an authentication manager that uses MyUserDetailsService to actually check if the username/password are correct
      3. We pass this authentication manager to the TokenBasedAuthenticationFilter, which we add to our HttpSecurity in the configuration() method in the SecurityConfiguration class

      Here’s what happens when we login:

      1. The default httpoBasic() and formLogin() are disabled, so they are skipped. BUT…
      2. Our TokenBasedAuthenticationFilter takes over!
      3. First thing, it invokes our authentication manager (which we have given at construction, remember?) which itself calls our MyUserDetailsService.
      4. MyUserDetailsService.loadUserByUsername() says “hey, this dude’s ok and authenticated”
      5. So Spring Security then class TokenBasedAuthenticationFilter.successfulAuthentication() method which generates our JWT token

      And that’s that! Feel free to run the GreetingsRestTest.returnSecureGreetings() method in debug mode in your IDE, putting debug points in MyUserDetailsService and TokenBasedAuthenticationFilter to see the sequence of the whole process.

      Hope this clarifies things a bit!


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.