JWTs with Spring Boot

Introduction

JWT (JSON Web Token) is an open source standard commonly used to transmit data between two services in a compact and secure way. This standard offers a wide range of libraries to generate JWTs and includes libraries for platforms such as .NET, Python, Node.js, Java, JavaScript, Perl, Ruby, Elixir, Golang, Groovy, and Haskell.

Features

How Does It Work?

JWT Communication
JWT Communication
  1. JWTs can be added to the URL, sent via POST as part of a parameter or added to the HTTP request header.
  2. It contains a payload with information about the sender, issued date, expiration dateā€¦
  3. JWTs are usually generated during the authentication phase, and once the user is logged in, the JWT previously generated allows the user to access to resources without having to make additional calls to databases.
  4. They can be used to exchange information between services in a secure way, making sure that it was not modified during the transmission. This is possible because the signature is calculated using the header and payload.
  5. The token is stored locally or in a cookie.
  6. When the user wants to use the token, the convention is to add it to the header in the Authorization field using the Bearer prefix followed with the token value.

e.g.

Authorization: Bearer

JWT format

JWTs are structured in three parts separated by dots:

As a result, the format is xxx.yyy.zzz

Java Integration

The jjwt library provides all you need to generate signed tokens in a Java application.

Maven dependency:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

Generate JWT Token:

String jwt = Jwts.builder()
    .setClaims(claims)
    .setSubject(email)
    .setIssuedAt(new Date())
    .setExpiration(new Date(System.currentTimeMillis()+ JWT_EXPIRATION_TIME))
    .signWith(SignatureAlgorithm.HS256, JWT_SECRET)
    .compact();

All these parameters are available through Claims getters.

Verify JWT Token:

final Claims claims = Jwts.parser()
    .setSigningKey(JWT_SECRET)
    .parseClaimsJws(compactJws)
    .getBody();

If the verfication succeed we will be able to store the metadata in a claims variable that is available to consume later. On the other hand, If the verification fails SignatureException is thrown.

Troubleshooting

In case you are using Java 9+, make sure you add an explicit dependency to the POM file.

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>

jaxb-api is missing in Java 9, and until jjwt adds the dependency or removes the usage of JAXB classes, we have to add it manually.

Source Code