认证鉴权框架SpringSecurity-1--概念和原理篇
1、基本概念
Spring Security 是一个强大且高度可定制的框架,用于构建安全的 Java 应用程序。它是 Spring 生态系统的一部分,提供了全面的安全解决方案,包括认证、授权、CSRF防护、会话管理等功能。
2、认证、授权和鉴权
(1)、认证
认证是判断一个用户的身份是否合法的过程。用户去访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问,不合法则拒绝访问。常见的用户身份认证方式有:用户名密码登录,二维码登录,手机短信登录,指纹认证等方式。
(2)、授权
授权是对系统中的用户赋予资源访问权限的过程,通常分为菜单权限,静态资源权限,接口权限等。
(3)、鉴权
授权是用户认证通过后,根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则正常访问,没有权限则拒绝访问。
3、实现原理
SpringSecurity通过实现一组过滤器来完成安全工作。这些过滤器按顺序处理请求。每个过滤器负责特定的安全任务。这里先简单阐述下主要工作流程,过滤器链在后面会详细描述。
(1)、经典web请求过滤器链
当客户端向服务端发起请求后,容器根据请求 URI 的路径和过滤器相关配置自动创建一个 FilterChain,其中包含过滤器实例和处理 HttpServletRequest 的 Servlet。类似如下图:

当过滤器执行放行后,才会进入到下一个过滤器中,所以调用每个 Filter 的顺序非常重要。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {// 进入servelt前,执行chain.doFilter(request, response); // 执行完servlet后,返回客户端时执行
}
(2)、spring加入过滤器链
当我们使用spring框架时,通过spring也可以加入自定义过滤器,那么spring是怎么做的呢?
答案是:
Spring 提供了一个名为 DelegatingFilterProxy 的过滤器代理类添加到了web请求的过滤器链中(DelegatingFilterProxy 就是一个过滤器)。在这个过滤器中spring做了以下事情:
1、获取到了自身spring容器内的所有Filter的实例(自定义的Filter也是作为Bean被spring容器管理)
2、依次执行了这些过滤器,直到全部执行完成后才放行到web过滤器链中的下一个过滤器或servlet中,这样spring自身的过滤器就都生效了。

DelegatingFilterProxy 代码示例如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {// 获取spring容器的所有过滤器BeanFilter delegate = getFilterBean(someBeanName);// 执行过滤器Beandelegate.doFilter(request, response);
}
(3)、springSecurity加入过滤器链
上面我们说了spring通过DelegatingFilterProxy代理过滤器成功加入到web过滤器链中。
springSecurity作为spring家族的一员,自身封装了一组过滤器链的实例(用于认证和授权)。
在DelegatingFilterProxy有一个属性Bean叫FilterChainProxy ,FilterChainProxy 是 Spring Security 提供的一个特殊过滤器,它允许通过 SecurityFilterChain 向多个过滤器实例委托。

FilterChainProxy在DelegatingFilterProxy中封装获取。看下DelegatingFilterProxy源码,如下所示,这里的delegate实际上就是FilterChainProxy对象,
public class DelegatingFilterProxy extends GenericFilterBean {@Nullableprivate String contextAttribute;@Nullableprivate WebApplicationContext webApplicationContext;@Nullableprivate String targetBeanName;private boolean targetFilterLifecycle;@Nullableprivate volatile Filter delegate; // FilterChainProxy就在这里private final Object delegateMonitor;//省略...
}
再看下FilterChainProxy 源码,发现其中就包含一组过滤器链SecurityFilterChain对象。就是这里,springSecurityFilterChain就上场了。
public class FilterChainProxy extends GenericFilterBean {private static final Log logger = LogFactory.getLog(FilterChainProxy.class);private final static String FILTER_APPLIED = FilterChainProxy.class.getName().concat(".APPLIED");private List<SecurityFilterChain> filterChains; // SecurityFilterChain 对象列表//省略...
}

FilterChainProxy 中List 来确定应该为当前请求调用哪一个 SpringSecurityFilterChain 实例。在选择过滤器链时,在FilterChainProxy 中是这样做的:
逻辑:
1、SecurityFilterChain(接口) -> DefaultSecurityFilterChain(实现类),里面有一个getFilters方法,这里就会根据请求返回了一组过滤器 。
2、RequestMatcher接口用来支持匹配HttpServletRequest的策略。匹配策略有很多,此处不多介绍。
3、RequestMatcher -> AntPathRequestMatcher(实现),servlet通过url路径进行匹配 。
private List<Filter> getFilters(HttpServletRequest request) {for (SecurityFilterChain chain : filterChains) {if (chain.matches(request)) { // 根据请求类型选择出不同过滤器链return chain.getFilters();}}return null;}
(4)、异常处理机制
概述:
SpringSecurity的过滤器链中,有一个ExceptionTranslationFilter,这个过滤器会捕获所有与安全相关的异常,并根据异常类型进行相应的处理。常见的安全异常包括:
AuthenticationException:表示认证失败。
AccessDeniedException:表示授权失败,即用户没有权限访问某个资源。
如果是AuthenticationException:
第一步:首先清除 SecurityContextHolder,这个是一个 Spring Security 中的一个核心类。
第二步:RequestCache:保存 HttpServletRequest 请求,在身份验证成功后可以使用它重复原始请求。//也可以不保存,那么用户就需要重新去请求
第三步、AuthenticationEntryPoint 用于从客户端获取请求凭据。// 它可能重定向到登录页面或发送 WWW-Authenticate 报文头。
如果是AccessDeniedException
则拒绝访问。直接调用 AccessDeniedHandler 来处理拒绝访问。// AccessDeniedHandler(接口),也可以自定义处理策略

这里看下ExceptionTranslationFilter的伪代码如下:
如果没有发生任何异常,ExceptionTranslationFilter过滤器直接放行到之后的过滤器;如果发生了安全异常,会根据异常类型走不同的方法,如认证异常(一般重新跳转登录页);如果是权限异常(提示相关的拒绝信息)
try {filterChain.doFilter(request, response);
} catch (AccessDeniedException | AuthenticationException ex) { //捕获特定异常if (!authenticated || ex instanceof AuthenticationException) {startAuthentication(); //启动认证流程} else {accessDenied(); //决绝策略}
}
(5)、原理总结
1、spring通过将DelegatingFilterProxy过滤器链加入到web请求过滤器链中。
2、DelegatingFilterProxy中封装了FilterChainProxy过滤器对象(springSecurity入口)
3、FilterChainProxy中封装了List过滤器链对象。
4、List初始过程会调用getFilters方法获取到目标过滤器链(策略是根据Request对象的URL)
5、之后会遍历执行List过滤器链,执行里面的每一个过滤器,完成认证或授权等过程。
6、如果出现安全异常,ExceptionTranslationFilter中会根据异常的类型走对应的异常处理方法。

学海无涯苦作舟!!!
相关文章:
认证鉴权框架SpringSecurity-1--概念和原理篇
1、基本概念 Spring Security 是一个强大且高度可定制的框架,用于构建安全的 Java 应用程序。它是 Spring 生态系统的一部分,提供了全面的安全解决方案,包括认证、授权、CSRF防护、会话管理等功能。 2、认证、授权和鉴权 (1&am…...
计算器上的MC、MR、M+、M—、CE是什么意思?
在计算器中, MC键叫做memory clear,中文 清除存储,是一个清除寄存器中存储数字的指令。 MS键叫做memory save,中文 存入存储。 而MR键,则是一个读取原先存储在寄存器中的数字的指令。 M键指将当前数值存入寄存器以…...
无人机飞手执照处处需要,森林、石油管道、电力巡检等各行业都需要
无人机飞手执照在多个行业中确实具有广泛的应用需求,包括森林、石油管道、电力巡检等领域。以下是对这些领域无人机飞手执照需求的具体分析: 一、森林领域 在森林领域,无人机飞手执照对于进行高效、准确的森林资源管理和监测至关重要。无人机…...
计算机网络——路由选择算法
路由算法 路由的计算都是以子网为单位计算的——找到从原子网到目标子网的路径 链路状态算法...
【前端】技术演进发展简史
一、前端 1、概述 1990 年,第一个web浏览器诞生,Tim 以超文本语言 HTML 为基础在 NeXT 电脑上发明了最原始的 Web 浏览器。 1991 年,WWW诞生,这标志着前端技术的开始。 前端(Front-end)和后端(…...
深入解析贪心算法及其应用实例
标题:深入解析贪心算法及其应用实例 一、引言 贪心算法(Greedy Algorithm)是一类简单、直观的算法设计策略,广泛应用于优化问题中。其基本思想是每一步都选择当前状态下最优的选择,即在每一步做出局部最优的决策&…...
电子工牌独立双通道定向拾音方案(有视频演示)
现在一些行业的客服人员在面对客户都要求使用电子工牌分别记录客服和顾客的声音,我们利用双麦克风阵列双波束拾音的方案设计了一个电子工牌方案.可以有效分别记录客服和顾客的声音. 方案思路: 我们采用了一个双麦阵列波束拾音的模块A-59,此模块可以利用2个麦克风组成阵列进行双…...
举例理解LSM-Tree,LSM-Tree和B+Tree的比较
写操作 write1:WAL 把操作同步到磁盘中WAL做备份(追加写、性能极高) write2:Memtable 完成WAL后将(k,v)数据写入内存中的Memtable,Memtable的数据结构一般是跳表或者红黑树 内存内采用这种数据结构一方面支持内存…...
React Native 全栈开发实战班 - 核心组件与导航
在 React Native 中,组件是构建用户界面的基本单元。React Native 提供了丰富的内置组件,涵盖了从基础布局到复杂交互的各种需求。本章节将详细介绍常用的内置组件,并重点讲解列表与滚动视图的使用。 1. 常用内置组件详解 React Native 提供…...
Leecode热题100-35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2示例 2: 输入:…...
密码学知识点整理二:常见的加密算法
常用的加密算法包括对称加密算法、非对称加密算法和散列算法。 对称加密算法 AES:高级加密标准,是目前使用最广泛的对称加密算法之一,支持多种密钥长度(128位、192位、256位),安全性高,加密效率…...
Linux如何将文件或目录打成rpm包?-- rpmbuild打包详解
👨🎓博主简介 🏅CSDN博客专家 🏅云计算领域优质创作者 🏅华为云开发者社区专家博主 🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入!…...
RabbitMQ-死信队列(golang)
1、概念 死信(Dead Letter),字面上可以理解为未被消费者成功消费的信息,正常来说,生产者将消息放入到队列中,消费者从队列获取消息,并进行处理,但是由于某种原因,队列中的…...
爬虫开发工具与环境搭建——环境配置
第二章:爬虫开发工具与环境搭建 第二节:环境配置 在进行爬虫开发之前,首先需要配置好开发环境。一个良好的开发环境不仅能提高开发效率,还能避免因环境不一致带来的问题。以下是环境配置的详细步骤,涵盖了Python开发…...
15.UE5等级、经验、血条,魔法恢复和消耗制作
2-17 等级、经验、血条、魔法消耗_哔哩哔哩_bilibili 目录 1.制作UI,等级,经验,血条 2.为属性面板绑定角色真实的属性,实现动态更新 3.魔法的消耗和恢复 1.制作UI,等级,经验,血条 创建控…...
【Homework】【5】Learning resources for DQ Robotics in MATLAB
Lesson 5 代码-TwoDofPlanarRobot.m 表示一个 2 自由度平面机器人。该类包含构造函数、计算正向运动学模型的函数、计算平移雅可比矩阵的函数,以及在二维空间中绘制机器人的函数。 classdef TwoDofPlanarRobot%TwoDofPlanarRobot - 表示一个 2 自由度平面机器人类…...
vue3中 ref和reactive的区别
ref的主要作用 ref 函数接受的参数数据类型可以是原始数据类型也可以是引用数据类型。在模板中使用 ref 时,我们不需要加 .value,因为当 ref 在模板中作为顶层属性被访问时,它们会被自动解包, <p>count: {{ count }}</…...
第十四章 Spring之假如让你来写AOP——雏形篇
Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…...
群控系统服务端开发模式-应用开发-前端个人资料开发
一、总结 其实程序开发到现在,简单的后端框架就只剩下获取登录账号信息及获取登录账号菜单这两个功能咯。详细见下图: 1、未登录时总业务流程图 2、登录后总业务流程图 二、获取登录账号信息对接 在根目录下src文件夹下store文件夹下modules文件夹下的us…...
动态规划技巧点
动规五部曲(来自b站卡哥):1、确定DP数组中i、j…的含义。2、确定DP推导式。3、DP数组初始化。4、DP数组遍历顺序。5、DP数组打印校验。 父问题、子问题有些许区别:LeetCode343.整数拆分 今天在哔哩哔哩上刷到了一个非常有意思的l…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
