
- Sprint Security - Home
- Spring Security - Introduction
- Spring Security - Architecture
- Spring Security - Project Modules
- Spring Security - Environment Setup
- Spring Security - Form Login
- Spring Security - Custom Form Login
- Spring Security - Logout
- Spring Security - Remember Me
- Spring Security - Redirection
- Spring Security - Taglibs
- Spring Security - XML Configuration
- Spring Security - Authentication Provider
- Spring Security - Basic Authentication
- Spring Security - AuthenticationFailureHandler
- Spring Security - JWT
- Spring Security - Retrieve User Information
- Spring Security - Maven
- Spring Security - Default Password Encoder
- Spring Security – Password Encoding
- Spring Security - Methods Level
- Spring Security - Manual Authentication
- Spring Security - Extra Login Fields
- Spring Security - Prevent Brute Force
- Spring Security - Login Page with React
- Spring Security - Security Filter Chain
- Spring Security - Securing Spring Boot API
- Spring Security Useful Resources
- Spring Security - Quick Guide
- Spring Security - Useful Resources
- Spring Security - Discussion
Spring Security - Authentication Failure Handler
Spring Security allows us to customize our authentication process as much as we want. Starting from a custom login page to our very own customized authentication providers and authentication filters, we can pretty much customize every aspect of the authentication process. We can define our own authentication process which can range from basic authentication using a username and a password to a complex one such as two-factor authentication using tokens and OTPs. We can customize authentication failure handling as well. By default, spring security redirects user to login page where HttpRequest object contains the error information.
Authentication Failure Handler
Spring Security provides AuthenticationFailureHandler interface with onAuthenticationFailure() method. We can use inbuilt handler implementations or create our own handler to customize the onAuthenticationFailure() method implementation.
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.sendRedirect("/error"); } }
Here we're sending http status UNAUTHORIZED or 401 and redirecting user to the error page.
AuthenticationFailureHandler Implementations
Spring Security provides following major implementations of AuthenticationFailureHandler.
SimpleUrlAuthenticationFailureHandler − This is the default authentication failure handler. It redirects user to the failureUrl if specified, otherwise 401 response is returned as UNAUTHORIZED.
ForwardAuthenticationFailureHandler − This authentication failure handler forwards the user to provided url.
ExceptionMappingAuthenticationFailureHandler − This authentication failure handler forwards the user to provided url on the basis of name of the AuthenticationException.
DelegatingAuthenticationFailureHandler − This authentication failure handler allows to use other AuthenticationFailureHandler implementations on the basis of the AuthenticationException instances.
We'll be creating our own AuthenticationFailureHandler in coming section.
Spring Security Configuration
We need to configure the CustomAuthenticationFailureHandler in spring securty configuration
http //... .formLogin(form -> form.loginPage("/login") .defaultSuccessUrl("/") .failureHandler(new CustomAuthenticationFailureHandler()) .permitAll()) ... }
That's all we need. Now let's see the complete code in action.
Before you start writing your first example using Spring framework, you have to make sure that you have set up your Spring environment properly as explained in Spring Security - Environment Setup Chapter. We also assume that you have a bit of working knowledge on Spring Tool Suite IDE.
Now let us proceed to write a Spring MVC based Application managed by Maven, which will ask user to login, authenticate user and then provide option to logout using Spring Security Form Login Feature.
Create Project using Spring Initializr
Spring Initializr is great way to start with Spring Boot project. It provides a easy to use User Interface to create a project, add dependencies, select java runtime etc. It generates a skeleton project structure which once downloaded can be imported in spring tool suite and we can proceed with our readymade project structure.
We're choosing a maven project, naming the project as formlogin, with java version as 21. Following dependencies are added:
Spring Web
Spring Security
Spring Boot DevTools

Thymeleaf is a templating engine for Java. It allows us to quickly develop static or dynamic web pages for rendering in the browser. It is extremely extensible and allows us to define and customize the processing of our templates in fine detail. In addition to this, we can learn more about Thymeleaf by clicking this link.
Let's move on to generate our project and download it. We then extract it to a folder of our choice and use any IDE to open it. I shall be using Spring Tools Suite 4. It is available for free downloading from the https://spring.io/tools website and is optimized for spring applications.
pom.xml with all relevant dependencies
Let's take a look at our pom.xml file. It should look something similar to this −
pom.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.3.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.tutorialspoint.security</groupId> <artifactId>formlogin</artifactId> <version>0.0.1-SNAPSHOT</version> <name>formlogin</name> <description>Demo project for Spring Boot</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>21</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity6</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <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> </plugin> </plugins> </build> </project>
AuthenticationFailureHandler
Inside of our config package, we have created the CustomAuthenticationFailureHandler class by implementing AuthenticationFailureHandler interface. As in onAuthenticationFailure() method, we're setting HTTP Status as UNAUTHORIZED and redirecting user to the error page.
package com.tutorialspoint.security.formlogin.config; import java.io.IOException; import org.springframework.http.HttpStatus; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.sendRedirect("/error"); } }
Spring Security Configuration Class
Inside of our config package, we have created the WebSecurityConfig class. We shall be using this class for our security configurations, so let's annotate it with an @Configuration annotation and @EnableWebSecurity. As a result, Spring Security knows to treat this class a configuration class. As we can see, configuring applications have been made very easy by Spring.
WebSecurityConfig
package com.tutorialspoint.security.formlogin.config; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.Customizer; 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.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.core.AuthenticationException; 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.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean protected UserDetailsService userDetailsService() { UserDetails user = User.builder() .username("user") .password(passwordEncoder().encode("user123")) .roles("USER") .build(); UserDetails admin = User.builder() .username("admin") .password(passwordEncoder().encode("admin123")) .roles("USER", "ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); } @Bean protected PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests( request -> request.requestMatchers("/login").permitAll() .requestMatchers("/error").permitAll() .requestMatchers("/**").authenticated() ) .formLogin(form -> form.loginPage("/login") .defaultSuccessUrl("/") .failureHandler(new CustomAuthenticationFailureHandler()) .permitAll()) .logout(config -> config .logoutUrl("/logout") .logoutSuccessUrl("/login")) .build(); } }
Configuration Class Details
Let's take a look at our configuration class.
First, we shall create a bean of our UserDetailsService class by using the userDetailsService() method. We shall be using this bean for managing our users for this application. Here, to keep things simple, we shall use an InMemoryUserDetailsManager instance to create users. These users, along with our given username and password, are mapped to User and Admin roles respectively.
Http Security Configuration
After the above steps, we move on to our next configuration. Here, we've defined the filterChain method. This method takes HttpSecurity as a parameter. We shall be configuring this to use our form login and logout function.
We can observe that all these functionalities are available in Spring Security. Lets study the below section in detail −
return http //... .failureHandler(new CustomAuthenticationFailureHandler()) //... .build();
Here we're added a authentication failure handler as CustomAuthenticationFailureHandler instance.
Controller Class
In this class, we've created a mapping for single "/" endpoint for the index page of this application, for simplicity. This will redirect to index.html.
AuthController
package com.tutorialspoint.security.formlogin.controllers; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class AuthController { @GetMapping("/") public String home() { return "index"; } }
Views
Create index.html in /src/main/resources/templates folder with following content to act as a home page.
index.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6"> <head> <title> Hello World! </title> </head> <body> <h1 th:inline="text">Hello World!</h1> <a href="/logout" alt="logout">Sign Out</a> </body> <html>
Create error.html in /src/main/resources/templates folder with following content to act as an error page.
error.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6"> <head> <title> Invalid Credentials </title> </head> <body> <h1>Invalid Credentials.</h1> </body> <html>
Running the Application
As we've all component ready, let's run the Application. Right Click on the project, select Run As and then Spring Boot App.
It will boot up the application and once application is started, we can run localhost:8080 to check the changes.
Output
Now open localhost:8080, you can see the login page.
Enter Invalid Credential

Error Page
If we enter invalid credential, then user will be redirected to error page.
