Spring Security Custom AuthenticationFailureHandler
Last Updated :
24 Apr, 2025
In Java, Spring Security is a very powerful framework that can provide comprehensive security services for Java enterprise software applications. One of the essential aspects of the security is authentication and it can be users are verified before granting access to the resource. Spring Security can allow for the customization of the authentication processes, and it can include handling authentication failures.
Implementation of Custom AuthenticationFailureHandler in Spring Security
We can develop the simple login management Spring application with the Custom Authentication failure handler mechanism.
Step 1: We can create the spring project including the below dependencies into the project.
Dependencies:
- Spring Web
- Spring Security
- Spring Data for MongoDB
- Spring Dev Tools
- Lombok
Once create the spring project with the above dependencies into the project then file structure looks like the below image.
File Structure:

Step 2: Open the application.properties file and put the below code for the database configuration.
spring.data.mongodb.uri=mongodb://localhost:27017/CustomData
Step 3: Create the new package named as the model and create the java class named as the User.
Go to src > com.gfg.customauthenticationfailure > model > User and put the below code.
Java
package com.gfg.customauthenticationfailure.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
// The @Data annotation generates getters, setters, toString, equals, and hashCode methods automatically
@Data
// The @AllArgsConstructor annotation generates a constructor with all arguments
@AllArgsConstructor
// The @NoArgsConstructor annotation generates a constructor with no arguments
@NoArgsConstructor
// The @Document annotation marks this class as a document in a MongoDB collection
@Document(collection = "users")
public class User {
// The @Id annotation marks this field as the primary key of the document
@Id
private String id;
// The @Field annotation specifies the name of the field in the MongoDB document
// If not specified, the field name will be the same as the variable name
private String username;
private String password;
}
Step 4: Create the new package named as the repository and create the java interface named as the UserRepository.
Go to src > com.gfg.customauthenticationfailure > repository > UserRepository and put the below code.
Java
package com.gfg.customauthenticationfailure.repository;
import com.gfg.customauthenticationfailure.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
// The @Repository annotation marks this interface as a repository component in Spring
@Repository
public interface UserRepository extends MongoRepository<User, String> {
// Method to find a user by their username
User findByUsername(String username);
}
Step 5: Create the new package named as the service and create the java interface named as the UserService.
Go to src > com.gfg.customauthenticationfailure > service > UserService and put the below code.
Java
package com.gfg.customauthenticationfailure.service;
import com.gfg.customauthenticationfailure.model.User;
import com.gfg.customauthenticationfailure.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
// The @Service annotation marks this class as a service component in Spring
@Service
public class UserService {
// Autowire the UserRepository to interact with the database
@Autowired
private UserRepository userRepository;
// Method to find a user by their username
public User findByUsername(String username) {
// Call the findByUsername method of the userRepository to find the user by username
return userRepository.findByUsername(username);
}
}
Step 6: Create the new package named as the securityconfig and create the java interface named as the CustomAuthenticationFailureHandler.
Go to src > com.gfg.customauthenticationfailure > securityconfig > CustomAuthenticationFailureHandler and put the below code.
Java
package com.gfg.customauthenticationfailure.securityconfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import java.io.IOException;
// Implement the AuthenticationFailureHandler interface to create a custom authentication failure handler
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
// Override the onAuthenticationFailure method to handle authentication failure
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
// Your custom failure handling logic goes here
// For example, redirect the user to the login page with an error message in the URL
response.sendRedirect("/login?error=true");
}
}
Step 7: Create the new package named as the securityconfig and create the java interface named as the SecurityConfig.
Go to src > com.gfg.customauthenticationfailure > securityconfig > SecurityConfig and put the below code.
Java
package com.gfg.customauthenticationfailure.securityconfig;
import com.gfg.customauthenticationfailure.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private UserRepository userRepository;
// Override the configure method to specify which URLs are allowed and which are not
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.requestMatchers("/signup").permitAll() // Allow requests to /signup without authentication
.anyRequest().authenticated() // Require authentication for all other requests
.and()
.formLogin() // Enable form-based login
.loginPage("/login") // Specify the login page URL
.failureHandler(new CustomAuthenticationFailureHandler()) // Specify the failure handler for login attempts
.permitAll() // Allow anyone to access the login page
.and()
.logout() // Enable logout functionality
.permitAll(); // Allow anyone to access the logout URL
}
// Create a PasswordEncoder bean to encode and decode passwords
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Step 8: Create the new package named as the request and create the java interface named as the SignRequest.
Go to src > com.gfg.customauthenticationfailure > request > SignRequest and put the below code.
Java
package com.gfg.customauthenticationfailure.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
// Lombok annotations for automatically generating getters, setters, and constructors
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SigninRequest {
// Fields for username and password
String username;
String password;
}
Step 9: Create the new package named as the controller and create the java interface named as the UserController.
Go to src > com.gfg.customauthenticationfailure > controller > UserController and put the below code.
Java
package com.gfg.customauthenticationfailure.controller;
import com.gfg.customauthenticationfailure.model.User;
import com.gfg.customauthenticationfailure.repository.UserRepository;
import com.gfg.customauthenticationfailure.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import com.gfg.customauthenticationfailure.request.SigninRequest;
@RestController
public class UserController {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
// Handle the /signup endpoint for registering new users
@PostMapping("/signup")
public void signUp(@RequestBody User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
userRepository.save(user);
}
@Autowired
private UserService userService;
// Handle the /signin endpoint for user authentication
@PostMapping("/signin")
public void signIn(@RequestBody SigninRequest signInRequest) throws Exception {
// Authenticate the user manually
User user = userService.findByUsername(signInRequest.getUsername());
if (user != null && user.getPassword().equals(signInRequest.getPassword())) {
// If the user is found and the password matches, authenticate the user
Authentication authentication = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
// If the user is not found or the password doesn't match, throw an exception
throw new Exception("Invalid username or password");
}
}
}
Step 10: Open the main class and put the below code.
Java
package com.gfg.customauthenticationfailure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CustomAuthenticationFailureApplication {
public static void main(String[] args) {
SpringApplication.run(CustomAuthenticationFailureApplication.class, args); // starts the Spring Boot application
// run the Spring Boot application
}
}
pom.xml File:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>CustomAuthenticationFailure</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>CustomAuthenticationFailure</name>
<description>CustomAuthenticationFailure</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 11: Once completed the spring project and its run as the spring application then the application runs the port 8080.

Similar Reads
Spring Security - Form-Based Authentication
Form-Based Authentication in Spring Security provides a secure way to authenticate users using a custom login form instead of the default security prompt. It allows better control over authentication flow, user experience, and security configurations. Key Features: Customizable login and logout mech
5 min read
Spring Security - Authentication Providers
Authentication in Spring Security refers to the process of verifying the identity of a user or a client application attempting to access a protected resource. In other words, it's the process of validating the user's credentials (such as username and password) to ensure that they are who they claim
14 min read
Spring Security - Role Based Authentication
Authentication is when anyone wants to access your Rest API they need some Authorization like a Username, Password, and token kind of. So Spring Boot Security has a Spring Boot 6.2.0 version. In the lower version Some Methods are deprecated in spring Security that's why a new thing comes into the pi
4 min read
Spring Security - Two Factor Authentication
Two-factor authentication (2FA) is a security method that requires users to provide two forms of authentication to access their accounts. These forms of authentication typically include something the user knows (such as a password or PIN) and something the user has (such as a mobile device or hardwa
10 min read
Authentication in Spring Security
In Spring Security, âauthenticationâ is the process of confirming that a user is who they say they are and that they have the right credentials to log in to a protected resource or to perform a privileged action in an application. Spring Security helps you set up different authentication methods, li
13 min read
Spring Security - Basic Authentication
Spring Security is a framework that allows a programmer to use JEE (Java Enterprise Edition) components to set security limitations on Spring Framework-based web applications. As a core part of the Spring ecosystem, itâs a library that can be utilized and customized to suit the demands of the progra
7 min read
Spring Security - In-Memory Authentication
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring
4 min read
Spring Boot Security Auto-Configuration
Spring Boot Security Auto Configuration can simplify the process of securing the Spring Boot applications by providing default security configurations. It can automate the many common security tasks such as setting up the authentication, and authorization and it can handle the common security vulner
4 min read
Spring Security Annotations
There are multiple annotations supported by Spring Security. But, in this article, we will discuss about these annotations can be used in a Spring Boot project as well. These annotations play a crucial role in creating a web application in Spring Boot. The Spring Security annotations are a powerful
3 min read
Securing Spring Cloud Config Server with Basic Authentication
Spring Cloud Config Server provides externalization for distributed systems. With the increasing importance of microservices, centrally managing configurations becomes crucial. Securing this configuration server is equally important to prevent unauthorized access. Basic authentication is a simple an
4 min read