JSON Web Tokens (JWT) are an open, industry standard method for representing claims
securely between two parties.
Introduction
In a previous post we developed a REST
Web Service with Spring.
In the post I talked about how you can implement a REST Web Service with Spring. We also talked about the various
HTTP methods and how to map them to Spring’s RequestMapping composite annotations.
In the post however, we did not talk about how to secure a Web Service. Security is an important aspect of
building a Web Service and more often than not, it is overlooked.
In this post we are going to secure the web service using JWT with Spring Security.
Spring Security is a framework that focuses on providing both authentication and authorization to Java
applications. To get started with this post, get the source for the previous post as zip|tar.gz and extract the contents of the archive.
Project Structure
At the end of this guide our folder structure will look similar to the following:
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely
transmitting information between parties as a JSON object. This information can be verified and trusted because
it is digitally signed. JWTs can be signed using a secret (with the HMAC+ algorithm) or a public/private key
pair using RSA.
JSON Web Tokens consist of three parts separated by dots (.), which are:
Header
Payload
Signature
Therefore, a JWT typically looks like the following. xxxxx.yyyyy.zzzzz
You can find a breakdown of the different parts on the Official Website.
Authentication Schemes
Security in a Web Application usually boils down Authentication and Authorization. There are several
shemes
involved when doing Authentication and Authorization. Some of the common ones are listed below:
Basic (RFC 7617, base64-encoded credentials.),
Bearer (RFC 6750, bearer tokens to access OAuth 2.0-protected resources),
Digest (RFC 7616, only md5 hashing is supported in Firefox),
Since we are leveraging the power of Spring-Boot, the above dependency to Spring Security registers the Spring
Security Filter Chain and sets up the Basic Authentication Scheme.
Open a terminal and run the project:
Open another terminal and run:
As you can see, you got an Unauthorized when you tried to access a protected resource. Let’s create a password
and username and try again:
The -u switch is to inform curl we intend to authenticate with a username:password combination. You can also request with the Base64 encoding:
JWT and Bearer Authentication
Now that we have seen the Basic scheme in action, let us now switch to the Bearer scheme using JWT.
Create the Spring Security WebSecurityConfigurerAdapter class:
This is to ensure that the Authentication filter is called before the UsernamePasswordAuthenticationFilter.
Once this is registered first, this will be called before the other authentication filters in the Spring
Security Filter Chain. This filter will check for a valid login before proceeding. All login attempts will
be a POST request to /api/authenticate/.
The AuthenticationEntryPoint will ensure users are presented with an Unauthorized 401 response. This will
override the Spring Security default of redirecting to a login page. Login pages do not make sense for REST
services.
AccessDeniedHandler for when a user tries to access a resource he is not permitted to access.
We will set session management to STATELESS for REST is stateless.
We will disable CSRF protection. It is not required in REST.
Make sure all routes require authentication.
Apply a security configurer to authenticate all requests.
Create a class that takes care of the concern of enconding and decoding the JWTs: