【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

相关推荐
WaaTong1 分钟前
Java反射
java·开发语言·反射
齐 飞25 分钟前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
九圣残炎34 分钟前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge36 分钟前
Netty篇(入门编程)
java·linux·服务器
LunarCod42 分钟前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
成富1 小时前
文本转SQL(Text-to-SQL),场景介绍与 Spring AI 实现
数据库·人工智能·sql·spring·oracle
Re.不晚1 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐1 小时前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。1 小时前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野1 小时前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java