文章目录
-
- 前言
- 简单介绍官方默认用户认证失败后处理器
- 自定义使用
- [SecurityConfiguration 配置](#SecurityConfiguration 配置)
前言
AuthenticationFailureHandler
主要是做用户认证失败后调用的处理器,这里的失败一般是指用户名或密码错误。当出现错误后,该处理器就会被调用,一般在开发中,会自己实现一个处理器,用来给前端返回一些已经商量好的异常码,下面分成两大块,先简单介绍一下官方给的一些用户失败后的处理器,再介绍我们自己实现的自定义处理器。
简单介绍官方默认用户认证失败后处理器
SimpleUrlAuthenticationFailureHandler
当认证失败后,重定向到一个指定的URL。
java
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
http
// 登录
.formLogin()
// 认证失败后处理器
.failureHandler(authenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
SimpleUrlAuthenticationFailureHandler handler = new SimpleUrlAuthenticationFailureHandler();
// 认证失败后重定向的URL
handler.setDefaultFailureUrl("/login?error=true");
return handler;
}
ForwardAuthenticationFailureHandler
认证失败后转发到一个指定的URL。
java
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
http
// 登录
.formLogin()
// 认证失败后处理器
.failureHandler(authenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
// 认证失败后转发的URL
return new ForwardAuthenticationFailureHandler("/login-error");
}
ExceptionMappingAuthenticationFailureHandler
认证失败中根据发生的异常类型映射到不同的处理逻辑或URL。
java
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
http
// 登录
.formLogin()
// 认证失败后处理器
.failureHandler(authenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
ExceptionMappingAuthenticationFailureHandler handler = new ExceptionMappingAuthenticationFailureHandler();
// 定义异常到URL的映射
Map<String, String> exceptionMappings = new HashMap<>();
exceptionMappings.put(IOException.class.getName(), "/login?error=io");
exceptionMappings.put(RuntimeException.class.getName(), "/login?error=runtime");
// 更多映射...
handler.setExceptionMappings(exceptionMappings);
// 当找不到映射时默认的URL
handler.setDefaultFailureUrl("/login?error=def");
return handler;
}
DelegatingAuthenticationFailureHandler
认证过程中发生的异常来委派给不同的 AuthenticationFailureHandler 实现。
java
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
http
// 登录
.formLogin()
// 认证失败后处理器
.failureHandler(authenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
LinkedHashMap<Class<? extends AuthenticationException>, AuthenticationFailureHandler> failureHandlers = new LinkedHashMap<>();
// 使用重定向
failureHandlers.put(BadCredentialsException.class, new SimpleUrlAuthenticationFailureHandler("/login?error=bad_credentials"));
// 使用转发
failureHandlers.put(LockedException.class, new ForwardAuthenticationFailureHandler("/login-error"));
// 更多映射...
return new DelegatingAuthenticationFailureHandler(
failureHandlers,
// 默认策略
new SimpleUrlAuthenticationFailureHandler("/login?error=def"));
}
自定义使用
java
package com.security.handler.auth;
import com.alibaba.fastjson2.JSON;
import com.security.controller.vo.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Slf4j
public class AuthenticationFailureHandlerImpl implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
log.info("AuthenticationFailureHandlerImpl 登录认证失败时调用 ...");
/**
* 设置响应状态值
*/
response.setStatus(402);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
String json = JSON.toJSONString(
ResponseResult.builder()
.code(402)
.message("认证失败!")
.build());
// JSON信息
response.getWriter().println(json);
}
}
SecurityConfiguration 配置
java
package com.security.config;
import com.security.handler.auth.AuthenticationFailureHandlerImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.web.cors.CorsConfiguration;
@Configuration
@EnableWebSecurity
// 开启限制访问资源所需权限
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfigurationTest extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
http
// 登录
.formLogin()
// 认证失败后处理器
.failureHandler(authenticationFailureHandler());
}
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
// 自定义的失败后的处理器
return new AuthenticationFailureHandlerImpl();
}
}
End