Java JWT (JJWT)

Language: Java

Security/Authentication

JWTs have become the standard for stateless authentication in modern web applications and microservices. Libraries like JJWT (Java JWT) simplify working with JWTs by providing a fluent API for token creation, signing, and verification. They are compatible with HMAC, RSA, and EC algorithms and integrate easily with Spring Security or custom authentication systems.

Java JWT libraries provide tools for creating, parsing, and validating JSON Web Tokens (JWT) in Java applications. They are widely used for implementing stateless authentication, secure token-based authorization, and claims-based identity management.

Installation

maven: Add dependency in pom.xml: <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency>
gradle: implementation 'io.jsonwebtoken:jjwt-api:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

Usage

JWT libraries allow creation of signed tokens, verification of token signatures, and extraction of claims. They support symmetric (HMAC) and asymmetric (RSA/EC) signing algorithms and can be used in authentication, authorization, and API security scenarios.

Creating a JWT token

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

String jwt = Jwts.builder()
    .setSubject("user123")
    .setIssuedAt(new Date())
    .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hour
    .signWith(Keys.secretKeyFor(SignatureAlgorithm.HS256))
    .compact();

Creates a JWT token with subject 'user123', issued and expiration time, and signs it using HMAC SHA-256.

Parsing and validating a JWT token

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

var claims = Jwts.parserBuilder()
    .setSigningKey(secretKey)
    .build()
    .parseClaimsJws(jwt)
    .getBody();

System.out.println(claims.getSubject());

Parses and verifies the JWT signature, then extracts the claims (payload) securely.

Using custom claims

String jwt = Jwts.builder()
    .setSubject("user123")
    .claim("role", "admin")
    .claim("email", "user@example.com")
    .signWith(secretKey)
    .compact();

Adds custom claims like 'role' and 'email' to the JWT payload.

Validating token expiration

try {
    var claims = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(jwt).getBody();
} catch (io.jsonwebtoken.ExpiredJwtException e) {
    System.out.println("Token has expired");
}

Catches an exception if the token is expired.

Asymmetric signing with RSA

KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
String jwt = Jwts.builder()
    .setSubject("user123")
    .signWith(keyPair.getPrivate())
    .compact();

Creates a JWT signed using RSA private key and verifies using the public key.

Error Handling

io.jsonwebtoken.ExpiredJwtException: Occurs when the token is expired. Handle by returning an authentication error or refreshing the token.
io.jsonwebtoken.SignatureException: Occurs when the token signature is invalid. Verify the signing key and algorithm.
io.jsonwebtoken.MalformedJwtException: Occurs if the token format is invalid or tampered with.

Best Practices

Use strong signing algorithms (HS256, RS256, or ES256) for token integrity.

Set short expiration times and implement refresh tokens.

Do not store sensitive information in JWT payload.

Validate token signature and claims before granting access.

Use HTTPS for transmitting JWTs to prevent interception.