Spring Security Authentication Success Handler Examples
- Details
- Written by Nam Ha Minh
- Last Updated on 30 October 2020   |   Print Email
In this Spring Security post, I would like to share with you some code examples that intervene the authentication process of Spring Security in order to run custom logics upon successful login, in a Spring Boot application.
For examples, the application needs to perform these tasks upon user’s successful login:
- Log user’s information (for auditing purpose)
- Request to change password if expired, or request to update user’s details
- Clear previous failed login attempts (for limit login attempts functionality)
- Clear One-Time Password (for OTP functionality)
- any custom logics you want to execute after successful authentication
And Spring Security allows programmers to do that by configuring an authentication success hander, which is explained in the following diagram:
In this article, I will share with you two different ways for implementing an authentication success handler in a Spring Boot application: simple and advanced.
1. Simple Authentication Success Handler
In this way, we create an anonymous class of type AuthenticationSuccessHandler as parameter for the successHandler() method of a FormLoginConfigurer class in a Spring security configuration class, as below:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { ... @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() ... .formLogin() .loginPage("/login") .usernameParameter("email") .permitAll() .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { // run custom logics upon successful login } }) ... } }
The callback method onAuthenticationSuccess() will be invoked by Spring Security right after a user has logged in successfully to the application.
This approach is suitable for simple use case, e.g. logging information. For example:
.formLogin() .loginPage("/login") .usernameParameter("email") .permitAll() .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { // run custom logics upon successful login UserDetails userDetails = (UserDetails) authentication.getPrincipal(); String username = userDetails.getUsername(); System.out.println("The user " + username + " has logged in."); response.sendRedirect(request.getContextPath()); } })
As you can see, the code snippet in the callback method prints username of the authenticated user and redirect the user to the homepage.
It’s recommended to extend the SavedRequestAwareAuthenticationSuccessHandler class which will automatically redirect the user to the secured page prior to login. For example:
successHandler(new SavedRequestAwareAuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { // run custom logics upon successful login UserDetails userDetails = (UserDetails) authentication.getPrincipal(); String username = userDetails.getUsername(); System.out.println("The user " + username + " has logged in."); super.onAuthenticationSuccess(request, response, authentication); } })
It’s better to use this implementation because Spring Security saved the URL prior to login and redirect the user back to that URL upon successful authentication.
2. Advanced Authentication Success Handler
In case the authentication success handler class needs to use another business class (a dependency) to perform the custom logics, we need to configure spring security differently.
First, create a separate handler class that extends SavedRequestAwareAuthenticationSuccessHandler class as follows:
@Component public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { @Autowired private CustomerServices customerService; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { CustomerUserDetails customerDetails = (CustomerUserDetails) authentication.getPrincipal(); Customer customer = customerDetails.getCustomer(); if (customer.isOTPRequired()) { customerService.clearOTP(customer); } super.onAuthenticationSuccess(request, response, authentication); } }
Here, the @Component annotation is used so its instances will be managed by Spring framework and injectable into other components if needed. And as you can see, this handler depends on CustomerService class to perform the custom logics in the callback method onAuthenticationSuccess().
And in the Spring Security configuration class, we need to autowire an instance of the handler 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") .permitAll() .successHandler(loginSuccessHandler) ... } @Autowired private LoginSuccessHandler loginSuccessHandler; }
So this advanced configuration would be suitable for almost any use cases of an authentication success handler.
To see the coding in action, I recommend you to watch the following video:
I hope you’ve found this post helpful. To learn more about Spring Security, check the following articles:
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 Failure 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