SpringSecurity安全过滤器工作原理

前面通过三篇文章,从底层代码的角度分析了SpringSecurity的初始化过程。

接下来我们就要具体看一下,Spring Security的安全过滤器初始化、装配好之后,到底是怎么工作的。

还是按图索骥


 

下面我们简单从底层源码分析一下,请求是怎么调用到Spring Security的安全过滤器的。
#### Spring Security安全过滤器工作原理
前面文章已经分析过DelegatinFilterProxy调用到FilterChainProxy的源码,所以我们今天直接从FilterChainProxy的doFilter方法开始:
```
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
        if (!clearContext) {
            doFilterInternal(request, response, chain);
            return;
        }
        try {
            request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
            doFilterInternal(request, response, chain);
        }
        catch (RequestRejectedException ex) {
            this.requestRejectedHandler.handle((HttpServletRequest) request, (HttpServletResponse) response, ex);
        }
        finally {
            SecurityContextHolder.clearContext();
            request.removeAttribute(FILTER_APPLIED);
        }
    }
```

直接看doInternalFilter方法。首先调用getFilters方法:
```
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        FirewalledRequest firewallRequest = this.firewall.getFirewalledRequest((HttpServletRequest) request);
        HttpServletResponse firewallResponse = this.firewall.getFirewalledResponse((HttpServletResponse) response);
        List<Filter> filters = getFilters(firewallRequest);
        //省略部分源码
        VirtualFilterChain virtualFilterChain = new VirtualFilterChain(firewallRequest, chain, filters);
        virtualFilterChain.doFilter(firewallRequest, firewallResponse);
    }
```
这个getFilters方法的源码就不贴出了,有兴趣的童鞋打开源码看一下,非常简单:从FilterChainProxy持有的DefaultSecurityFilterChain对象中获取到filters,这个filters就是Spring Security初始化过程中装配好的Spring Security的各安全过滤器。

之后用安全过滤器组装一个叫virtualFilterChain的内部对象,这个内部对象主要就是为了持有Spring Security的安全过滤器的,然后通过调用virtualFilterChain的doFilter方法,逐个调用Spring Security的安全过滤器。
#### Spring Security安全过滤器
Spring Security有不少安全过滤器(下图,SprigBoot默认启动的就有15个),我们主要关注与用户身份认证及鉴权密切相关的、或者项目中比较常见的过滤器,其他过滤器暂时略过或一笔带过。
![image.png](/img/bVc4txS)

#### 1.WebAsyncManagerIntegrationFilter
web异步集成过滤器,创建SecurityContextCallableProcessingInterceptor并注册到WebAsyncManager中。

详细作用略。

#### 2.SecurityContextPersistenceFilter
将包含认证信息的SecurityContextHolder在认证之后保存起来(保存在SecurityContextRepository中,一般情况下是session),并且在每次请求发起、认证发生之前从SecurityContextRepository获取出来放置到SecurityContextHolder中。

SecurityContextPersistenceFilter是Spring Security的第2个安全过滤器,在所有认证过滤器之前执行。

SecurityContextPersistenceFilter首先从session中(默认情况下)获取SecurityContext,如果session中没有SecurityContext则创建一个空的SecurityContext,之后将SecurityContext存入SecurityContextHolder。

默认情况下SecurityContextHolder通过ThreadLocalSecurityContextHolderStrategy(也就是使用ThreadLocal)存储SecurityContext。

最后,在请求执行完成之后,将SecurityContextHolder持有的SecurityContext保存起来(默认存储在session中),并清空SecurityContextHolder。

***这样,通过SecurityContextPersistenceFilter过滤器,Spring Security就可以在其他安全过滤器执行之前,从session中获取当前用户的认证信息,因而在后续用户认证操作执行之前、如果当前用户已经完成了认证、则可以确保能够获取到当前用户的认证信息,因此能够通过后续的用户认证过程!!!***

#### 3.HeaderWirterFilter
写Response头信息以便达到对Http Response的相应控制。

HeaderWirterFilter初始化的时候会注册如下HeadWriter:
![image.png](/img/bVc4MXi)
这些HeadWriter会帮助我们对Http Response Header做一些默认设置,比如CacheControlHeadersWriter会执行如下操作:

```
    private static List<Header> createHeaders() {
        List<Header> headers = new ArrayList<>(3);
        headers.add(new Header(CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"));
        headers.add(new Header(PRAGMA, "no-cache"));
        headers.add(new Header(EXPIRES, "0"));
        return headers;
    }
```
一般情况下,我们的应用需要这样的设置,不使用Spring Security的话我们的应用需要手动设置,使用了Spring Security的话,就不需要多此一举了。

#### 4.CsrfFilter
跨域请求过滤器,主要作用是防跨域攻击。

#### 5.LogoutFilter
处理Logout请求,并导航到logout页面。

#### 6.UsernamePasswordAuthenticationFilter
这是Spring Security用户认证的默认实现。

![image.png](/img/bVc4S1M)

他有一个叫AbstractAuthenticationProcessingFilter的父类,doFilter方法就是在父类实现的。

只针对post方法的/login请求生效,所以如果我们要使用该过滤器的话,应用的登录必须是post方法的/login请求。

Spring Security的登录认证过程就是通过这个过滤器实现的,相对还比较复杂,篇幅关系今天就不展开了,今天的主要目标是要搞清楚他的作用。

首先验证当前请求是否需要登录认证,如前所述,如果请求不是post的/login的话,则不做登录认证。

从request中获取的username,password创建UsernamePasswordAuthenticationToken对象进行认证。

认证的过程其实就是我们验证用户名、密码的过程,SpringSecurity有一个默认的用户名、密码认证实现,是在系统启动过程中为用户user生成UUID并打印在控制台、通过用户名user、密码为该UUID完成认证。我们可以实现自己的认证,比如通过数据库的用户名、密码方式完成认证。

认证通过则将认证信息存储在SecurityContext中,如果认证失败(比如用户名密码错误等)则清空SecurityContext并记录相关异常。

#### 7.DefaultLoginPageGeneratingFilter
为/login请求生成登录页面。

#### 8.DefaultLogoutPageGeneratingFilter
导航到登出页面。

#### 9.BasicAuthenticationFilter
对于采用Basic Authentication的请求执行认证。Basi Authentication指的是请求头中包含:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

其中Basic后是采用base64编码的密码信息。

不太了解、没有使用过这种认证方式,略过。

#### 10.RequestCacheAwareFilter
主要作用是缓存当前请求信息,以便在由于认证未通过无法执行该请求的情况下,后续认证通过后重新发起该请求。

#### 11.SecurityContextHolderAwareRequestFilter
用于对request做一层包装,以便支持Servlet中安全相关的API调用。

#### 12.AnonymousAuthenticationFilter
匿名过滤器,从SecurityContextHolder获取认证信息,如果经过了前面的SecurityContextPersistenceFilter、以及UsernamePasswordAuthenticationFilter处理后,SecurityContextHolder中还是没有认证信息的话,说明当前请求并没有通过Spring Security的安全认证,则创建一个匿名认证信息存储在SecurityContextHolder中。

#### 13.SessionManagementFilter
session管理的过滤器,主要为了防止session固化攻击、以及实现登录并发控制功能。

#### 14.ExceptionTranslationFilter
实现异常控制的安全过滤器,注意该过滤器对异常的处理是安全过滤器链执行完成、返回之后。所以,下面的第14个、第15个过滤器执行过程中的异常,也能被本过滤器捕获并处理。

主要处理Spring Security的两类异常:
1. AuthenticationException
2. AccessDeniedException
并将异常交给相应的异常处理器进行处理,比如AccessDeniedException异常处理器通常会通过response返回前端403错误。

#### 15.FilterSecurityInterceptor
Spring Security主要安全过滤器的执行已经接近尾声,但是这个FilterSecurityInterceptor是重头戏。

FilterSecurityInterceptor主要完成如下工作:
1. 解析当前请求的安全配置,主要包括:permitAll、authenticated、denyAll、anonymous等。
2. 从SecurityContextHolder获取安全认证信息。
3. 根据当前请求的安全配置信息及当前用户的安全认证信息进行认证投票,其实就是判断获取到的当前用户的安全认证信息是否符合配置的安全认证需求,符合的话则通过认证,不符合的话抛出accesssdeny异常。

之所以说FilterSecurityInterceptor是Spring Security安全过滤器的重头戏,是因为我们根据项目的具体需求、针对不同请求配置好的安全认证标准的解析是FilterSecurityInterceptor完成的,解析之后检查当前用户是否满足请求所需要的安全要求也是FilterSecurityInterceptor完成的。

如果当前用户认证信息不满足当前请求的安全需求,比如匿名用户访问/helloworld、/helloworld配置为authenticated的话,FilterSecurityInterceptor会抛出accesssdeny异常,最终经ExceptionTranslationFilter处理之后前台页面会收到403错误信息。

#### 总结

Spring security主要安全过滤器的基本工作原理分析完毕,其实每一个安全过滤器的底层工作细节都可以单独写一篇文章进行代码级的分析。但是一般来讲,对于相对复杂一点的知识,入门学习的时候太过细节的分析会影响到对整体框架的理解,Spring Security相对来讲比较负责,因此适合这一原则。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/weixin_44612246/article/details/128357129

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/13038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习300问】90、怎么理解测试集、验证集必须和训练集来自于同一分布?

我写这篇文章是因为我自己在做一个手势识别项目的时候&#xff0c;所用的训练集是网上爬取的以及公开的数据集。但当我训练完成后使用我自己通过摄像头捕捉的实地拍摄的手势图片&#xff0c;得出的识别准确率非常的低&#xff01;这些图片可能在光照、背景、手势姿势等方面与通…

基于SpringBoot设计模式之创建型设计模式·工厂方法模式

文章目录 介绍开始架构图样例一定义工厂定义具体工厂&#xff08;上衣、下装&#xff09;定义产品定义具体生产产品&#xff08;上衣、下装&#xff09; 测试样例 总结优点缺点与抽象工厂不同点 介绍 在 Factory Method模式中&#xff0c;父类决定实例的生成方式&#xff0c;但…

图像/视频恢复和增强CodeFormer

github&#xff1a;https://github.com/sczhou/CodeFormer 尝试增强旧照片/修复人工智能艺术 面部修复 面部色彩增强和恢复 脸部修复

Python 机器学习 基础 之 监督学习 [ 核支持向量机 SVM ] 算法 的简单说明

Python 机器学习 基础 之 监督学习 [ 核支持向量机 SVM ] 算法 的简单说明 目录 Python 机器学习 基础 之 监督学习 [ 核支持向量机 SVM ] 算法 的简单说明 一、简单介绍 二、监督学习 算法 说明前的 数据集 说明 三、监督学习 之 核支持向量机 1、线性模型与非线性特征 …

汇编语言入门:探索 x86 架构

目录 前言 1. x86 语言 x86 架构简介 x86 架构的特点 x86 架构的演变 x86 架构的应用 2. 常用汇编指令集 3. 寻址方式 结语 前言 汇编语言是一种低级编程语言&#xff0c;直接面向计算机的硬件架构。在计算机科学中&#xff0c;了解汇编语言是非常重要的&#xff0c;因…

探索Java中的利器:ThreadLocal

在日常的Java开发中&#xff0c;我们经常会遇到多线程并发访问共享资源的情况&#xff0c;而这时候线程安全就成了我们需要重点考虑的问题之一。幸运的是&#xff0c;Java提供了一种非常巧妙的机制来解决这个问题&#xff0c;那就是 ThreadLocal。 什么是ThreadLocal&#xff…

基于网络爬虫技术的网络新闻分析(二)

目录 2 系统需求分析 2.1 系统需求概述 2.2 系统需求分析 2.2.1 系统功能要求 2.2.2 系统IPO图 2.2 系统非功能性需求分析 3 系统概要设计 3.1 设计约束 3.1.1 需求约束 3.1.2 设计策略 3.1.3 技术实现 3.3 模块结构 3.3.1 模块结构图 3.3.2 系统层次图 3.3.3…

JumpServer堡垒机应用(v3.10.8) 下

目录 JumpServer堡垒机简单式部署与管理(v3.10.8) 上-CSDN博客 一. 资产管理 1.1创建资产 1.2 给资产主机创建用户 1.2.1 普通账户&#xff1a; 1.2.2 特权账户&#xff1a; 1.2.3 创建用户 二. 命令过滤 2.1 创建命令组 2.2 创建命令过滤 ​编辑 三. 创建资产授权 …

在另外一个页面,让另外一个页面弹框显示操作(调佣公共的弹框)vue

大概意思是&#xff0c;登录弹框在另外一个页面中&#xff0c;而当前页面不存在&#xff0c;在当前页面中判断如果token不存在&#xff0c;就弹框出登录的弹框 最后一行 window.location.href … 如果当前用户已登录&#xff0c;则执行后续操作(注意此处&#xff0c;可不要)

2024中国应急(消防)品牌巡展西安站成功召开!惊喜不断

消防品牌巡展西安站 5月10日&#xff0c;由中国安全产业协会指导&#xff0c;中国安全产业协会应急创新分会、应急救援产业网联合主办&#xff0c;陕西消防协会协办的“一切为了安全”2024年中国应急(消防)品牌巡展-西安站成功举办。该巡展旨在展示中国应急&#xff08;消防&am…

ADS使用记录之使用RFPro进行版图联合仿真

ADS使用记录之使用RFPro进行版图联合仿真 在ADS中&#xff0c;我们往往使用EM仿真来明确电路的实际性能&#xff0c;但是常规的方法我们只会得到S参数&#xff0c;对于场还有电路的电流分布往往不进行检查。但是在实际中&#xff0c;观察场和电流分布是非常有意义的&#xff0…

Python送你小花花

快到520了&#xff0c;准备好送上你的爱意了吗&#xff1f; 还记得去年从网上模仿了一篇python使用turtle画的小花花程序&#xff0c;当时还没有转行到程序员行业&#xff0c;刚刚入门学习编程&#xff0c;还在纠结是学习python、Java还是C#的时候。 总会被一些猎奇的内容吸引&…

在Linux系统上使用nmcli命令配置各种网络(有线、无线、vlan、vxlan、路由、网桥等)

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; 在Linux系统上使用nmcli命令配置各种网络&#xff08;有线、无线、vlan、vxlan等&#xff09;https://myweb.myskillstree.cn/123.html 更新于2024/5/13&…

01.认识HTML及常用标签

目录 URL&#xff08;统一资源定位系统&#xff09; HTML&#xff08;超文本标记语言&#xff09; 1&#xff09;html标签 2&#xff09;head标签 3&#xff09;title标签 4&#xff09;body标签 标签的分类 DTD文档声明 基础标签 1&#xff09;H系列标签 2&#xff09…

Linux 第三十四章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

EFDC建模方法及在地表水环境评价、水源地划分、排污口论证中实践【从软件安装到EFDC源码编译】

近年&#xff0c;随着水环境问题的凸显&#xff0c;地表水水环境状况不仅是公众关注的焦点&#xff0c;也是环保、水务等部门兼管的重点&#xff0c;已成为项目审批、规划制定&#xff0c;甚至领导考核的决定因素&#xff0c;特别是国务院水十条即将出台&#xff0c;必将掀起新…

【RSGIS数据资源】2001-2021 年亚洲季风区主要国家作物种植制度数据集

文章目录 1. 数据集概况2. 数据格式3. 文件名命名规则4. 数据生产服务单位5. 元数据6. 数据引用与参考文献引用 1. 数据集概况 2001-2021 年亚洲季风区主要国家作物种植制度数据集&#xff08;ACIA500&#xff09;是结合MODIS 影像和现有的土地利用等多源数据&#xff0c;基于…

js实现同步请求

看了一些网上的推荐&#xff0c;但是同步依然借助的async、await&#xff0c;这不是我需要的。这里记录下不依赖async来实现同步请求。 function syncRequest(url, param){const xhr new XMLHttpRequest();xhr.open("GET", url, false); // false 表示同步请求xhr.…

扫码免费领!全国各地妇幼医院引进绿葆自助取袋机,助力宝妈绿色出行

根据国家发展改革委生态环境部印发《关于进一步加强塑料污染治理的意见》第二条第五款&#xff0c;到2020年底&#xff0c;直辖市、省会城市、计划单列市城市建成区的商超、医院、药店等公共场所禁止使用不可降解塑料袋&#xff0c;并鼓励提供可降解环保袋和自助化、智慧化的投…

CNN卷积神经网络初学

1.为什么要学CNN 在传统神经网络中&#xff0c;我们要识别下图红色框中的图像时&#xff0c;我们很可能识别不出来&#xff0c;因为这六张图的位置都不通&#xff0c;计算机无法分辨出他们其实是一种形状或物体。 这是传统的神经网络图&#xff0c;通过权重调整神经元和神经元…