Published on

Adding Security to a Spring Boot Application with JWT and Hazelcast

Authors

In this article, we will secure our Spring Boot application and implement a caching system.

👉 If you haven't followed the first article, here's the link: [link]


Spring Security and JWT Token

The first step is to add the spring-boot-starter-security dependency to your pom.xml file.

This will add a layer of security to your application.

➡️ Restart the application and try displaying the employee list with the URL: http://localhost:8181/api/employee/all


1. Application User

We need to separate application users from employees.

To do this, let's create a User class.

This class will contain:

  • a login,
  • a password,
  • a link to the associated employee.

2. Create the User Repository

User Authentication and Authorization with Spring Boot

To support both authentication and authorization in our application, we will:

  • Implement an authentication filter to deliver JWTs to users submitting their credentials,
  • Implement an authorization filter to validate requests containing a JWT,
  • Create a custom implementation of UserDetailsService to help Spring Security load user-specific data into the framework,
  • Extend the WebSecurityConfigurerAdapter class to customize the security configuration according to our needs.

Main Steps

  1. Authentication Filter Used to deliver a JWT to the user who authenticates with their credentials.

  2. Authorization Filter Validates requests that contain a JWT in their header.

  3. UserDetailsService Implementation Allows Spring Security to load user-specific information (login, password, roles, etc.).

  4. WebSecurityConfigurerAdapter Extension Allows you to configure security rules, such as protected endpoints, allowed HTTP methods, etc.


Securing a REST API with Spring Security

Adding security to a Spring Boot application is very simple. Simply add the following dependency to your pom.xml:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Launch the application

Restart your application. In the console logs, you will see that a password is automatically generated.

Default username: user

Default password: generated in the console when the application starts.

Example

If you try to access the API via: http://localhost:7070/api/employee

A login form will be automatically displayed.

The default username and password can be found in the console logs when the application starts.

  • Default username: user
  • Default password: Visible in the STS console as shown below.
security-hazelcast-cache-1

To use your own username and password instead of the automatically generated ones, you must specify the following properties in the application.properties file:

spring.security.user.name=test
spring.security.user.password=test123

Updating your Angular endpoint to access a secure REST endpoint

If you try to access http://localhost:4200/heroes via the browser or Postman, you will get a 401 Unauthorized code, which means unauthorized access to the URL.

So we need to send Basic authorization headers in our HTTP request. Let's update our Angular HeroService, in the getHeroes() method:

getHeroes() {
const url = 'http://localhost:7070/api/heroes';
const headers = new HttpHeaders({
Authorization: 'Basic' + btoa('test:test123')
});
return this.http.get(url, { headers });
}

Try again by checking http://localhost:7070/api/heroes in your browser. Does it work?

No. The reason is that we need to add CORS support to our REST backend.

Cross-Origin Resource Sharing (CORS)

We need to add CORS support so that our Angular service