AuthenticationProvider
is a core component that allows custom authentication logic. This tutorial will guide you through setting up a Spring Boot 3.2 application with Spring Security 6.1 and implementing a custom AuthenticationProvider
.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
- Thymeleaf (optional, for the frontend)
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
server.port=8080
# Thymeleaf configuration (optional)
spring.thymeleaf.cache=false
Step 2: Create a Custom Authentication Provider
2.1 Implement the CustomAuthenticationProvider
Create a class to implement the AuthenticationProvider
interface.
package com.example.demo.security;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
if (authenticateUser(username, password)) {
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new UsernamePasswordAuthenticationToken(username, password, authorities);
} else {
throw new BadCredentialsException("Authentication failed");
}
}
private boolean authenticateUser(String username, String password) {
// Custom authentication logic (e.g., checking credentials against a database)
return "user".equals(username) && "password".equals(password);
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Explanation:
authenticate
: Custom logic to authenticate the user.authenticateUser
: A helper method for the custom authentication logic.supports
: Checks if theAuthenticationProvider
can handle the given authentication token.
Step 3: Configure Spring Security
3.1 Create a Security Configuration Class
Create a configuration class to set up Spring Security and register the custom AuthenticationProvider
.
package com.example.demo.config;
import com.example.demo.security.CustomAuthenticationProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
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;
import org.springframework.beans.factory.annotation.Autowired;
@Configuration
public class SecurityConfig {
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/login", "/resources/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(formLogin ->
formLogin
.loginPage("/login")
.permitAll()
)
.logout(logout ->
logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.permitAll()
)
.authenticationProvider(customAuthenticationProvider);
return http.build();
}
}
Explanation:
SecurityFilterChain
: Configures the security filter chain.authorizeHttpRequests
: Defines URL authorization.formLogin
: Configures form-based login.logout
: Configures logout functionality.authenticationProvider
: Registers the customAuthenticationProvider
.
Step 4: Create the Login and Home Pages
4.1 Create the Login Page
Create a login page using Thymeleaf. Create a file named login.html
in the src/main/resources/templates
directory.
<!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>
<div th:if="${param.logout}">
You have been logged out.
</div>
<div th:if="${param.error}">
Invalid username or password.
</div>
</body>
</html>
4.2 Create the Home Page
Create a home page that will be accessible only to authenticated users. Create a file named home.html
in the src/main/resources/templates
directory.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<h1>Welcome, <span th:text="${#httpServletRequest.remoteUser}">User</span>!</h1>
<a th:href="@{/logout}">Logout</a>
</body>
</html>
Step 5: Create a Controller
5.1 Create the HomeController
Create a controller to handle requests to the login and home pages.
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/")
public String home() {
return "home";
}
}
Explanation:
@Controller
: Marks the class as a web controller.@GetMapping("/login")
: Maps GET requests for the login page.@GetMapping("/")
: Maps GET requests for the home page.
Step 6: Running and Testing the Application
6.1 Run the Application
Run the Spring Boot application using your IDE or the command line:
./mvnw spring-boot:run
6.2 Test the Login Functionality
- Open a web browser and navigate to
http://localhost:8080
. - You will be redirected to the login page.
- Enter the username
user
and passwordpassword
, and click the "Login" button.- You should be redirected to the home page and see a welcome message.
- Log out by clicking the "Logout" link.
Conclusion
In this tutorial, you have learned how to implement a custom AuthenticationProvider
using Spring Security 6.1 in a Spring Boot 3.2 application. We covered:
- Setting up a Spring Boot project with Spring Security.
- Implementing a custom
AuthenticationProvider
for custom authentication logic. - Configuring Spring Security to use the custom
AuthenticationProvider
. - Creating login and home pages using Thymeleaf.
- Creating a controller to handle requests.
By following these steps, you can effectively manage authentication in your Spring Boot applications using custom authentication logic with Spring Security.
Comments
Post a Comment