Spring Security Authentication Failure Handler Examples
- Details
- Written by Nam Ha Minh
- Last Updated on 30 October 2020   |   Print Email
In this Spring Security article, I would like to share with you some code examples that customize the authentication process in order execute some custom logics upon user’s failure login. In practice, we may need to perform the following tasks right after a user fails to login:
- Log the failed login attempt (for auditing purpose)
- Record the failed login to implement limit failed login attempts feature (to prevent brute force attack)
- Display a custom login failure page
- any custom logics we want to perform upon authentication failure.
We can easily implement that, thanks to the highly customizable and flexible APIs provided by Spring Security. The following diagram explains the process:
As you can see, we need to configure an authentication failure handler which will be invoked by Spring Security upon failed login. And then we can decide to redirect the user to the default login error page, or any page which the user must see.
Now, let’s see how to write code.
1. Simple Authentication Failure Handler
Suppose that you have an existing Spring Boot application in which Spring Security is used for authentication. The following code snippet shows you the simplest way of implementing an authentication failure handler using an anonymous class:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ... @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() ... .formLogin() .loginPage("/login") .usernameParameter("email") .failureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { String email = request.getParameter("email"); String error = exception.getMessage(); System.out.println("A failed login attempt with email: " + email + ". Reason: " + error); String redirectUrl = request.getContextPath() + "/login?error"; response.sendRedirect(redirectUrl); } }) .permitAll() ... } }
As you can see, the AuthenticationFailureHandler interface defines the method onAuthenticationFailure() which will be called by Spring Security upon a failed login attempt. The code in this example just logs the information (email and error message) and then redirects the user to the login error page.
However, it is recommended to have the handler class extends the SimpleUrlAuthenticationFailureHandler class which will redirect the user to the default failure URL and also forward the exception object, as shown in the following example:
.formLogin() .loginPage("/login") .usernameParameter("email") .failureHandler(new SimpleUrlAuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { String email = request.getParameter("email"); String error = exception.getMessage(); System.out.println("A failed login attempt with email: " + email + ". Reason: " + error); super.setDefaultFailureUrl("/login?error"); super.onAuthenticationFailure(request, response, exception); } })
Here, we need to specify the default failure URL, otherwise it will give 404 error. But in the login page we can display the exception message.
2. Advanced Authentication Failure Handler
In case the authentication failure handler needs to depend on a business/service class in order to perform the custom logics upon failed login, we should create a separate authentication failure handler class, as shown in the example code below:
@Component public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler { @Autowired private CustomerServices customerService; @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { String email = request.getParameter("email"); String redirectURL = "/login?error&email=" + email; if (exception.getMessage().contains("OTP")) { redirectURL = "/login?otp=true&email=" + email; } else { Customer customer = customerService.getCustomerByEmail(email); if (customer.isOTPRequired()) { redirectURL = "/login?otp=true&email=" + email; } } super.setDefaultFailureUrl(redirectURL); super.onAuthenticationFailure(request, response, exception); } }
Here, you see the handler class is annotated with the @Component annotation – so Spring framework will manage instances (beans) of this class. And it depends on an instance of the CustomerService class, which will be injected by Spring framework because the @Autowired annotation is used. And you can see code in the onAuthenticationFailure() callback method needs to use CustomerService.
And update the Spring security configuration class as follows:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ... @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() ... .formLogin() .loginPage("/login") .usernameParameter("email") .failureHandler(failureHandler) ... } @Autowired private LoginFailureHandler failureHandler; }
That’s some code examples for implementing authentication failure handler in a Spring Boot application. To see the coding in action, I recommend you to watch the following video:
Related Spring Security Tutorials:
- Spring Security Authentication with JPA, Hibernate and MySQL
- Spring Security Role-based Authorization Tutorial
- Spring Security Customize Login and Logout
- How to Get Logged-in User's Details with Spring Security
- Spring Security: Prevent User from Going Back to Login Page if Already logged in
- Spring Security Authentication Success Handler Examples
- Spring Security Logout Success Handler Example
- Spring Security Before Authentication Filter Examples
Other Spring Boot Tutorials:
- How to create a Spring Boot Web Application (Spring MVC with JSP/ThymeLeaf)
- Spring Boot CRUD Example with Spring MVC – Spring Data JPA – ThymeLeaf - Hibernate - MySQL
- Spring Boot Hello World RESTful Web Services Tutorial
- Spring Boot Thymeleaf Form Handling Tutorial
- Spring Data JPA Paging and Sorting Examples
- Spring Boot Error Handling Guide
- Spring Boot Logging Basics
Comments