DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Spring OAuth Server: Token Claim Customization
  • How to Use JWT Securely
  • Authentication With Remote LDAP Server in Spring Web MVC
  • How to Implement Two-Factor Authentication in a Spring Boot OAuth Server? Part 1: Configuration

Trending

  • Enforcing Architecture With ArchUnit in Java
  • Chat With Your Knowledge Base: A Hands-On Java and LangChain4j Guide
  • Intro to RAG: Foundations of Retrieval Augmented Generation, Part 1
  • Understanding IEEE 802.11(Wi-Fi) Encryption and Authentication: Write Your Own Custom Packet Sniffer
  1. DZone
  2. Coding
  3. Frameworks
  4. Using Nimbus JOSE + JWT in Spring Applications

Using Nimbus JOSE + JWT in Spring Applications

Want to learn more about the difference between using Nimbus JOSE and JWT tokens in Spring Applications? Click here to learn more!

By 
Sanjay Patel user avatar
Sanjay Patel
DZone Core CORE ·
Jul. 31, 18 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
63.7K Views

Join the DZone community and get the full member experience.

Join For Free

JWTs could be very useful in RESTful Web Services — not only for stateless authentication, but for all the purposes that require tokens — e.g. email verification and forgot-password. In this post, we'll discuss why and how to use the Nimbus JOSE + JWT library for creating and parsing JWT (JWE) tokens.

For code examples, we’ll refer to Spring Lemon. If you haven’t heard of Spring Lemon, you should give it a look. It’s a library encapsulating the sophisticated non-functional code and configuration that’s needed when developing real-world RESTful web services using the Spring framework and Spring Boot. 

JWT in a Nutshell

There’s already a lot of material available on JWT. So, instead of repeating those here, let's just summarize it as plainly as possible.

A JWT is a URL-safe token with some data embedded in it. The data would be signed/encrypted, so that malicious guys can’t alter it (or create another token with altered data). There are two kinds of JWTs — JWS and JWE.

JWS tokens will have their data signed but not encrypted. That means that the data can be parsed by anyone. For example, these can be used as authentication tokens where the front-end or any client needs to read the data.

JWE tokens instead will have the data encrypted so that no one (except the creator or someone having the secret key) can parse it.

Why Nimbus JWT

Java has two popular open source libraries for JWT creation and parsing: JJWT and Nimbus JOSE + JWT. Between these, JJWT is simple and easy to use. In fact, most articles on the Internet that dicuss how to use JWT with Spring use the JJWT library.

So, why bother using the Nimbus JWT?

For a couple of reasons. First, Nimbus JWT is comprehensive. It has many useful features that are not found in JJWT. For example, JJWT supports only JWS, but Nimbus supports both JWS and JWE. JWE is essential for creating tokens to be sent through mail (e.g. forgot-password tokens).

Secondy, Spring Security 5 itself uses Nimbus JWT — its dependencies like spring-security-oauth2-client and spring-security-oauth2-jose include nimbus-jose-jwt.

So, when using Spring Security 5, it’s natural to prefer Nimbus JWT instead of any other library.

How to Use Nimbus JWT

Nimbus JWT supports multiple algorithms for signing and encrypting tokens. In this post, we’ll discuss creating/parsing JWE tokens using a shared key, which would fit into most use cases when developing stateless REST Web Services — e.g. authorization, email validation, forgot-password etc.

So, let’s see how to use it. I’ll be pasting in some code snippets as examples, but for a detailed reference, you can refer to the JwtService class of Spring Lemon and the Spring Framework Recipes For Real World Application Development book.

Creating a Token

A JWT will have multiple parts. One of those is the payload, which contains the actual data to carry.

Creating the Payload

Each piece of the data in the payload is called a claim. For example, if you’d like to pass an email and a name, first build a ClaimsSet with two claims:

JWTClaimsSet claims = new JWTClaimsSet.Builder()
  .claim("email", "sanjay@example.com")
  .claim("name", "Sanjay Patel")
  .build();


Tip: You can use the standard JWT claims — such as subject, audience or expiration time — when possible. In fact, Nimbus classes, such as the builder above, have special methods supporting those. See the JwtService class of Spring Lemon for examples.

Then, create the payload as below:

Payload payload = new Payload(claims.toJSONObject());


Creating the Header

Another part of a JWT would be the header, which contains the encryption algorithm and method. Here is how you could create one:

JWEHeader header = new JWEHeader(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256);


The above says that we are going to use direct encryption with A128CBC_HS256 algorithm. So, the next step is to create an encrypter for it.

Creating the Encrypter

The encrypter can be created as below:

String secret = “841D8A6C80CBA4FCAD32D5367C18C53B”;
byte[] secretKey = secret.getBytes();
encrypter = new DirectEncrypter(secretKey);


The secret above is an aes-128-cbc key, generated using an online utility.

Note that the encrypter above could be a global one; you don’t need to create an encrypter per token.

Creating the Token

Now that you have the header, payload, and an encrypter, the next steps would be create a JWE object, encrypt it, and then serialize it to produce the desired token:

JWEObject jweObject = new JWEObject(header, payload);
jweObject.encrypt(encrypter);
String token = jweObject.serialize();


So, your token is ready. Give it to whoever wants it!

Parsing a Token

Let’s now see how to parse tokens. For that, we’d first need to configure a JWT Processor.

Configuring a JWT Processor

Configuring our JWT Processor can be done as below:

ConfigurableJWTProcessor<SimpleSecurityContext> jwtProcessor = new DefaultJWTProcessor<SimpleSecurityContext>();
JWKSource<SimpleSecurityContext> jweKeySource = new ImmutableSecret<SimpleSecurityContext>(secretKey);
JWEKeySelector<SimpleSecurityContext> jweKeySelector =
    new JWEDecryptionKeySelector<SimpleSecurityContext>(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256, jweKeySource);
jwtProcessor.setJWEKeySelector(jweKeySelector);


The secretKey above must be the same one that we used earlier.

Parsing the Claims

The above jwtProcessor can then be used to parse the claims out of our tokens, which is shown below:

JWTClaimsSet claims = jwtProcessor.process(token, null);
String email = (String) claims.getClaim(“email”);
String name = (String) claims.getClaim(“name”);


Conclusion

So, this is a way we can use Nimbus JWTs in our applications. It does look a little harder than JJWT, but this is non-functional stuff that you only need to code once to receive its benefits all the time. (You, of course, would need to maintain it as new versions of Nimbus JWT comes out, but you can use a high level library like Spring Lemon to avoid coding such non-functional stuff.)

Spring Framework JWT (JSON Web Token) Nimbus (cloud computing)

Published at DZone with permission of Sanjay Patel. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Spring OAuth Server: Token Claim Customization
  • How to Use JWT Securely
  • Authentication With Remote LDAP Server in Spring Web MVC
  • How to Implement Two-Factor Authentication in a Spring Boot OAuth Server? Part 1: Configuration

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: