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 Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
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
  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!

Sanjay Patel user avatar by
Sanjay Patel
CORE ·
Jul. 31, 18 · Tutorial
Like (5)
Save
Tweet
Share
51.06K 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.

Popular on DZone

  • Microservices Discovery With Eureka
  • API Design Patterns Review
  • Deploying Java Serverless Functions as AWS Lambda
  • How To Check Docker Images for Vulnerabilities

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: