I’m implementing Spring Security login.
In SecurityConfig, I implemented LoginErrorMessageResetFilter to execute before the existing filter as follows.
[SecurityConfig]
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final AuthenticationProvider authenticationProvider;
/**
* @brief Spring Security Setting
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(authz -> authz
.requestMatchers("/login").permitAll()
.anyRequest().authenticated())
.formLogin(f -> {
f.loginPage("/login")
.loginProcessingUrl("/authenticate")
.defaultSuccessUrl("/", true)
.failureHandler(new LoginFailHandler());
})
.addFilterBefore(new TestFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new LoginErrorMessageResetFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
enter image description here
So, what I expected was that in the event of a login failure, the sequence would be request -> LoginErrorMessageResetFilter -> failHandler. However, when I checked the order using Lombok, the failHandler is executed first.
Based on what I’ve studied, I think the login validation should occur after the filter. Am I misunderstanding something, or is there an issue with my code?
[LoginErrorMessageResetFilter]
@Slf4j
public class LoginErrorMessageResetFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpSession session = httpRequest.getSession();
String errorMessage = (String) session.getAttribute("errorMessage");
if (errorMessage != null) {
log.info("LoginErrorMessageResetFilter::" + errorMessage);
session.removeAttribute("errorMessage");
}
chain.doFilter(request, response);
}
}
[LoginFailHandler]
@Slf4j
public class LoginFailHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
String errorMessage = "loginFailHandler::";
if (e instanceof BadCredentialsException || e instanceof InternalAuthenticationServiceException) {
errorMessage += "error1";
} else if (e instanceof UsernameNotFoundException) {
errorMessage +="error2";
} else {
errorMessage +="error3";
}
logger.info(errorMessage);
HttpSession session = request.getSession();
session.setAttribute("errorMessage", errorMessage);
super.onAuthenticationFailure(request, response, e);
}
}
I would be really grateful if someone who knows could tell me.
.addFilterBefore(new TestFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new LoginErrorMessageResetFilter(), UsernamePasswordAuthenticationFilter.class);
<< add, delete filter and move filter’s location.
But, Always failureHandler is first..
손은비 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.