spring 用户通过交互界面登录成功事件源码分析

版本

spring-security-web:5.6.7

源码

用户通过前端交互界面登录成功触发此事件

org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent

事件触发过程

  • 用户名密码认证过滤器
    org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
java 复制代码
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter 
  • 认证处理过滤器
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter
java 复制代码
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
	throws IOException, ServletException {
	if (!requiresAuthentication(request, response)) {
		chain.doFilter(request, response);
		return;
	}
	try {
		// 尝试对请求进行认证
		Authentication authenticationResult = attemptAuthentication(request, response);
		if (authenticationResult == null) {
			return;
		}
		this.sessionStrategy.onAuthentication(authenticationResult, request, response);
		// 认证成功
		if (this.continueChainBeforeSuccessfulAuthentication) {
			chain.doFilter(request, response);
		}
		successfulAuthentication(request, response, chain, authenticationResult);
	}
	catch (InternalAuthenticationServiceException failed) {
		this.logger.error("An internal error occurred while trying to authenticate the user.", failed);
		unsuccessfulAuthentication(request, response, failed);
	}
	catch (AuthenticationException ex) {
		// Authentication failed
		unsuccessfulAuthentication(request, response, ex);
	}
}
// 默认的认证成功处理行为
// 1. 将认证对象设置到安全上下文
// 2. 通知RememberMe服务
// 3. 发布交互认证成功事件
// 4. 执行成功处理器
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
	Authentication authResult) throws IOException, ServletException {
	SecurityContext context = SecurityContextHolder.createEmptyContext();
	context.setAuthentication(authResult);
	SecurityContextHolder.setContext(context);
	if (this.logger.isDebugEnabled()) {
		this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authResult));
	}
	this.rememberMeServices.loginSuccess(request, response, authResult);
	if (this.eventPublisher != null) {
		this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
	}
	this.successHandler.onAuthenticationSuccess(request, response, authResult);
}
相关推荐
非优秀程序员8 小时前
第07章 孙德良的阳谋|《互联网产品恩仇录》
javascript·后端
非优秀程序员8 小时前
第06章 浙江帮的内战|《互联网产品恩仇录》
后端
非优秀程序员8 小时前
第08章 马云的反击|《互联网产品恩仇录》
后端
非优秀程序员8 小时前
题记|《互联网产品恩仇录》
后端·程序员·创业
非优秀程序员8 小时前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻9 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
文丑颜不良啊11 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang12 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
Gopher_HBo12 小时前
Go CPU 剖析的"地基":信号、CAS、写屏障、无锁环形缓冲
后端
panbook12 小时前
从0到1实现一个分布式时序数据库(二):写入成功之后,如何用 WAL 找回数据
后端