No one can deny from the fact that Security is a vital feature of a production ready application. Although we can secure one web application using In-memory authentication, JDBC Authentication or via UserDetailsService. But when one application uses the services of other application internally, then implementation of security with webservices concept becomes important. In this situation we secure our application using a token which has a particular period of validity. Further, we are going to learn ‘How to implement JWT Authentication in Spring Boot Project?’ to understand the concept behind JWT(JSON Web Token) Authentication as a whole. As JWT stands for ‘JSON Web Token’, it is clear that the token holds the data in the form of JSON only.
Moreover, unlike aforementioned techniques of authentication, JWT comes under stateless authentication. In brief, it doesn’t have data. Generally, this type of authentication is used in Webservices, horizontal scaling of servers or even in OAuth technique up to some extent. To illustrate the webservice, let’s visualize the process of booking an order from Amazon. Here, the user interacts with Amazon app, whereas Amazon app internally interacts with payment gateway app via a webservice call. Now let’s start discussing about our topic ‘How to implement JWT Authentication in Spring Boot Project?’ and related points.
Table of Contents (Click on links below to navigate)
- 1 What Can You Expect from This Article as a Whole?
- 2 What is Stateless and Stateful Authentication?
- 3 What is a Token, What is JWT authentication all about and What is the benefit of using it?
- 4 How does JWT authentication work?
- 5 How to generate an encoded Token as JWT & decode it(read the Claims) again?
- 6 How to implement JWT Authentication in Spring Boot Project?
- 6.1 What Software/Technologies would you need?
- 6.2 Step#1 : Create a Spring Boot Starter Project in STS(Spring Tool Suite)
- 6.3 Step#2A: Create Entity class as User.java (For versions lower than Spring Boot 3.0)
- 6.4 Step#2B: Create Entity class as User.java (For versions Spring Boot 3.0 and later)
- 6.5 Step#3 : Update application.properties
- 6.6 Step#4 : Create interface UserRepository.java
- 6.7 Step#5 : Create AppConfig.java
- 6.8 Step#6 : Create User service interface and it’s implementation class
- 6.9 Step#7 : Create JWTUtil.java
- 6.10 Step#7 : Create UserRequest & UserResponse Models
- 6.11 Step#8 : Create UserRestController.java
- 6.12 Step#9 : Create SecurityFilter.java
- 6.13 Step#10 : Create UnAuthorizedUserAuthenticationEntryPoint.java
- 6.14 Step#11A: Create SecurityConfig.java (For versions lower than Spring Security 5.7)
- 6.15 Step#11B: Create SecurityConfig.java (For versions higher than Spring Security 5.7 and lower than Spring Security 6.0)
- 6.16 Step#11C: Create SecurityConfig.java (For versions Spring Security 6.0 and higher: Spring Boot 3.0)
- 7 How to test the JWT security enabled Application ?
- 8 Summary
What Can You Expect from This Article as a Whole?
Once you complete going through this article, you will be able to answer :
1) What is stateless & stateful authentication in a security context?
2) What is the difference between stateless & stateful authentication?
3) Then What is a Token and what is a JWT(JSON Web Token)?
4) What are the benefits of using JWT authentication?
5) How does JWT work internally?
6) In which context we use JWT authentication?
7) Further, What is the difference between JWT authentication & a stateful authentication?
8) Additionally, How to generate an encoded token as JWT and How to decode it back?
9) How to implement JWT Authentication in Spring Boot Project step by step?
10) How to write Security Configuration class without using WebSecurityConfigurerAdapter in Spring Boot 3.0?
11) Finally, How to test the JWT security enabled Application?
What is Stateless and Stateful Authentication?
Generally there are two types of authentication techniques. Both happen in a client server concept in such a way that Server provides a service to a Client only after authentication. Here clients can be a browser or another server again.
In this type of Authentication, there is a session management involved between client & server. When a client requests for a service from a server, it first logins to the server. Then server creates a session and stores this information in the form of key – value pairs. This session is a kind of memory at server side. We also call it HttpSession as Http protocol manages it. Further, in response to client requests, the server provides a session id with the response in the form of Cookie to the client. That cookie gets stored in the client browser. When same client makes request for the second time, cookie also comes with the request header. Consequently, the server checks the request header and if it finds the same SID (Session id) in the cookie it assumes that the request came from the same client. In this way session management happens.
When a client logs out from the server, the session gets destroyed accordingly. As a result, the server removes the session information (key-value) from the memory accordingly. Equally important, For every new client, the server creates a new session(memory).
When a client sends a request to the server for a service, it first logins to the server. Consequently, the server generates a token (data in encoded format) and sends to the client with the response. While making second request, Client sends the same token along with the request to the server. Now, the server reads token from the request and validates the token. In fact, from the first request server checks the valid login(credentials) of the client. If it is a valid login, then only, server creates a token.
Furthermore, on the second request it validates the token. If the token is valid it sends the requested response, otherwise asks the client to login again. However, every token will have a valid time period, such as 30 minutes, 1 hour etc. Based on business requirements, token validity period can be configured.
In case of Token, there is no concept of logout. Instead, the client can make a request & get the response until the token expires.
What is a Token, What is JWT authentication all about and What is the benefit of using it?
In a nutshell, Token is a data in an encoded format. It can be generated using a secret key(a kind of password). JWT is an abbreviation to ‘JSON Web Token’, which is a standard mechanism to generate tokens. It defines a compact and self-contained way of transmitting information securely between parties(multiple servers) as a JSON object. JWT has three parts : Header, Payload & Signature. Each part is separated by comma. Its an open source API. JWT concept exists not only in Java, but also in other languages.
Header : contains JWT Specific Information
Payload : contains Claims (Client ID, Client Name, Issuer Name, Audience Name, Date of issue, Expiry date etc…)
Signature: Base64 encoded form of Header & Payload. Additionally, signed with a secret key
Below is the example in format: aaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.cccccccccccccccccccccccccccccccccc
Example of an encoded JWT : eyJhbGciOiJIUzUxMiJ9 .eyJqdGkiOiIzNDMyIiwic3ViIjoiZHMyNTI1IiwiaXNzIjoiQUJDX0x0ZCIsImF1ZCI6IlhZWl9MdGQiLCJpYXQiOjE2MDc0NDI1NzQsImV4cCI6MTYwNzQ0NjE3NH0 .3fIcXIvL9Uz0WtZgaXC95Wj8Hn7ONWKkaaspRwCT6v5Q8QSxZx7hiDQY3klYUMkfe5t2ioasYzEulM_OGc_GEw
How does JWT authentication work?
When a client requests for a service from a server, it first logins to the server. Consequently, the server generates a token(data in encoded format) and send to the client with the response. While making a second request Client sends token along with the request to the server. Now server reads token from the request and validate the token. While validating the token which client sends with the request, server requires that secret key again to decode it. Further to validate the token server always requires the secret key. Even after the successful login, server generates token using secret key only for the first time. In summary, server requires the secret key while generating the token & even at the time of validating it too.
Unlike stateful authentication, here server maintains the token at the server side only. As aforementioned, in stateful authentication browser(client) stores session ID in the form of cookies.
Suppose we are booking an order through amazon app. There are at least three participants on the whole to complete the booking. User, Amazon app and Payment gateway app. Here payment gateway app authenticates amazon app not the client. This happens because of token authentication technique. Further amazon app will not use payment gateway’s service once payment is complete. Hence token authentication is preferable in this situation. For further internal details on JWT, kindly visit JWT website.
How to generate an encoded Token as JWT & decode it(read the Claims) again?
Here Claims is a process of reading or parsing JWT details by providing two inputs : Token & Secret Key
In order to implement the POC(Proof Of Concept) on ‘How to generate & read Claims back’, we should think of finding a JAVA API for JWT. Undoubtedly, we already have jjwt.jar to make it possible. Now let’s create a POC to implement our functionality step by step.
Step#1: Create a simple Maven project in Eclipse or STS.
Open your eclipse and select File>New>Other, then search for ‘Maven Project’. Then click on ‘Next’, Select ‘create a simple project’ checkbox. Now click on ‘Next’. Enter ‘Group Id’ and ‘Artifact id’ as your project details. Finally click on ‘Finish’.
Step#2: Include jjwt dependency in your pom.xml.
Include ‘jjwt‘ dependency as given below. Additionally if you are using JDK8 or later version you need to include ‘jaxb‘ dependency as well.
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency>
Step#3: Create classes & Implement functionality
Consequently we will create two classes : JWTUtil.java & JWT_Test.java
In JWTUtil.java we will have implementation logic which can work as a utility class. Further we will test our POC from JWT_Test.java accordingly.
Below is the output of our POC.
How to implement JWT Authentication in Spring Boot Project?
To illustrate the implementation of JWT Authentication, we will definitely require a webservice call. For that we will register some users into DB using REST webservice. To make this happen, we will use POSTMAN software as we will not have a registration form in this case. Then we will apply JWT security features into our code. Finally we will verify the security features we incorporated through testing. Let’s start implementing it accordingly.
What Software/Technologies would you need?
♦STS (Spring Tool Suite) : Version-> 4.7.1.RELEASE
⇒Dependent Starters : Spring Security, Spring Web, Lombok, Spring Data JPA, MySQL Driver, Spring Boot DevTools
♦MySQL Database : Version ->8.0.19 MySQL Community Server
♦JDK8 or later versions (Extremely tested on JDK8, JDK11 and JDK14)
Step#1 : Create a Spring Boot Starter Project in STS(Spring Tool Suite)
While creating Starter Project select ‘Spring Security’, ‘Spring Web’, ‘Spring Data JPA’, ‘MySQL Driver’, ‘Lombok’ and ‘Spring Boot DevTools’ as starter project dependencies. Additionally add ‘jaxb’ dependency in pom.xml as aforementioned. Even If you don’t know how to create Spring Boot Starter Project, Kindly visit Internal Link. Also, if you want to know more about Lombok, then visit Internal Link on Lombok.
Step#2A: Create Entity class as User.java (For versions lower than Spring Boot 3.0)
Step#2B: Create Entity class as User.java (For versions Spring Boot 3.0 and later)
In import statements, use ‘jakarta’ in place of ‘javax’. For example: Use ‘jakarta.persistence.Entity;’ in place of ‘javax.persistence.Entity;’.
Step#3 : Update application.properties
#application.properties ------------------------------------------------------------------ #-------------------- Server Properties --------------- server.port=8080 #--------------------- DB Connection Properties ------------------ #AutoLoading of driver class since JDBC 4 #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/testJWTSecurity spring.datasource.username=root spring.datasource.password=devs #--------------------JPA Properties----------------- spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update #spring.jpa.database-platform=org.hibernet.dialect.MySQL8Dialect #------------------Security Specific Properties------- app.secret.key=[email protected]!gt*K
Step#4 : Create interface UserRepository.java
Step#5 : Create AppConfig.java
Step#6 : Create User service interface and it’s implementation class
Step#7 : Create JWTUtil.java
Step#7 : Create UserRequest & UserResponse Models
Step#8 : Create UserRestController.java
Step#9 : Create SecurityFilter.java
Step#10 : Create UnAuthorizedUserAuthenticationEntryPoint.java
Step#11A: Create SecurityConfig.java (For versions lower than Spring Security 5.7)
Step#11B: Create SecurityConfig.java (For versions higher than Spring Security 5.7 and lower than Spring Security 6.0)
As WebSecurityConfigurerAdapter has been deprecated from Spring Security 5.7.0-M2 as per an announcement posted in the Spring Official website, on 21st Feb, 2022, we will write SecurityConfig class without using WebSecurityConfigurerAdapter as shown below:
Step#11C: Create SecurityConfig.java (For versions Spring Security 6.0 and higher: Spring Boot 3.0)
From Spring Security 6.0 (released in November, 2022), the WebSecurityConfigurerAdapter is completely removed from the Spring Security API. It has also impacted the newly released Spring Boot 3.0 in November, 2022. Hence, if you are using Spring Framework 6.0+ or Spring Boot 3.0+, in either case, your implementation of SecurityConfig.java should look like below. Additionally, you can also check the Spring Security related changes in Spring Framework 6.0.
Finally, your project structure should look like below screenshot.
How to test the JWT security enabled Application ?
Although the word ‘testing’ looks very easy to a developer but it is equally important as it provides the result of our implementation on the whole. Therefore, follow the steps given below:
1) Register User through a REST call using Postman
Enter URL http://localhost:8080/user/saveUser in Postman, select POST method, then Select Body>Raw>JSON respectively. Now paste below JSON data and then click on ‘Send’ button.
“email”: “[email protected]”,
You should get the below response :
output on Postman : User with id ‘1’ saved succssfully!
2) Login as a User to generate token
Enter URL http://localhost:8080/user/loginUser in Postman, select POST method, then Select Body>Raw>JSON respectively. Now paste below JSON data and then click on ‘Send’ button.
You should get the below response :
♠ if entered wrong username/password then output will be as below :
3) Access data/resource within token validity period
Enter URL http://localhost:8080/user/getData in Postman URL bar, select POST method, then Select Headers. Under Headers select key as ‘Authorization’. Now paste token as a value of Authorization as in below screenshot. Then click on ‘Send’ button.
As a successful response, you should get the below output :
You are accessing data after a valid Login. You are :ds2525
After going through all the theoretical & examples part of ‘How to implement JWT Authentication in Spring Boot Project?’, finally, we are able to implement JWT authentication security in a Spring Boot project. Of course, In this article we have thoroughly learned about the JWT authentication features. Similarly, we expect from you to further extend this example and implement it in your project accordingly. Additionally, If there is any change in future, we will update the article accordingly. Moreover, Feel free to provide your comments in the comments section.