Spring Security in Spring Boot 3 provides a robust security framework that can be easily integrated into your application, even without using a custom login page or a database. This guide will walk you through the process of setting up Spring Security in a Spring Boot 3 application with in-memory authentication, using default login mechanisms provided by Spring Security.
Step 1: Set Up Your Spring Boot 3 Project
You can create a new Spring Boot 3 project using Spring Initializr (https://start.spring.io/). Select the following dependencies:
- Spring Web: For building REST APIs or web applications.
- Spring Security: For adding security features.
Step 2: Update pom.xml
Make sure your pom.xml
includes the necessary dependencies for Spring Web and Spring Security:
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Security Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
Step 3: Create the Security Configuration Class
In Spring Boot 3, security configuration is done using SecurityFilterChain
and UserDetailsService
. Here’s how you can configure in-memory authentication with default login and no custom login page:
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.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public/**").permitAll() // Allow access to the /public/ path without authentication
.anyRequest().authenticated() // All other requests require authentication
)
.formLogin(withDefaults()) // Enable default login page
.httpBasic(withDefaults()); // Enable HTTP Basic authentication for API testing
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder() // In-memory user details
.username("user")
.password("password")
.roles("USER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("admin")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
Step 4: Explanation of Configuration
securityFilterChain(HttpSecurity http)
Method:- Configures the security for HTTP requests.
- The
/public/**
path is open to all users, meaning no authentication is required. - All other paths require authentication.
- The default Spring Security login form is enabled by using
formLogin()
. This will provide a basic login page out of the box. - Basic authentication is also enabled for non-browser clients (e.g., Postman, curl).
userDetailsService()
Method:- Defines two in-memory users:
user
with the roleUSER
andadmin
with the roleADMIN
. - Passwords are encoded using
withDefaultPasswordEncoder()
, which is a simple and not secure password encoder for demonstration purposes. For production, use a stronger password encoder likeBCryptPasswordEncoder
.
Step 5: Default Login Page and Basic Authentication
With this configuration, when you access any secured endpoint (e.g., /api/private
), Spring Security will redirect you to a default login page. This login page is provided by Spring Security and requires you to enter a username and password.
For example:
- Accessing
/public/welcome
will not require authentication. - Accessing
/api/private
will redirect you to the login page if not authenticated.
Step 6: Test Your Application
To test the application:
- Run your Spring Boot application.
- Open your browser and go to
http://localhost:8080/public/welcome
. This path should be accessible without any authentication. - Now, navigate to any other endpoint, such as
http://localhost:8080/api/private
. You will be redirected to the default login page. - Log in using the credentials
user/password
oradmin/admin
. Once logged in, you should be able to access the protected resource.
Step 7: Test with HTTP Basic Authentication
You can also test HTTP Basic authentication using tools like Postman or curl.
For example, to access the protected endpoint via curl:
curl -u user:password http://localhost:8080/api/private
This will authenticate the user and provide access to the protected resource.
Example REST Controller:
You can create a simple REST controller to demonstrate the secured and unsecured endpoints:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/public/welcome")
public String publicEndpoint() {
return "Welcome to the public endpoint!";
}
@GetMapping("/api/user")
@PreAuthorize("hasRole('USER')")
public String userEndpoint() {
return "This is a user-only endpoint!";
}
@GetMapping("/api/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminEndpoint() {
return "This is an admin-only endpoint!";
}
@GetMapping("/api/any")
@PreAuthorize("hasAnyRole('USER', 'ADMIN')")
public String userOrAdminEndpoint() {
return "This endpoint is accessible by USER or ADMIN roles!";
}
@GetMapping("/api/custom")
@PreAuthorize("hasRole('ADMIN') and #customCheck(#parameter)")
public String customEndpoint(String parameter) {
return "This is a custom-secured endpoint!";
}
// Custom method with a security check in SpEL
public boolean customCheck(String parameter) {
return parameter != null && parameter.equals("valid");
}
}
Step 8: Customizing Further (Optional)
If you want to customize the security configuration further, such as adding additional roles or configuring more complex access rules, you can do so within the HttpSecurity
configuration. However, for basic setups with in-memory authentication and no custom login page, the steps above should be sufficient.
Conclusion:
This guide has walked you through setting up Spring Security in Spring Boot 3 with in-memory authentication, using default login forms, and securing endpoints without the need for a database or custom login pages. This is a simple and effective way to add security to your Spring Boot application while adhering to modern security practices.