【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

相关推荐
一只叫煤球的猫6 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9657 小时前
tcp/ip 中的多路复用
后端
bobz9657 小时前
tls ingress 简单记录
后端
皮皮林5518 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友8 小时前
什么是OpenSSL
后端·安全·程序员
bobz9658 小时前
mcp 直接操作浏览器
后端
前端小张同学11 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook11 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康12 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在12 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net