Spring Security
Spring Security
spring提供的安全框架。主要提供了认证和授权的功能。简单梳理看看。
原理简单说就是Spring Security在基于Servlet应用中,其底层采用了Filter机制实现了对请求的认证,授权和漏洞防御等功能。
DelegatingFilterProxy
我们知道,Filter是Servlet规范里面的东西。基于Servlet规范,我们可以为ServletR勇气注入一些自定义Filters。
但是在Spring应用中,实现了Filter接口的Bean无法被Servlet容器感知到。因此,Spring提供了一个DelegatingFilterProxy代理类,DelegatingFilterProxy实现了Filter,因此它可以被注入到FilterChain中,同时,当请求到来时,它会把请求转发到Spring容器中实现了Filter接口的Bean实体。也就是说,DelegatingFilterProxy桥接了Servlet容器和Spring容器。
默认情况下,DelegatingFilterProxy从Spring容器中获取得到的就是FilterChainProxy实体,而FilterChainProxy也是一个代理类,它最终会将请求转发到SpringSecurity提供的SecurityFilterChain中。
FilterChainProxy就是Spring Security真正的入口起始点。调试代码的时候,可以将断点设置在FilterChainProxy#doFilter就可以追踪SpringSecurity完整调用流程。
FilterChainProxy
public class FilterChainProxy extends GenericFilterBean {
//FILTER_APPLIED 变量是一个标记,用来标记过滤器是否已经执行过了private static final String FILTER_APPLIED = FilterChainProxy.class.getName().concat(".APPLIED");
//filterChains 是过滤器链,注意,这个是过滤器链,而不是一个个的过滤器private List<SecurityFilterChain> filterChains;
//filterChainValidator 是 FilterChainProxy 配置完成后的校验方法,默认使用的 NullFilterChainValidator 实际上对应了一个空方法,也就是不做任何校验private FilterChainValidator filterChainValidator = new NullFilterChainValidator();//FilterChain为servlet的过滤器链@Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {//为true,表示尚未执行过;false表示,已经标记boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;if (clearContext) {try {request.setAttribute(FILTER_APPLIED, Boolean.TRUE);//执行spring security的过滤器doFilterInternal(request, response, chain);}finally {//清除SecurityContextHolder 中保存的用户信息,同时移除 request 中的标记SecurityContextHolder.clearContext();request.removeAttribute(FILTER_APPLIED);}}else {doFilterInternal(request, response, chain);}
}
在 doFilter 方法中,正常来说,clearContext 参数每次都是 true,于是每次都先给 request 标记上 FILTER_APPLIED 属性,然后执行 doFilterInternal 方法去走过滤器,执行完毕后,最后在 finally 代码块中清除 SecurityContextHolder 中保存的用户信息,同时移除 request 中的标记。
private void doFilterInternal(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {FirewalledRequest fwRequest = firewall.getFirewalledRequest((HttpServletRequest) request);HttpServletResponse fwResponse = firewall.getFirewalledResponse((HttpServletResponse) response);//根据当前request,从FilterChainProxy中配置的多个过滤器链(可以只有一个),找到和当前相匹配的一个securityFilterChain,并获取filtersList<Filter> filters = getFilters(fwRequest);if (filters == null || filters.size() == 0) {if (logger.isDebugEnabled()) {logger.debug(UrlUtils.buildRequestUrl(fwRequest)+ (filters == null ? " has no matching filters": " has an empty filter list"));}fwRequest.reset();//如果filters为null,表示当前请求不需要执行security的过滤器链,直接执行servlet上的过滤器链chain.doFilter(fwRequest, fwResponse);return;}//如果需要执行security的过滤器链,首先构造一个虚拟的过滤器链VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);vfc.doFilter(fwRequest, fwResponse);
}//request匹配到的过滤器链上的所有filters
private List<Filter> getFilters(HttpServletRequest request) {for (SecurityFilterChain chain : filterChains) {if (chain.matches(request)) {return chain.getFilters();}}return null;
}
doFilterInternal 方法就比较重要了:
- 首先将请求封装为一个 FirewalledRequest 对象,在这个封装的过程中,也会判断请求是否合法。
- 对响应进行封装。
- 调用 getFilters 方法找到过滤器链。该方法就是根据当前的请求,从 filterChains 中找到对应的过滤器链,然后由该过滤器链去处理请求。
- 如果找出来的 filters 为 null,或者集合中没有元素,那就是说明当前请求不需要经过过滤器。直接执行 chain.doFilter ,这个就又回到原生过滤器中去了。那么什么时候会发生这种情况呢?那就是针对项目中的静态资源,如果我们配置了资源放行,如 web.ignoring().antMatchers(“/hello”);,那么当你请求 /hello 接口时就会走到这里来,也就是说这个不经过 Spring Security Filter。
- 如果查
相关文章:
Spring Security
Spring Security spring提供的安全框架。主要提供了认证和授权的功能。简单梳理看看。 原理简单说就是Spring Security在基于Servlet应用中,其底层采用了Filter机制实现了对请求的认证,授权和漏洞防御等功能。 DelegatingFilterProxy 我们知道,Filter是Servlet规范里面…...
vue中大屏可视化适配所有屏幕大小
1. 外部盒子 .screenBox {width: 100vw;height: 100vh;background: url("/assets/images/bg.png") no-repeat;background-size: cover; }2.比例盒子 外层盒子css定义 .boxScale {width: 1920px;height: 1080px;background-color: orange;transform-origin: left top;…...
AI大模型探索之路-实战篇12: 构建互动式Agent智能数据分析平台:实现多轮对话控制
系列篇章💥 AI大模型探索之路-实战篇4:深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5:探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6:掌握Function Calling的详细流程 AI大模型探索之路-实战篇7…...
深入理解文件系统和日志分析
文件是存储在硬盘上的,硬盘上的最小存储单位是扇区,每个扇区的大小是512字节。 inode:存储元信息(包括文件的属性,权限,创建者,创建日期等等) block:块,连续…...
vue+vant移动端显示table表格加横向滚动条
vant移动端显示table效果,增加复选框,可以进行多选和全选。加横向滚动条,可以看全部内容。 <template><div class"app-container"><div class"nav_text" style"position: relative;"><…...
webserver服务器从零搭建到上线(八)|EpollPoller事件分发器类
文章目录 EpollPoller事件分发器类成员变量和成员函数解释私有的成员函数和成员变量成员函数 具体实现常量的作用构造函数和析构函数⭐️poll函数updateChannel函数removeChannel 函数removeChannel 和updateChannel⭐️fillActiveChannels 函数⭐️update 函数 总结 终于要开始…...
SD-WAN:企业网络转型的必然趋势
随着SD-WAN技术的不断进步和完善,越来越多的企业选择利用SD-WAN进行网络转型。根据IDC的研究,47%的企业已经成功迁移到SD-WAN,另有48%的公司计划在未来两个月内部署这一技术。 据Channel Futures报道,一位合作伙伴透露,…...
构建高效稳定的短视频直播系统架构
随着短视频直播的迅猛发展,构建一个高效稳定的短视频直播系统架构成为了互联网企业的重要挑战。本文将探讨如何构建高效稳定的短视频直播系统架构,以提供优质的用户体验和满足日益增长的用户需求。 ### 1. 短视频直播系统的背景 短视频直播近年来蓬勃发…...
python分别保存聚类分析结果+KeyError: ‘CustomerID‘报错
如何在完成聚类分析后按聚类编号保存数据并且带上原数据所属ID # 将每个聚类的数据保存到不同的文件中 for cluster_id in range(6): # 假设共有6个聚类cluster_data data[data[cluster] cluster_id]cluster_data_with_customer_id cluster_data.copy()cluster_data_with_…...
Sui与Atoma合作为开发者提供AI支持
AI初创公司Atoma宣布其即将推出的推理网络将与Sui集成,该网络将使开发者能够在他们的应用程序中使用AI工具。Atoma选择Sui作为其第一个区块链集成对象是由于Sui的可扩展性和性能。 尽管生成式AI在过去几年中引起了轰动,但它尚未进入许多消费者应用程序。…...
go-gin中session实现redis前缀和db库选择+单点登录
分别实现了redigo中自动加前缀和session中自动加前缀 等有空了整理一个demo放到github上,到时候求个小星星 在gin-contrib/sessions/redis库中redis的前缀是被封装起来了,所以自定义前缀没有内部方法在这里我们自己实现一下NewStoreWithDBPrefix方法配…...
python-双胞胎字符串
[问题描述]:给定两个字符串s和t,每次可以任意交换s的奇数位和偶数位的字符,即奇数位的字符可以与任意其它奇数位的字符交换,偶数位的字符同样也可以与任意偶数位的字符的字符交换,问能否在有限的次数的交换下使s变为t?…...
万字长文,小白新手怎么开始做YOLO实验,从零开始教!整体思路在这里,科研指南针!
最近专栏来了很多的新手小白,对科研实验的过程感到困惑和无从下手,这篇文章就来讲解一下整体的科研流程,从选择数据集到发表论文的各个步骤,并针对大家在实验中常犯的错误进行解答。并且为大家提供通向我其他相关博客的指引&#…...
MDR-1A用什么前端:深度解析与实用指南
MDR-1A用什么前端:深度解析与实用指南 索尼MDR-1A作为一款备受瞩目的音乐耳机,其音质表现与前端设备的搭配息息相关。那么,MDR-1A用什么前端才能达到最佳的音效体验呢?本文将从四个方面、五个方面、六个方面和七个方面进行深入探…...
01Linux以及操作系统概述
课程目标 1.了解现代操作系统的整体构成及发展历史 2.了解Linux操作系统及其分支版本 3.直观上理解服务器端与桌面端版本的区别 课程实验 1.通过对CentOS和Ubuntu的演示,直观理解Linux与Windows的异同 课堂引入 本章内容主要为大家详细讲解Linux操作系统(以下简…...
华为OD刷题C卷 - 每日刷题 1
1、(两数之和): 这段代码是针对力扣(LeetCode)上的“两数之和”问题。它提供了一个Java类Solution,其中包含一个方法twoSum,该方法接收一个整数数组nums和一个整数目标值target。目的是找出数组…...
基于ELK的日志管理【开发实践】
文章目录 一、ELK简介1.1 ELK的作用与应用1.2 ELK的组成1.3 Elasticsearch1.4 Logstash1.5 Kibana1.6 ELK架构简述1.7 基础知识1.7.1 数据格式1.7.2 正排索引和倒排索引1.7.3 全文搜索 二、ES入门---基于HTTP的使用方式(了解)2.1 索引操作2.1.1 创建索引…...
音视频开发—音频相关概念:数模转换、PCM数据与WAV文件详解
文章目录 前言1.模拟数字转换(ADC)1.1ADC的关键步骤: 2.数字模拟转换(DAC)2.1DAC 的基本流程包括: 3.PCM数据3.1PCM 数据的关键要素包括: 4.WAV文件4.1 WAV的构成4.2WAV文件的标准块结构4.3WAV的…...
Elasticsearch 8.1官网文档梳理 - 十三、Search your data(数据搜索)
Search your data 这里有两个比较有用的参数需要注意一下 Search timeout:设置每个分片的搜索超时时间。从集群级别可以通过 search.default_search_timeout 来设置超时时间。如果在 search.default_search_timeout 设置的时间段内未完成搜索请求,就会…...
笔墨挥毫如游龙 最是经典铁线篆——记著名书法家王子彬
真正的书法大家,必是经历了日积月累的求索磨炼,毕竟书法从来都不是一蹴而就的艺术,因此但凡是急功近利者,其人也是远远无法达到书入臻境的创作高度。而纵观当代书坛界内,其中王子彬先生的艺术声誉可谓是广为人知,作为一名深具传统功底的实力派书法大家,王子彬先生的取法历途无疑…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
