In our previous blog, we covered the basics of Spring Security and its core concepts. In this post, we’ll walk through adding and configuring Spring Security in a Spring Boot application. We’ll start with a simple web application and then integrate Spring Security to secure our endpoints.
1. Create a Simple Spring Boot Web Application
1.1. Generate a Spring Boot Project
- Go to Spring Initializr and create a new project.
- Language: Java
- Project: Maven or Gradle Project
- Spring Boot: Choose a stable version (preferably >=3.0.0)
- Dependencies: Spring Web
- Download and open it in your preferred IDE.
1.2. Create a Simple API Endpoint
Create a HelloWorldController.java
class:
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloWorldController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, World!";
}
}
Run the app and visit http://localhost:8080/hello to confirm it's working.
2. Add Spring Security to Your Project
2.1. Add Spring Security Dependency
Add the following dependency to your build file:
Maven (pom.xml
):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Gradle (build.gradle
):
implementation 'org.springframework.boot:spring-boot-starter-security'
After adding this dependency, restart your application and try to access http://localhost:8080/hello.
What Happened?
You’re likely greeted with a login page! That’s because Spring Security automatically secures all endpoints by default.
The default username is 'user', and the password is logged in your console upon application startup. This can be inconvenient since the password changes each time you restart your application.
2.2. Configure Static Password
To set a static username and password, add the following to your application.properties
file:
spring.security.user.name=user
spring.security.user.password=dummy
With this configuration, you can now use the username 'user' and the password 'dummy' to access secured endpoints.
Understanding Security Filters
3.1. How Security Filters Work
When a request is sent, it is intercepted by Spring Security through a series of filters known as the Security Filter Chain. Security Filter Chains are applied to every request that Spring receives.
To understand the default configuration, look at the WebSecurityConfiguration
class, which contains the default SecurityFilterChain configured for you.
Here’s a typical configuration:
this.httpSecurity.authorizeHttpRequests(
(authorize) -> authorize.anyRequest().authenticated());
this.httpSecurity.formLogin(
Customizer.withDefaults());
this.httpSecurity.httpBasic(
Customizer.withDefaults());
return this.httpSecurity.build();
- authorizeHttpRequests: Ensures that all requests (anyRequest()) require the user to be authenticated.
- formLogin: Sets up form-based authentication, typical for web applications where users enter their credentials via a login form.
- httpBasic: Enables basic authentication, often used for APIs where credentials are passed directly in the HTTP header.
Key Components of Security Filter Chain
Image credit: Kasun Prageeth Dissanayake
Now that we've got better understanding of security filter chain, it's important to understand how Spring Security handles authentication under the hood. Three key components are involved:
- Authentication Manager
- Authentication Provider
- UserDetailsService
Detailed Authentication Flow
1. User Login Attempt:
- The user submits a login form with credentials.
- Filters in the chain process the request to determine if authentication is required.
2. AuthenticationManager Handles the Request:
- If authentication is needed, the credentials are wrapped in an Authentication object and passed to the AuthenticationManager.
3. AuthenticationManager Delegates to AuthenticationProvider:
- The AuthenticationManager delegates the request to one or more AuthenticationProvider instances.
4. AuthenticationProvider Uses UserDetailsService:
- The AuthenticationProvider calls UserDetailsService to load the user’s data.
- UserDetailsService returns a UserDetails object with the user's information.
5. Credentials Verification:
- The AuthenticationProvider compares provided credentials with stored credentials.
- If they match, a fully authenticated Authentication object is returned. Otherwise, an AuthenticationException is thrown.
6. Successful Authentication:
- If successful, the user gains access to the application.
Conclusion
In this post, we successfully integrated Spring Security into a Spring Boot application, secured a simple endpoint with basic authentication, and explored the fundamental components of the Security Filter Chain. By now, you should have a solid understanding of how Spring Security handles requests, manages authentication, and secures your application.
In future posts, we'll cover more advanced security configurations, including integrating databases for credential management, using password encoders, and implementing token-based authentication methods. Stay tuned to further enhance your application's security!
Happy coding! 😊
Top comments (0)