处理认证失败后的逻辑AuthenticationFailureHandler
大约 3 分钟
处理认证失败后的逻辑AuthenticationFailureHandler
1、简介
AuthenticationFailureHandler
是一个接口,用于处理认证失败后的逻辑。当用户尝试登录并提供无效的凭据时,AuthenticationFailureHandler
会处理认证失败的情况。可以自定义该处理器来执行特定的操作,如显示错误消息、记录登录失败信息、跳转到特定页面等。作用如下:
- 提供详细的错误消息给用户。
- 在认证失败时记录错误信息或进行其他操作。
- 控制认证失败后的跳转页面或重定向。
- 限制连续的登录失败次数(例如账户锁定机制)。
2、源码
public interface AuthenticationFailureHandler {
void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException;
}
参数说明:
HttpServletRequest request
:当前请求对象,用于获取请求的详细信息。HttpServletResponse response
:当前响应对象,用于发送响应信息。AuthenticationException exception
:认证失败时抛出的异常。这个异常包含了失败的原因,通常是BadCredentialsException
或其他认证失败的异常。
3、使用场景
3.1、提示用户输入错误的凭据
最常见的场景是当用户输入错误的用户名或密码时,重定向到登录页面并显示错误信息。
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
// 记录错误信息,可以在这里进行日志记录等
request.setAttribute("error", "Invalid username or password"); // 设置错误消息到请求中
// 重定向到登录页面,并显示错误提示
request.getRequestDispatcher("/login?error=true").forward(request, response); // 转发到登录页面并附带错误标志
}
}
此示例中,如果登录失败,将错误信息传递给登录页面,并将用户重定向回登录页面,通常是显示一个“错误”的标识,提示用户凭据输入错误
3.2、记录失败日志
ublic class LoggingAuthenticationFailureHandler implements AuthenticationFailureHandler {
private static final Logger logger = Logger.getLogger(LoggingAuthenticationFailureHandler.class.getName());
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
String username = request.getParameter("username");
// 记录登录失败的日志
logger.warning("Login attempt failed for user: " + username);
// 跳转回登录页面并提示错误
response.sendRedirect("/login?error=true");
}
}
3.3、登录失败次数限制(账户锁定)
public class FailureCountAuthenticationFailureHandler implements AuthenticationFailureHandler {
private static final int MAX_FAILURES = 5; // 最大失败次数
private static final AtomicInteger failureCount = new AtomicInteger(0); // 记录失败次数
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
// 增加失败次数
failureCount.incrementAndGet();
if (failureCount.get() >= MAX_FAILURES) {
// 达到最大失败次数,锁定账户或进行其他操作
response.sendRedirect("/account-locked"); // 跳转到账户锁定页面
} else {
// 否则继续提示错误
response.sendRedirect("/login?error=true");
}
}
}
4、配置
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// 开启授权保护
.authorizeHttpRequests(authorize -> authorize
.anyRequest()//对所有请求开启授权保护
.authenticated()//已认证的请求会被自动授权
)
//自定义登录页面
.formLogin(form -> form.loginPage("/login").permitAll()
.successHandler(new MyAuthenticationSuccessHandler()) //认证成功时的处理
.failureHandler(new MyAuthenticationFailureHandler()) //认证失败时的处理
)//.permitAll() 解决localhost 将您重定向的次数过多
.httpBasic(withDefaults())//使用基本授权方式
.csrf(AbstractHttpConfigurer::disable)//关闭 csrf 攻击防御
;
return http.build();
}