【Spring Security】AuthenticationFailureHandler 用户认证失败后处理

文章目录

前言

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

相关推荐
考虑考虑1 小时前
cmd局部设置java变量
运维·后端·自动化运维
benbenAItalk1 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
sunshine22 girl1 小时前
Java学习二 基本语法2, 算术运算符
java·学习
niucloud-admin1 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
2601_962885721 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
滕州市燕猫虎计算机科技工作室个体工商户2 小时前
Java锁
java·开发语言
shehuiyuelaiyuehao4 小时前
1计算机是如何工作的
java·计算机网络
陈随易4 小时前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
letisgo54 小时前
JAVA 高级进阶07篇《@Transactional失效的8个场景:代理机制到传播行为》
java·面试·transactional·spring事务·aop动态代理
水域安全老周4 小时前
水趣钓鱼救生衣专利拆解:两级锁紧如何解决落水人衣分离
java·前端·网络