【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

相关推荐
wangchunyu1141 小时前
JAVA CompletableFuture异步编程实战
java·开发语言·python
paopaokaka_luck2 小时前
流浪动物救助与收养系统(DeepSeek AI对话、 ECharts多维分析、救助流程衔接、领养与回访衔接、 捐赠确认与公示、志愿者协作)
java·前端·javascript·人工智能·mysql·echarts·推荐算法
Thomas.Sir2 小时前
第9课:SpringBoot4.x Web开发基础:WebMvc自动配置、静态资源、请求参数接收
java·spring boot
程序 代码狂人2 小时前
切片表与分区表的区别(数据开发面试版)
java·大数据·开发语言·数据仓库·算法
m0_639906943 小时前
Linux 操作系统入门:目录结构、服务排查常用命令、Shell 脚本基础
linux·运维·后端
2501_944521593 小时前
Deepmerge 跨端三方库仓颉适配全流程
java·python·eclipse·github
holly就是我3 小时前
AI 编程助手为什么跑偏?用开源 ccglass 看清 Prompt、工具调用和 Token 消耗
人工智能·后端
鸿蒙开发3 小时前
共享 Schema 与 SchemaFactory
前端·后端·harmonyos
用户788477316343 小时前
小程序后端三选一:云开发、.NET WebAPI、Node,我按客户现状分了三种答案
后端
aiopencode3 小时前
局域网设备抓包怎么做?用 TraceEagle 抓电视、游戏机和 IoT 流量
后端·ios