JWTs with Spring Boot


24 Apr 2018  Sergio Martin Rubio  3 mins read.

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

  • Secure: JWTs are signed by using a secret or a public/private key pair.
  • Self-contained: all information is stored inside the JWT token. No need for further database calls.
  • Unmodifiable information, but exposed: Do not put secrets inside JWTs.
  • Compact format: JWTs are lightweight.

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:

  • Header: contains the token type (jwt) and hashing algorithm like SHA256 or RSA.
  • Payload: contains claims, which is the metadata (subjects, senders, or expiration date). There are three kinds of claims: registered, public, and private.
  • Signature: the combination of header, payload, secret, and the algorithm specified in the header. The signature ensures that nothing has changed.

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();
  • Issuer (iss): getIssuer() and setIssuer(String)
  • Subject (sub): getSubject() and setSubject(String)
  • Audience (aud): getAudience() and setAudience(String)
  • Expiration (exp): getExpiration() and setExpiration(Date)
  • Not Before (nbf): getNotBefore() and setNotBefore(Date)
  • Issued At (iat): getIssuedAt() and setIssuedAt(Date)
  • JWT ID (jti): getId() and setId(String)

All these parameters are available through Claims getters.

Verify JWT Token:

final Claims claims = Jwts.parser()
    .setSigningKey(JWT_SECRET)
    .parseClaimsJws(compactJws)
    .getBody();
  • JWT_SECRET is the secret used when we generate the token.
  • compactJws is the JWT token pass in the header.

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