JSON Web Token implementation for Java according to RFC 7519. Easily create, parse and validate JSON Web Tokens using a fluent API.

Overview

JWT-Java

Build & Test

JSON Web Token library for Java according to RFC 7519.

Table of Contents

What are JSON Web Tokens?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public / private key pair using RSA or ECDSA.

JSON Web Tokens consist of three parts, which are seperated with .'s:

  • Header
  • Payload
  • Signature

A JWT has therefore the following structure: xxxxx.yyyyy.zzzzz

Header

The header holds information about the JWT. It typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used, such as HMAC SHA256 or RSA. There are two registered header parameters:

  • typ: Type, is used by JWT applications to declare the media type of this complete JWT
  • cty: Content Type, is used by this specification to convey structural information about the JWT

Payload

The second part of the token is the payload, which contains the claims. Claims are statements about an entity and additional data. Reserved claims are called registered claims. There are seven registered claims:

  • iss: Issuer, identifies the principal that issued the JWT
  • sub: Subject, identifies the principal that is the subject of the JWT
  • aud: Audience, identifies the principal that is the audience of the JWT
  • exp: Expiration Time, identifies the expiration time on or after which the JWT must not be accepted for processing
  • nbf: Not-before, identifies the time before which the JWT must not be accepted for processing
  • iat: Issued At, identifies the time at which the JWT was issued
  • jti: JWT ID, provides a unique identifier for the JWT

Signature

To create the signature part you have to take the Base64URL encoded header, the Base64URL encoded payload, a secret, the algorithm specified in the header, and sign that.

Features

  • Creating JSON Web Tokens
  • Powerful JWT validation options
  • Self explanatory and easy to learn API
  • Fluent interfaces

Supported algorithms

SHA256 SHA384 SHA512
HMAC ✔️ ✔️ ✔️
RSA ✔️ ✔️ ✔️

Installation

Maven

<dependency>
    <groupId>com.github.bastiaanjansen</groupId>
    <artifactId>jwt-java</artifactId>
    <version>1.2.0</version>
</dependency>

Gradle

implementation 'com.github.bastiaanjansen:jwt-java:1.2.0'

Usage

Choose algorithm

To generate a JSON Web Token, you can use the fluent-interface builder API. But first, the builder expects an Algorithm instance. The Algorithm class has several static helper methods to create concrete Algorithm instances. For example, when you want to use the HMAC512 algorithm to sign your JWT's, create an Algorithm instance the following way:

Algorithm algorithm = Algorithm.HMAC512("secret");

Or use another algorithm:

KeyPair keyPair = // Get key pair
Algorithm algorithm = Algorithm.RSA512(keyPair);

For a list of available algorithms: Supported algorithms

Secrets

HMAC-SHA
  • HS256 secret key must be at least 256 bits (or 32 bytes) long
  • HS384 secret key must be at least 384 bits (or 48 bytes) long
  • HS512 secret key must be at least 512 bits (or 64 bytes) long
RSA

All RSA algorithms require a secret which is at least 2048 bits (or 256 bytes) long.

Creating JWT's

When you have chosen an algorithm, you can use the JWT Builder to define how the JWT must look like and sign the token:

try {
  String jwt = new JWT.Builder(algorithm)
    .withIssuer("issuer")
    .withAudience("aud1", "aud2")
    .withIssuedAt(new Date())
    .withID("id")
    .withClaim("username", "BastiaanJansen") // add custom claims
    .sign();
} catch (JWTCreationException e) {
  e.printStackTrace(); // Handle error
}

Signed JWT's automatically have the typ header claim set to "JWT"

You can also define the header and payload before hand and add them without the JWT Builder:

Header header = new Header();
header.setAlgorithm("HS512");

Payload payload = new Payload();
payload.setIssuer("issuer");
payload.setAudience("aud1", "aud2");
payload.setIssuedAt(new Date());
payload.setID("id");
payload.addClaim("username", "BastiaanJansen"); // add custom claims

try {
  String jwt = new JWT(algorithm, header, payload).sign();
} catch (JWTCreationException e) {
  e.printStackTrace(); // Handle error
}

These two ways of creating JWT's will generate the same tokens.

You don't need to immediately sign your JWT. You can also just build a JWT instance. With a JWT instance, you can get the header, payload, algorithm and validate the token which will be covered in a later chapter. You can, for example, pass around this JWT instance to other objects without passing around String objects.

// Build JWT instance
JWT jwt = new JWT.Builder(algorithm)
  .withIssuer("issuer")
  .build();
  
Header header = jwt.getHeader();
Payload payload = jwt.getPayload();
Algorithm algorithm = jwt.getAlgorithm();

try {
  // To finally sign and get JWT String
  String jwtString = jwt.sign();
} catch (JWTCreationException e) {
  e.printStackTrace(); // Handle error
}

Parsing JWT's

To parse raw JWT's, you can use the JWT.fromRawJWT() method which expects an Algorithm an a raw JWT string:

String rawJWT = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3N1ZXIiLCJzdWIiOiJzdWJqZWN0IiwianRpIjoiaWQiLCJhdWRpZW5jZSI6WyJhdWQxIiwiYXVkMiJdLCJ1c2VybmFtZSI6IkJhc3RpYWFuSmFuc2VuIn0.mu1sSfzaNKH1dJ-cC1bsrFEJiwZs7H0AhnFf5tR4D0062zsxpU90F3dMrSlbneTtrxVI3PGxJlCYN8kcfpJkpw";

Algorithm algorithm = Algorithm.HMAC512(secret);

try {
  JWT jwt = JWT.fromRawJWT(algorithm, jwt);
} catch (JWTCreationException | JWTDecodeException e) {
  e.printStackTrace(); // Handle error
}

When you have retrieved the JWT instance, you can get data from the header and payload:

Header header = jwt.getHeader();
Payload payload = jwt.getPayload();

// Get data from header and payload
String alg = header.getAlgorithm();
String typ = header.getType();
String cty = header.getContentType();

String iss = payload.getIssuer();
String sub = payload.getSubject();
String jti = payload.getID();
Date iat = payload.getIssuedAt();
Date exp = payload.getExpirationTime();
Date nbf = payload.getNotBefore();
String[] audience = payload.getAudience();

String customClaim = payload.getClaim("username", String.class);

boolean hasClaim = payload.containsClaim("key");

Validating JWT's

Basic validation

To validate a JWT, you can use a JWTValidator. To validate a token in it's most basic form, use the validate() method on a JWT instance:

JWT jwt = JWT.fromRawJWT(algorithm, "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3N1ZXIiLCJzdWIiOiJzdWJqZWN0IiwianRpIjoiaWQiLCJhdWRpZW5jZSI6WyJhdWQxIiwiYXVkMiJdLCJ1c2VybmFtZSI6IkJhc3RpYWFuSmFuc2VuIn0.mu1sSfzaNKH1dJ-cC1bsrFEJiwZs7H0AhnFf5tR4D0062zsxpU90F3dMrSlbneTtrxVI3PGxJlCYN8kcfpJkpw");

try {
  jwt.validate();
  
  // JWT is valid!
} catch (JWTValidationException e) {
  e.printStackTrace(); // JWT is not valid, handle error
}

The validate() method uses the DefaultJWTValidator class underneath. Which, by default, enforces:

  • the type (typ) in header is set to "JWT"
  • the signature is valid
  • when set, the expiration time is not exceeded,
  • when set, the not-before time is not after or equal current time,

Custom validation

The DefaultJWTValidator does also support enforcing header or payload claims. This way you can make sure that, for example, the issuer is equal to something you expect. To use this feature, use the Builder of DefaultJWTValidator:

JWTValidator validator = new DefaultJWTValidator.Builder()
  .withAlgorithm("HS512") // Enforce the alg in the header is set to HS512
  .withIssuer("issuer")
  .withID("id")
  .withOneOfAudience("aud1", "aud2") // Enforce audience has "aud1" or "aud2"
  .withClaim("username", "BastiaanJansen") // Enforce custom claim value
  .build();

try {
  // Give the verifier as argument
  jwt.validate(validator);
  
  // Or verify directly on the verifier
  verifier.validate(jwt);
  
  // JWT is valid!
} catch (JWTValidationException e) {
  e.printStackTrace(); // JWT is not valid, handle error
}

Or add custom validation logic:

JWTValidator validator = new DefaultJWTValidator.Builder()
  .withClaim("username", new ClaimValidator() {
      @Override
      public boolean validate(Object value) {
          return "bastiaanjansen".equalsIgnoreCase(String.valueOf(value));
      }
  })
  .build();
  
// Or use a lambda
JWTValidator validator = new DefaultJWTValidator.Builder()
  .withClaim("username", value -> "bastiaanjansen".equalsIgnoreCase(String.valueOf(value)))
  .build()

Create your own validator

If the DefaultJWTValidator doesn't meet your requirements, you can create your own validator:

public class CustomJWTValidator implements JWTValidator {

  @Override
  public void validate(JWT jwt) throws JWTValidationException {
    // Validate JWT
  }

}

You can use your custom validator the same way as the DefaultJWTValidator:

try {
  JWTValidator customValidator = new CustomJWTValidator();
  
  // Give the verifier as argument
  jwt.validate(customValidator);
  
  // Or verify directly on the verifier
  customValidator.validate(jwt);
  
  // JWT is valid!
} catch (JWTValidationException e) {
  e.printStackTrace(); // JWT is not valid, handle error
}

Sources

Sources used to gather information about JSON Web Tokens:

Stargazers repo roster for @BastiaanJansen/OTP-Java

You might also like...

The goal of the project is to create a web application using Java EE and database (PostgreSQL) without connecting a modern technology stack like spring boot and hibernate

The goal of the project is to create a web application using Java EE and database (PostgreSQL) without connecting a modern technology stack like spring boot and hibernate

About The Project SignIn page SignUp page Profile page The goal of the project is to create a web application using Java EE and database (PostgreSQL)

Mar 23, 2022

This is simple project to show how to create a basic API using Java 11 + Maven + Spring Boot + PostgrSQL + Flyway.

This is simple project to show how to create a basic API using Java 11 + Maven + Spring Boot + PostgrSQL + Flyway.

Dec 10, 2022

An API Library that provides the functionality to access, manage and store device topologies found in JSON files using Java and Maven Framework

An API Library that provides the functionality to access, manage and store device topologies found in JSON files using Java and Maven Framework

Topology API 📙 About An API library which provides the functionality to access, manage and store device topologies. 📝 Description Read a topology fr

Aug 4, 2022

OpenAPI JSON Schema Generator allows auto-generation of API client libraries with a focus on JSON schema given an OpenAPI Spec

OpenAPI JSON Schema Generator IMPORTANT: before the first release, one will need to build the project locally to use the enhancements, bug fixes in th

Dec 31, 2022

All development related with the ONLYONE token.

onlyone All development related with the Onlyone Finance. ONLYONE Token Total Supply: 1 Contract creation: https://bscscan.com/tx/0x1becbd78297f267dec

Jan 1, 2023

Shitty, yet simple way to get someone's token right at their discord client's startup.

discord-token-stealer Shitty, yet simple discord injector to add a little spice to their discord client Disclaimer: This is for educational purposes o

Sep 26, 2022

Integrates with XRPLedger to send token payment to trustline addresses

strategyengine token distribution rest service This service also runs here -- https://fsedistributionservice-56gpv2b23a-uc.a.run.app/ #How to run loca

Dec 14, 2022

With react-native-update-in-app library you can easily implement in-app updates in your React Native app using CDN or any other file server

React Native In-App update With react-native-update-in-app library you can easily implement in-app updates in your React Native app using CDN or any o

Dec 21, 2022

Cloud Native and Low Code Platform to create FullStack web Admin applications in minutes

Cloud Native and Low Code Platform to create FullStack web Admin applications in minutes

Cloud Native and Low Code Platform to create FullStack web Admin applications in minutes ✨ Features & Technologies REST API generator Low Code CRUD &

Dec 26, 2022
Releases(jwt-java-1.2.0)
Owner
Bastiaan Jansen
Software Engineering student at University of Applied Sciences Leiden in The Netherlands.
Bastiaan Jansen
trying to create a plugin using the spigot api! this plugin will be responsible for delivering the products according to the settings!

KettraShop "simples plugin de ativação de produtos da loja, dentro do Minecraft" ⚙️ Configurações caso você não tenha uma loja virtual para seu servid

SEBASTIAN JN ฅ^•ﻌ•^ฅ 4 Nov 2, 2022
Spring Boot Refresh Token using JWT example - Expire and Renew JWT Token

Spring Boot Refresh Token with JWT example Build JWT Refresh Token in the Java Spring Boot Application. You can know how to expire the JWT, then renew

null 152 Dec 28, 2022
A library to create, read and validate ZUGFeRD compliant invoices. Available for Java and .NET

Konik ZUGFeRD Library Is an easy to use open source implementation of the ZUGFeRD data model including various enhancements. Features Easy and underst

Konik 42 Dec 20, 2022
Assistant to create, update and validate Modget manifests

Modget Create This tool helps to create Modget Manifests, which is used by the mod Modget. Modget Create (or MGC for short) is NOT perfect, but will a

null 5 Aug 13, 2022
There are two challenges one is to create a backend api the other is to create a frontend application to consume the public data api devall.

Sobre | Desafio | Resolução | Tecnologias | Execução | Itexto desafio tecnico Sobre os Desafios existem dois desafios um é criar uma api backend o out

fabricio S Miranda 1 Oct 18, 2021
Zero-Dependency RFC 8252 OAuth 2.0 Authorization Flow

Tiny OAuth2 Client This is a minimal zero-dependency implementation of the RFC 8252 OAuth 2.0 for Native Apps, relying on Loopback Interface Redirecti

Coffee Libs ☕️ 4 Jun 17, 2022
Search API with spelling correction using ngram-index algorithm: implementation using Java Spring-boot and MySQL ngram full text search index

Search API to handle Spelling-Corrections Based on N-gram index algorithm: using MySQL Ngram Full-Text Parser Sample Screen-Recording Screen.Recording

Hardik Singh Behl 5 Dec 4, 2021
Rivr is a lightweight open-source dialogue engine enabling Java developers to easily create enterprise-grade VoiceXML applications.

Overview Rivr is a lightweight open-source dialogue engine enabling Java developers to easily create enterprise-grade VoiceXML applications. Read our

Nu Echo Inc. 57 Jun 27, 2022
An extension for Keycloak, that enables web-based sign in with Apple and token exchange

Apple Identity Provider for Keycloak ?? This repository represents an extension for Keycloak, which enables Sign in with Apple for web-based applicati

Klaus Betz 58 Dec 29, 2022
Android Library to create Lottie animation view dialog easily with a lot of customization

LottieDialog Android Library to create Lottie animation view dialog easily with a lot of customization Why you should use Lottie Dialog You have no li

Amr Hesham 39 Oct 7, 2022