eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Introduction

JWT (JSON Web Token) is a standard that defines a compact and secure way of transmitting data along with a signature between two parties. The payload within a JWT is a JSON object that asserts some claims. This payload can be easily verified and trusted by the verifier as it’s digitally signed. JWTs can be signed using either a secret key or a public/private key pair.

In this tutorial, we’ll learn how to create and decode a JWT using the Auth0 JWT Java Library.

2. Structure of a JWT

A JWT basically consists of three parts:

  • Header
  • Payload
  • Signature

Each of these sections represents a Base64-encoded string separated by dots (‘.’) as a delimiter.

2.1. JWT Header

The JWT Header typically consists of two parts: the token type, which is “JWT”, and the signing algorithm used to sign the JWT.

The Auth0 Java JWT library provides various algorithm implementations to sign a JWT like HMAC, RSA, and ECDSA.

Let’s have a look at a sample JWT Header:

{
  "alg": "HS256",
  "typ": "JWT"
}

The above header object is then Base64-encoded to form the first part of the JWT.

2.2. JWT Payload

The JWT Payload contains a set of claims. Claims are basically statements about an entity along with some additional data.

There are three types of claims:

  • Registered – These are a set of useful predefined claims that are recommended but not mandatory. These claim names are only three characters long to keep the JWT compact. Some of the registered claims include iss (issuer), exp (expiration time), and sub (subject), among others.
  • Public – These can be defined at will by those using JWTs.
  • Private – We can use these claims to create custom claims.

Let’s take a look at a sample JWT Payload:

{
  "sub": "Baeldung Details",
  "nbf": 1669463994,
  "iss": "Baeldung",
  "exp": 1669463998,
  "userId": "1234",
  "iat": 1669463993,
  "jti": "b44bd6c6-f128-4415-8458-6d8b4bc98e4a"
}

Here, we can see that the Payload contains a private claim userId denoting the logged-in user’s ID. Also, we can find some other useful restricted claims that define additional details about the JWT.

The JWT Payload is then Base64-encoded to form the second part of the JWT.

2.3. JWT Signature

Lastly, the JWT Signature is generated when we sign the encoded header and encoded payload using a signing algorithm with a secret key. The signature can then be used to verify if the data within the JWT is valid.

It’s important to note that anyone having access to a JWT can easily decode and view its content. Signed tokens can verify the integrity of claims contained within them. If tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.

Finally, combining all three parts, we get our JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJCYWVsZHVuZyBEZXRhaWxzIiwibmJmIjoxNjY5NDYzOTk0LCJpc3MiOiJCYWVsZHVuZyIsImV4cCI6MTY2OTQ2Mzk5OCwidXNlcklkIjoiMTIzNCIsImlhdCI6MTY2OTQ2Mzk5MywianRpIjoiYjQ0YmQ2YzYtZjEyOC00NDE1LTg0NTgtNmQ4YjRiYzk4ZTRhIn0.14jm1FVPXFDJCUBARDTQkUErMmUTqdt5uMTGW6hDuV0

Next, let’s look at how we can create and manage a JWT using the Auth0 Java JWT library.

3. Using Auth0

Auth0 provides an easy-to-use Java library for creating and managing JWTs.

3.1. Dependencies

To get started, we add the Auth0 Java JWT library’s Maven dependency to our project’s pom.xml file:

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>4.2.1</version>
</dependency>

3.2. Configure Algorithm and Verifier

We first create an instance of the Algorithm class. In this tutorial, we’ll use the HMAC256 algorithm to sign our JWT:

Algorithm algorithm = Algorithm.HMAC256("baeldung");

Here, we initialize an instance of an Algorithm with a secret key. We’ll later use this during both the creation and verification of a token.

Further, let’s initialize an instance of JWTVerifier that we’ll be using to verify the created token:

JWTVerifier verifier = JWT.require(algorithm)
  .withIssuer("Baeldung")
  .build();

To initialize the verifier, we use the JWT.require(Algorithm) method. This method returns an instance of Verification that we can then use to build an instance of JWTVerifier.

We are now ready to create our JWT.

3.3. Create a JWT

To create a JWT, we use the JWT.create() method. The method returns an instance of the JWTCreator.Builder class. We will use this Builder class to build the JWT token by signing the claims using the Algorithm instance:

String jwtToken = JWT.create()
  .withIssuer("Baeldung")
  .withSubject("Baeldung Details")
  .withClaim("userId", "1234")
  .withIssuedAt(new Date())
  .withExpiresAt(new Date(System.currentTimeMillis() + 5000L))
  .withJWTId(UUID.randomUUID()
    .toString())
  .withNotBefore(new Date(System.currentTimeMillis() + 1000L))
  .sign(algorithm);

The above snippet returns a JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJCYWVsZHVuZyBEZXRhaWxzIiwibmJmIjoxNjY5NDYzOTk0LCJpc3MiOiJCYWVsZHVuZyIsImV4cCI6MTY2OTQ2Mzk5OCwidXNlcklkIjoiMTIzNCIsImlhdCI6MTY2OTQ2Mzk5MywianRpIjoiYjQ0YmQ2YzYtZjEyOC00NDE1LTg0NTgtNmQ4YjRiYzk4ZTRhIn0.14jm1FVPXFDJCUBARDTQkUErMmUTqdt5uMTGW6hDuV0

Let’s discuss some of the JWTCreator.Builder class methods used above to set some of the claims:

  • withIssuer() – identifies the party that created the token and signed it
  • withSubject() – identifies the subject of the JWT
  • withIssuedAt() – identifies the time at which the JWT was created; we can use this to determine the age of the JWT
  • withExpiresAt() – identifies the expiration time of the JWT
  • withJWTId() – unique identifier for the JWT
  • withNotBefore() – identifies the time before which the JWT should not be accepted for processing
  • withClaim() – used to set any custom claim

3.4. Verifying a JWT

Further, to verify a JWT, we use the JWTVerifier.verify(String) method from the JWTVerifier we initialized earlier. If the JWT is valid, the method parses the JWT and returns an instance of DecodedJWT.

The DecodedJWT instance provides various convenience methods we can use to fetch the claims contained in the JWT. If the JWT is invalid, the method throws a JWTVerificationException.

Let’s decode the JWT we created earlier:

try {
    DecodedJWT decodedJWT = verifier.verify(jwtToken);
} catch (JWTVerificationException e) {
    System.out.println(e.getMessage());
}

Once we obtain an instance of the DecodedJWT instance, we can use its various getter methods to obtain the claims.

For example, to obtain the custom claims, we use the DecodedJWT.getClaim(String) method. This method returns an instance of a Claim:

Claim claim = decodedJWT.getClaim("userId");

Here, we’re fetching our custom claim userId that we set earlier while creating the JWT. We can now obtain our claim value by calling the Claim.asString() or any other available method based on the data type of the claim:

String userId = claim.asString();

The above snippet returns the String1234″ of our custom claim.

In addition to the Auth0 Java JWT library, Auth0 also provides an intuitive web-based JWT Debugger to help us decode and verify a JWT.

4. Conclusion

In this article, we looked at the structure of a JWT and how it can be used for authentication.

We then used the Auth0 Java JWT library to create and verify the integrity of a token using its signature, algorithm, and secret key.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LSS – NPI (cat=Security/Spring Security)
announcement - icon

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)