06. February 2017
timer-icon 4 min

JSON Web Token with Apache Shiro

Abstract

In this post, I will try to introduce you to the concept of JSON Web Tokens and show a way to use them in combination with Apache Shiro. The only premise is some basic understanding of Apache Shiro.

Let’s start right away with the question…

What is a JSON Web Token (JWT)?

JWT is an open standard (RFC 7519). It’s goal is to define a compact and self-contained way to transfer data. Let’s elaborate a bit more on the embolded terms.

compact: JWT’s are small and can be sent via URL / POST Request / HTTP Header. Also, smaller size means faster transmission.

self-contained: You can place all the necessary data in the payload. Thus reducing the amount of queries to a database.

Use Cases

A popular use of JWT’s is Single Sign On (SSO). Once a subject authenticates to a domain, it receives a JWT. This JWT is then presented everytime the subject requests protected resources.

Another popular use is data transmission. JWT’s are always hashed and signed. Because of this, you can always be sure of data integrity and the senders authenticity.

Structure

So, what does a JWT look like? There are three parts: header, payload and signature.

Header

Usually, the header contains two entries. The first one is the name of the hashing algorithm in use. The second is the type of the token.

Payload

The playload holds several “claims” about the entity that owns the token. There are three types of claims: reserved (predefined and optional),  public (should be registered in IANA, or have a public name) and private (only used by your server and clients).

Signature

At last, there is the signature. It’s a combination of the encoded header and payload, signed using a secret. The secret may be any kind of information, for example the servers public key.

Example Token

Decoded:


 

Encoded. Dots separate the header, payload and secret.

Combine JWT and Apache Shiro

Now let’s see how we can use JWT in co-operation with Apache Shiro. The approach is simple. First, we get the necessary JAR’s. Second, we create a servlet to generate tokens. Finally, we create two filters. And then we are done!

Get a library

There are several JWT libraries available (see here). I’m using “Java JWT: JSON Web Token for Java and Android” (repo). It’s well designed and easy to use, just like Apache Shiro. Which is not surprising, since they have the same developer (Lez Hazlewood).

Maven Dependency:


If you are not using any kind of build tool, download these: jjwt, jackson-core, jackson-databind. Note: jackson-* must be at least version 2.x.

Write the Components

Servlet: JWTProvider

The JWTProvider does exactly what the name suggests. Upon receiving a request, it generates a token and sends it back in the response body. In this example, we’ll only save the username of the current subject. Of course, you can (and should) use a variety of information. This is one of JWT’s advantages. You can put almost any kind of data in the payload.

Authentication Filter: JWTGuard

Using JWT, we want to secure our REST API. If an incoming request contains no token, the recommended approach is to simply deny the request. Let’s create a filter for that.

Access Control Filter: JWTVerifyingFilter

Now, if the request actually contains a token, we should see if it’s valid. Since we only save the current subject’s username, we should check if the incoming token contains one. If yes, additionally check if it equals the current subject’s username. And if any of the checks fails, we simply deny the request.

Shiro INI

So far, we declared the different classes. Now let’s configure Shiro to actually use them.

That’s it!

With only little effort we made it possible for clients to get a token and let a server verify it. I should mention that the username-equals approach is not recommended.

Comment article

Comments

  1. Miguel

    It would be great if the complete example could be available in some GitHub repository.
    As other comments said, there seems to be some missing parts to fully understand how JWT works with Shiro.
    Where is the “noSessionCreation” mentioned in shiro.ini defined , for example?

    A more complete example can be found here:
    https://github.com/panchitoboy/shiro-jwt

    However your approach seems to be “cleaner” to me… therefore a full example would be greatly appreciated !

  2. Joe

    Example seems to be missing an important part 🙁

  3. jack

    SecurityUtils.getSubject()

    When did the current user join?