当前位置: 首页 > article >正文

Spring Security 认证流程——补充

一、认证流程概述

Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilterAuthenticationManagerUserDetailsService 等。整个流程可分为以下步骤:

  1. 用户提交登录请求
  2. 拦截请求并封装认证对象
  3. 认证管理器(AuthenticationManager)处理认证
  4. 认证成功或失败的处理
  5. 安全上下文存储与后续处理

二、详细步骤解析

1. 用户提交登录请求

  • 用户通过表单提交用户名和密码(如访问 /login 路径)。
  • 请求由 UsernamePasswordAuthenticationFilter 拦截(默认处理 /login 请求)。

2. 拦截请求并封装认证对象

  • UsernamePasswordAuthenticationFilter 的作用
    • 从请求中提取用户名和密码。
    • 创建 UsernamePasswordAuthenticationToken 对象(未认证的 Authentication 实例)。
    • 示例代码:
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {String username = obtainUsername(request); // 提取用户名String password = obtainPassword(request); // 提取密码UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);return this.getAuthenticationManager().authenticate(authRequest); // 调用认证管理器}
}

3. 认证管理器(AuthenticationManager)处理认证

  • AuthenticationManager 的职责
    • 协调认证流程,调用 AuthenticationProvider 进行具体认证。
    • 默认实现是 ProviderManager,其内部维护一个 AuthenticationProvider 列表。
  • DaoAuthenticationProvider 的角色
    • 负责从数据源加载用户信息(通过 UserDetailsService)。
    • 对比用户输入的密码与数据库中存储的密码(通过 PasswordEncoder)。
    • 示例代码:
public class DaoAuthenticationProvider implements AuthenticationProvider {@Overridepublic Authentication authenticate(Authentication authentication) {String username = authentication.getName();UserDetails userDetails = userDetailsService.loadUserByUsername(username); // 加载用户信息if (passwordEncoder.matches(authentication.getCredentials().toString(), userDetails.getPassword())) {return new UsernamePasswordAuthenticationToken(userDetails, authentication.getCredentials(), userDetails.getAuthorities());} else {throw new BadCredentialsException("密码错误");}}
}

4. 认证成功或失败的处理

  • 认证成功

    • AuthenticationManager 返回已认证的 Authentication 对象。
    • UsernamePasswordAuthenticationFilter 将该对象存入 SecurityContextHolder(通过 SecurityContext)。
    • 触发 AuthenticationSuccessHandler(如跳转到首页或返回 JWT 令牌)。
    • 示例代码:
public class UsernamePasswordAuthenticationFilter {private AuthenticationSuccessHandler successHandler;protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) {SecurityContextHolder.getContext().setAuthentication(authResult); // 存储认证信息successHandler.onAuthenticationSuccess(request, response, authResult); // 调用成功处理器}
}

认证失败

  • AuthenticationManager 抛出 AuthenticationException 异常。
  • UsernamePasswordAuthenticationFilter 调用 AuthenticationFailureHandler(如返回错误信息或重定向到登录页面)。
  • 示例代码:
public class UsernamePasswordAuthenticationFilter {private AuthenticationFailureHandler failureHandler;protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {failureHandler.onAuthenticationFailure(request, response, failed); // 调用失败处理器}
}

5. 安全上下文存储与后续处理

  • SecurityContextPersistenceFilter 的作用
    • 在请求开始时,从 SecurityContextRepository(默认是 HttpSessionSecurityContextRepository)加载 SecurityContext 到当前线程。
    • 在请求结束时,将 SecurityContext 保存回 SecurityContextRepository 并清空线程中的上下文。
    • 示例代码:
public class SecurityContextPersistenceFilter implements Filter {public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {HttpServletRequest request = (HttpServletRequest) req;HttpSession session = request.getSession(false);SecurityContext context = session != null ? (SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT") : null;SecurityContextHolder.setContext(context); // 加载上下文try {chain.doFilter(req, res);} finally {session = ((HttpServletRequest) req).getSession(false);session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext()); // 保存上下文SecurityContextHolder.clearContext(); // 清空线程上下文}}
}

三、关键组件与接口

组件/接口职责
Authentication封装用户凭证(如用户名、密码)和权限信息。
AuthenticationManager认证入口,协调多个 AuthenticationProvider
AuthenticationProvider具体认证逻辑的实现者(如 DaoAuthenticationProvider)。
UserDetailsService从数据源加载用户信息(如数据库),返回 UserDetails 对象。
PasswordEncoder加密和校验密码(如 BCryptPasswordEncoder)。
SecurityContext存储当前用户的认证信息(通过 SecurityContextHolder 与线程绑定)。

四、认证流程图

[用户提交登录请求]↓
[UsernamePasswordAuthenticationFilter 拦截请求]↓
[创建 UsernamePasswordAuthenticationToken(未认证)]↓
[调用 AuthenticationManager.authenticate()]↓
[ProviderManager 遍历 AuthenticationProvider]↓
[DaoAuthenticationProvider 加载用户信息(通过 UserDetailsService)]↓
[PasswordEncoder 校验密码]↓
[认证成功:返回已认证的 Authentication 对象]↓
[SecurityContextHolder 存储 Authentication]↓
[调用 AuthenticationSuccessHandler(如跳转页面或返回 JWT)]

五、自定义认证逻辑

  • 自定义 UserDetailsService

    • 实现 UserDetailsService 接口,从数据库加载用户信息。
    • 示例代码:
@Service
public class CustomUserDetailsService implements UserDetailsService {@Autowiredprivate UserRepository userRepository;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userRepository.findByUsername(username);if (user == null) {throw new UsernameNotFoundException("用户不存在");}return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),AuthorityUtils.createAuthorityList("ROLE_USER") // 返回用户权限);}
}

自定义 PasswordEncoder

  • 使用 BCryptPasswordEncoder 或自定义加密逻辑。
  • 示例代码:
@Bean
public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();
}

六、常见问题与解决方案

  • 密码不匹配

    • 确保 UserDetailsService 返回的密码与数据库中存储的密码格式一致(如已加密)。
    • 检查 PasswordEncoder 配置是否正确。
  • 认证失败无提示

    • 自定义 AuthenticationFailureHandler 处理异常,返回用户友好的错误信息。
  • 多认证方式支持

    • 添加自定义过滤器(如 JWT 认证过滤器),插入到过滤器链中。
    • 示例配置:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);}
}

七、总结

Spring Security 的认证流程通过 过滤器链核心组件协作 实现,关键步骤包括:

  1. 用户提交登录请求,被 UsernamePasswordAuthenticationFilter 拦截。
  2. AuthenticationManager 协调 AuthenticationProvider 进行认证。
  3. UserDetailsService 加载用户信息,PasswordEncoder 校验密码。
  4. 认证结果通过 SecurityContext 存储,并触发成功或失败处理器。

掌握这一流程后,开发者可以灵活配置认证逻辑(如数据库认证、JWT 认证)并扩展安全功能(如动态权限控制)

相关文章:

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...

git: early EOF

macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

离线语音识别方案分析

随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

DBLP数据库是什么?

DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...

c# 局部函数 定义、功能与示例

C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...