Add and Validate Custom Claims in JWT

In this tutorial, you will learn how to add JWT support to your Spring Boot application and also how to add and validate custom JWT Claims.

In this tutorial, I am going to use a very simple Spring Boot application generated with Spring Tools. To learn how to create a very simple Spring Boot application or even a very simple Spring Boot Web Service have a look at this tutorial: Create a Simple Web Service with Spring Initializr.

Once you have your Spring Boot application created you can add JWT dependency to it.

Add JWT Dependency to Spring Boot Application

Adding JWT support to a Spring Boot application is very simple. All you need to do is to add a short XML code snippet to a pom.xml file. You can find the JWT support dependency XML code snippet here: JSON Web Token Support For The JVM. Just pick the version you need.

At the time of writing this tutorial, the latest version of JWT dependency is 0.9.1. So I am going to add to a pom.xml file of my Spring Boot application the following XML code snippet.

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

When working with JWT I also had to add the XML support to my Spring Boot application. You can do so by adding the following dependency to pom.xml file.

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

Generate Simple JWT

To generate a new JWT I will use the Jwts.builder() which comes with the JJWT dependency we have added to a pom.xml file.

The below code snippet is a custom function which accepts three parameters:

subject – which is a value that identifies the principal user. This value can be a user ID or userName for which this JWT was generated,
expDate – this is the value when the JWT should expire,
secret – this value is a secret key which is usually a unique alpha-numeric Spring of characters and should be kept private.  It is this secret key with which the JWT will be signed using one of the security algorithms like for example HMAC SHA256.

public String generateJWT(String subject, Date expDate, String secret) {
     // Generate GWT
     String token = Jwts.builder()
     .setSubject(subject)
     .setExpiration(expDate)
     .signWith(SignatureAlgorithm.HS512, secret )
     .compact();
     
     return token;
}

To run this code I will create a very simple Utility class and will run it in a Spring Boot console application. To learn how to create a very simple Spring Boot Console application read the following tutorial: Spring Boot Console Application.

import com.appsdeveloperblog.tutorials.jwtclaims.security.MyJWTUtils;
import java.util.Date;

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class JWTDemo implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {

        MyJWTUtils jwtUtil = new MyJWTUtils();
        String subject = "MyUserName";
        Date expDate = new Date(System.currentTimeMillis() + Long.parseLong("3600000"));
        String tokenSecret = "1nc4jRjdO5enfUc4loN3q7gEb8fhr9O";
        String token = jwtUtil.generateJWT(subject, expDate, tokenSecret);

        System.out.println("Generated JWT = " + token);
    }

}

If I run the above Spring Boot application I will get the following JWT printed:

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJNeVVzZXJOYW1lIiwiZXhwIjoxNTc3MDUwODY3fQ.2jv6zWqbsBJrthFFntpWUUis1hjyuIc2KUPCcKEL23hO1S2scAjWyQrHxNVyMM_JUviIQEPpgPZ0XRFau_7Lmw

The JWT is Base64 encoded and you can easily decode it with any Base64 decoder online tool. Because the content of JWT can be easily decoded, you should never place a user’s sensitive information into the JWT token. For example, never include the user’s password or token secret with which the JWT was signed in the body of the JWT token.

Validate JWT

To validate the JWT we will need to use the same secret key with which the JWT was earlier signed. If the token secret is not correct the following error will be thrown when JWT is validated: “io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.

You can use the following code snippet to validate JWT and read the subject value.

String subject = Jwts.parser()
                .setSigningKey(tokenSecret)
                .parseClaimsJws(jwt)
                .getBody()
                .getSubject();

Add Custom Claims to JWT

Claims live in the Body of JWT.  JWT Claims are pieces of information that are asserted to the subject and are key-value pairs. There are claims that are reserved to ensure interoperability with third-party, or external, applications and there are custom claims that can be added to JWT by you. If needed you can add additional pieces of information(custom claims) about the subject or the user for which the JWT is created.

Reserved Claims

Let’s have a look at the list of reserved claims.

iss – Issuer,
sub – Subject,
aud – Audience,
exp – Expiration,
nbf – Not Before,
iat – Issued At,
jti – JWT ID

Custom Claims

Custom claims are custom key-value pairs that you can add to the body of JWT. It can be a user Role or a Privilege, it can be the user’s department at work or anything else you need to add to JWT. For example, in the below code snippet I am adding two custom claims to JWT which are the user’s Role and Department at work.

// Generate GWT
String token = Jwts.builder()
.setSubject(subject)
.setExpiration(expDate)
.claim("Role", "Admin")
.claim("Department", "Product development")
.signWith(SignatureAlgorithm.HS512, secret )
.compact();

In the above code example, I have added two custom claims: Role and Department. If needed you can add more claims to the body of JWT. Just remember not to add sensitive information like a user password or token secret. JWT claims can be decoded and viewed.

Read Custom Claims

To read the custom Claims from the body of JWT token you can use the following code snippet.

Claims claims = Jwts.parser()         
   .setSigningKey(tokenSecret)
   .parseClaimsJws(jwt).getBody();
 
// Reading Reserved Claims
System.out.println("Subject: " + claims.getSubject());
System.out.println("Expiration: " + claims.getExpiration());

// Reading Custom Claims
System.out.println("Role: " + claims.get("Role"));
System.out.println("Department: " + claims.get("Department"));

Remember that JWT is a Base64 encoded string and can be easily decoded. Therefore, you should not put into Claims any user details that are sensitive. Even though the information in Claims cannot be altered, this information can be viewed by the Base64-decoding JWT token.

I hope this tutorial was helpful to you. If you are interested to learn more about Spring Boot and Spring Security check out my other tutorials on this blog. If you are interested to learn about Microservices and Spring Cloud, then check out this page: Spring Cloud.

If you enjoy learning by following step-by-step online video courses, then have a look at the below list of online video courses that teach Spring Security. One of them might be very helpful.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free Video Lessons

Enter your email and stay on top of things,

Subscribe!