Prerequisites
- JDK 17 or later
- Maven or Gradle
- IDE (IntelliJ IDEA, Eclipse, etc.)
Step 1: Set Up a Spring Boot Project
1.1 Create a New Spring Boot Project
Use Spring Initializr to create a new project with the following dependencies:
- Spring Web
- Spring Security
Download and unzip the project, then open it in your IDE.
1.2 Configure application.properties
Set up the application properties for your project. This file is located in the src/main/resources
directory.
# src/main/resources/application.properties
server.port=8080
Step 2: Implement Security Configuration
2.1 Create a Security Configuration Class
In Spring Boot 3.2, the way to configure security has changed. The authorizeRequests()
method has been replaced with authorizeHttpRequests()
, and antMatchers()
has been replaced with requestMatchers()
. We will use these new methods to set up our security configuration.
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/login")
.permitAll()
)
.logout((logout) -> logout
.permitAll()
);
return http.build();
}
}
Explanation:
@Configuration
: Marks this class as a source of bean definitions.SecurityFilterChain
: Configures the security filter chain.authorizeHttpRequests()
: Replaces the deprecatedauthorizeRequests()
.requestMatchers()
: Replaces the deprecatedantMatchers()
for URL matching.formLogin()
: Configures form-based authentication.logout()
: Configures the logout functionality.
2.2 Create a Custom Login Page
Create a custom login page in the src/main/resources/templates
directory. If you're not using Thymeleaf, adjust the path and file type as necessary.
<!-- src/main/resources/templates/login.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form th:action="@{/login}" method="post">
<div>
<label>Username:</label>
<input type="text" name="username"/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
</body>
</html>
2.3 Create a Controller for Public Access
Create a controller to handle public and secure endpoints.
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/public")
public String publicEndpoint() {
return "This is a public endpoint.";
}
@GetMapping("/secure")
public String secureEndpoint() {
return "This is a secure endpoint.";
}
}
Explanation:
@RestController
: Marks the class as a REST controller.@GetMapping("/public")
: Maps GET requests to thepublicEndpoint
method.@GetMapping("/secure")
: Maps GET requests to thesecureEndpoint
method.
Step 3: Running and Testing the Application
3.1 Run the Application
Run the Spring Boot application using your IDE or the command line:
./mvnw spring-boot:run
3.2 Test the Security Configuration
-
Open your browser and navigate to
http://localhost:8080/public
. You should see the message "This is a public endpoint." -
Navigate to
http://localhost:8080/secure
. You should be redirected to the login page. -
Log in using the default credentials provided by Spring Security (
user
and a generated password printed in the console). -
After logging in, you should see the message "This is a secure endpoint."
Step 4: Customizing User Details
4.1 Create a Custom UserDetailsService
To provide custom user details, you can implement the UserDetailsService
interface.
package com.example.demo.service;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class UserDetailsServiceConfig {
@Bean
public UserDetailsService userDetailsService() {
var userDetailsService = new InMemoryUserDetailsManager();
var user = User.withUsername("user")
.password("{noop}password") // {noop} indicates no encoding
.roles("USER")
.build();
userDetailsService.createUser(user);
return userDetailsService;
}
}
Explanation:
InMemoryUserDetailsManager
: An implementation ofUserDetailsService
that stores user details in memory.User.withUsername("user")
: Creates a user with the username "user" and password "password" (no encoding).
4.2 Update Security Configuration
Update the SecurityConfig
class to use the custom UserDetailsService
.
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
private final UserDetailsService userDetailsService;
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/login")
.permitAll()
)
.logout((logout) -> logout
.permitAll()
)
.userDetailsService(userDetailsService);
return http.build();
}
}
Explanation:
- The
SecurityConfig
constructor now takes aUserDetailsService
parameter. - The
userDetailsService
method is added to the security filter chain configuration.
Conclusion
In this tutorial, you have learned how to set up and configure security in a Spring Boot 3.2 application using the new recommended approach. We covered:
- Creating a custom security configuration class.
- Setting up a custom login page.
- Creating a controller for public and secure endpoints.
- Running and testing the security configuration.
- Customizing user details with a custom
UserDetailsService
.
By following these steps, you can secure your Spring Boot applications and control access to different parts of your application.
Comments
Post a Comment