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.
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.
So, what does a JWT look like? There are three parts: header, payload and signature.
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.
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).
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.
Encoded. Dots separate the header, payload and secret.
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).
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.
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.