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.

Leave a Comment

1 comment

  1. j

    SecurityUtils.getSubject()

    When did the current user join?

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close