JSON web token (JWT) implementation in Java

In my previous article , I talked about JWT introduction and how it works. There are multiple libraries by which you can implement JWT in Java.

1. Java JWT: JSON Web Token for Java and Android

Installation

Use your favorite Maven-compatible build tool to pull the dependency (and its transitive dependencies) from Maven Central:

Maven:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.6.0</version>
</dependency>



Gradle:


dependencies {
    compile 'io.jsonwebtoken:jjwt:0.6.0'
}

Note: JJWT depends on Jackson 2.x. If you’re already using an older version of Jackson in your app, read this

Usage

Most complexity is hidden behind a convenient and readable builder-based fluent interface, great for relying on IDE auto-completion to write code quickly. Here’s an example:

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.MacProvider;
import java.security.Key;

// We need a signing key, so we'll create one just for this example. Usually
// the key would be read from your application configuration instead.
Key key = MacProvider.generateKey();

String s = Jwts.builder().setSubject("Joe").signWith(SignatureAlgorithm.HS512, key).compact();
How easy was that!?

Now let's verify the JWT (you should always discard JWTs that don't match an expected signature):

assert Jwts.parser().setSigningKey(key).parseClaimsJws(s).getBody().getSubject().equals("Joe");
You have to love one-line code snippets!

But what if signature validation failed? You can catch SignatureException and react accordingly:

try {

    Jwts.parser().setSigningKey(key).parseClaimsJws(compactJwt);

    //OK, we can trust this JWT

} catch (SignatureException e) {

    //don't trust the JWT!
}

2. Using Nimbus Jose + JWT

The most popular and robust Java library for JSON Web Tokens (JWT)
Supports all standard signature (JWS) and encryption (JWE) algorithms
Open source Apache 2.0 licence

Features –

– Signed / encrypted tokens, such as bearer access tokens in OAuth 2.0 or OpenID Connect identity tokens;
– Self-contained API keys, with optional revocation;
– Protecting content and messages;
– Authenticating clients and web API requests.

Use in Java

// Create an HMAC-protected JWS object with some payload
JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256),
                                    new Payload("Hello world!"));

// We need a 256-bit key for HS256 which must be pre-shared
byte[] sharedKey = new byte[32];
new SecureRandom().nextBytes(sharedKey);

// Apply the HMAC to the JWS object
jwsObject.sign(new MACSigner(sharedKey));

// Output to URL-safe format
jwsObject.serialize(); 

Maven configuration

Maven
For Java 7+ :

<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>4.11.2</version>
</dependency>

3. JSON token library – It depend on Google Guava.The library is in fact used by Google Wallet.

Here is how to create a jwt, and to verify it and deserialize it:

Maven –

<dependency>
    <groupId>com.googlecode.jsontoken</groupId>
    <artifactId>jsontoken</artifactId>
    <version>1.0</version>
</dependency>
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>

and Java implementation –

import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.util.Calendar;
import java.util.List;

import net.oauth.jsontoken.JsonToken;
import net.oauth.jsontoken.JsonTokenParser;
import net.oauth.jsontoken.crypto.HmacSHA256Signer;
import net.oauth.jsontoken.crypto.HmacSHA256Verifier;
import net.oauth.jsontoken.crypto.SignatureAlgorithm;
import net.oauth.jsontoken.crypto.Verifier;
import net.oauth.jsontoken.discovery.VerifierProvider;
import net.oauth.jsontoken.discovery.VerifierProviders;

import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.joda.time.DateTime;

import com.google.common.collect.Lists;
import com.google.gson.JsonObject;


/**
 * Provides static methods for creating and verifying access tokens and such. 
 * @author davidm
 *
 */
public class AuthHelper {

    private static final String AUDIENCE = "NotReallyImportant";

    private static final String ISSUER = "YourCompanyOrAppNameHere";

    private static final String SIGNING_KEY = "[email protected]^($%*$%";

    /**
     * Creates a json web token which is a digitally signed token that contains a payload (e.g. userId to identify 
     * the user). The signing key is secret. That ensures that the token is authentic and has not been modified.
     * Using a jwt eliminates the need to store authentication session information in a database.
     * @param userId
     * @param durationDays
     * @return
     */
    public static String createJsonWebToken(String userId, Long durationDays)    {
        //Current time and signing algorithm
        Calendar cal = Calendar.getInstance();
        HmacSHA256Signer signer;
        try {
            signer = new HmacSHA256Signer(ISSUER, null, SIGNING_KEY.getBytes());
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        }

        //Configure JSON token
        JsonToken token = new net.oauth.jsontoken.JsonToken(signer);
        token.setAudience(AUDIENCE);
        token.setIssuedAt(new org.joda.time.Instant(cal.getTimeInMillis()));
        token.setExpiration(new org.joda.time.Instant(cal.getTimeInMillis() + 1000L * 60L * 60L * 24L * durationDays));

        //Configure request object, which provides information of the item
        JsonObject request = new JsonObject();
        request.addProperty("userId", userId);

        JsonObject payload = token.getPayloadAsJsonObject();
        payload.add("info", request);

        try {
            return token.serializeAndSign();
        } catch (SignatureException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Verifies a json web token's validity and extracts the user id and other information from it. 
     * @param token
     * @return
     * @throws SignatureException
     * @throws InvalidKeyException
     */
    public static TokenInfo verifyToken(String token)  
    {
        try {
            final Verifier hmacVerifier = new HmacSHA256Verifier(SIGNING_KEY.getBytes());

            VerifierProvider hmacLocator = new VerifierProvider() {

                @Override
                public List<Verifier> findVerifier(String id, String key){
                    return Lists.newArrayList(hmacVerifier);
                }
            };
            VerifierProviders locators = new VerifierProviders();
            locators.setVerifierProvider(SignatureAlgorithm.HS256, hmacLocator);
            net.oauth.jsontoken.Checker checker = new net.oauth.jsontoken.Checker(){

                @Override
                public void check(JsonObject payload) throws SignatureException {
                    // don't throw - allow anything
                }

            };
            //Ignore Audience does not mean that the Signature is ignored
            JsonTokenParser parser = new JsonTokenParser(locators,
                    checker);
            JsonToken jt;
            try {
                jt = parser.verifyAndDeserialize(token);
            } catch (SignatureException e) {
                throw new RuntimeException(e);
            }
            JsonObject payload = jt.getPayloadAsJsonObject();
            TokenInfo t = new TokenInfo();
            String issuer = payload.getAsJsonPrimitive("iss").getAsString();
            String userIdString =  payload.getAsJsonObject("info").getAsJsonPrimitive("userId").getAsString();
            if (issuer.equals(ISSUER) && !StringUtils.isBlank(userIdString))
            {
                t.setUserId(new ObjectId(userIdString));
                t.setIssued(new DateTime(payload.getAsJsonPrimitive("iat").getAsLong()));
                t.setExpires(new DateTime(payload.getAsJsonPrimitive("exp").getAsLong()));
                return t;
            }
            else
            {
                return null;
            }
        } catch (InvalidKeyException e1) {
            throw new RuntimeException(e1);
        }
    }


}

public class TokenInfo {
    private ObjectId userId;
    private DateTime issued;
    private DateTime expires;
    public ObjectId getUserId() {
        return userId;
    }
    public void setUserId(ObjectId userId) {
        this.userId = userId;
    }
    public DateTime getIssued() {
        return issued;
    }
    public void setIssued(DateTime issued) {
        this.issued = issued;
    }
    public DateTime getExpires() {
        return expires;
    }
    public void setExpires(DateTime expires) {
        this.expires = expires;
    }
}

Happy API secure using JWT with Vinay

Reference
– https://github.com/jwtk/jjwt
– http://connect2id.com/products/nimbus-jose-jwt
– https://code.google.com/archive/p/jsontoken/

Play framework tutorial for Starters

What is play-Play! is very different compared to your average Java web application. Play! doesn’t follow many of the J2EE conventions or standards. Instead the developers of Play! decided to make the most efficient web framework possible. It’s not a full Java Enterprise stack and Play! expressly states that it is built for web developers. This humble developer started out very skeptical that it would be useful and some of the design choices made little sense to my “Java Enterprise” mindset.

So what is Play!? – let’s take a look at what it offers at a glance.

Completely stateless – matching the HTTP standard
Non-blocking IO – reactive, fast
Hot-reload of Java classes – more on this later
Compiled views – which can be tested
Symmetrical simple routes – created with purpose and design
Both Scala and Java – Built with Scala but Java is a first class alternative
Large third-party module repository – growing daily
Commercial Support – by TypeSafe and Zenexity
Download and install the Play binary package from http://www.playframework.com/download .

To check if play is working or not, open the command prompt and type ‘play help’.

C:\>play help

you should get below screen.

Creting a new Application
step 1 : C:\>play new myFirstApp
step 2 : Confirm the application name.Press enter.
Step 3: type 2 for creating a simple java application.

Creating a working eclipse project from a play application
step 1 : cd to the new application directory
C:\>cd myFirstApp
step 2 : play
C:\myFirstApp>play
step 3 : eclipsify
[myFirstApp] $ eclipsify

Import the project in eclipse.

The app/ directory contains executables. Below are 3 packages
app/controllers
app/models
app/views

The public/ directory contains static assets. Has 3 subdirectories
images
css
javascript

The conf/ directory contains applications configuration files.There are 2 configuration files.
application.conf – standard configuration parameters.
routes – routes defination file

The lib/ directory – libraries/jar files

The project/ directory – sbt build definitions
Plugins.sbt
Build.scala – application build script

The target/ directory – contains things generated by build system

Typical .gitignore file – Generated folders should be ignored by your version control system
logs
project/project
project/target
target
tmp

To run the newly created application

[myFirstApp] $ run

On the browser address type
localhost:9000

The below screen gets displayed.

Modify the source code as below.

Application.java

package controllers;

import model.Task;
import play.*;
import play.data.Form;
import play.mvc.*;

import views.html.*;
import views.*;

public class Application extends Controller {
	
  public static Result index() {
	
	  Form<Task> form = form(Task.class);
    return ok(index.render(form));
  }
  
  public static Result sayHello() {
	  Form<Task> taskForm = form(Task.class).bindFromRequest();
	  if(taskForm.hasErrors())
		  return badRequest(index.render(taskForm));
	  else
	  {
	  Task data = taskForm.get();
	  
	  return ok(sayHello.render(data.name, data.age));
	  }
	  
		  
  }

}

Task.java

package model;

import java.util.*;
import play.data.validation.Constraints.*;
public class Task {
  
	@Required
  public String name;
  
	@Required
  public String age;
    
}
Index.scala
@(form1: Form[model.Task])
@import helper._

@main(title = "The 'helloworld' application") {
    
    <h1>Configure your 'Hello world':</h1>
  @form(action = routes.Application.sayHello, args = 'id -> "helloform") {
        
        @inputText(
            field = form1("name"),
            args = '_label -> "What's your name?"
        )
        
        @inputText(
            field = form1("age"),
            args = '_label -> "What's your age?", 'size -> 3
        )
        
         <p class="buttons">
            <input type="submit">
        <p>
       } 
}


[/sourcecode ]

You can write the code for creating form in HTML also if not in Scala.



 <form action= @routes.Application.sayHello method=GET >
  <table>
  <tr>
  <td>Name   :</td>
  <td><input type="text" name="name"   required="required" > </td></tr>
 <tr><td> Age :</td><td><input type="text" name="age" > </td></tr>

  <tr><td><input type="submit" value="Submit" /></td></tr>
      
  </table>
main.scala

@(title: String)(content: Html)
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <title>@title</title>		
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
     
    </head>
    <body>
        @content 
    </body>
</html>

sayHello.scala

@(name: String, age: String)
@main("Details are : "){
<h1>Hello @name!</h1>
<h1>Your age is @age</h1> 
<a href="@{routes.Application.index()}">Back to form</a>
}
</body>
</html>

routes.conf
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# Home page
GET / controllers.Application.index()

GET /sayHello controllers.Application.sayHello()
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path=”/public”, file)

Refresh the browser.
You will see the below screen.

Test your application.

Happy coding with Techartifact