7、Spring Security过滤器及加载过程

深入 Spring Security 6:从底层机制到动态模块化配置 摘要:本文深入剖析SpringSecurity 6.x底层架构,重点解析FilterChainProxy与SecurityFilterChain的协作机制,以及"Builder+Configurer"设计模式。通过模块化拆分示例,论证基于多个SecurityConfigurer实现动态配置的优势:1)避免单一配置类臃肿,符合单一职责原则;2)支持@ConditionalOnMissingBean实现零代码功能覆盖;3)通过addFilterBefore精确控制过滤器顺序;4)便于微服务场 阅读详情

Spring Security介绍及过滤器

1 、Spring Security常用过滤器介绍

过滤器是一种典型的AOP思想,关于什么是过滤器,就不赘述了,谁还不知道凡是web工程都能用过滤器?

接下来咱们就一起看看Spring Security中这些过滤器都是干啥用的,源码我就不贴出来了,有名字,大家可以自

己在看。我也会在后续的学习过程中穿插详细解释。** 、

1.org.springframework.security.web.context.SecurityContextPersistenceFilter 
	首当其冲的一个过滤器,作用之重要,自不必多言。 
	SecurityContextPersistenceFilter主要是使用SecurityContextRepository在session中保存或更新一个 SecurityContext,并将SecurityContext给以后的过滤器使用,来为后续fifilter建立所需的上下文。 
SecurityContext中存储了当前用户的认证以及权限信息。 

2.org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter 
	此过滤器用于集成SecurityContext到Spring异步执行机制中的WebAsyncManager 
	
3. org.springframework.security.web.header.HeaderWriterFilter 
	向请求的Header中添加相应的信息,可在http标签内部使用security:headers来控制 

4. org.springframework.security.web.csrf.CsrfFilter 
	csrf又称跨域请求伪造,SpringSecurity会对所有post请求验证是否包含系统生成的csrf的token信息,如果不包含,则报错。起到防止csrf攻击的效果。 

5. org.springframework.security.web.authentication.logout.LogoutFilter 
	匹配URL为/logout的请求,实现用户退出,清除认证信息。 

6. org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 
	认证操作全靠这个过滤器,默认匹配URL为/login且必须为POST请求。 

7. org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter 
	如果没有在配置文件中指定认证页面,则由该过滤器生成一个默认认证页面。 

8. org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter 
	由此过滤器可以生产一个默认的退出登录页面 

9. org.springframework.security.web.authentication.www.BasicAuthenticationFilter 
	此过滤器会自动解析HTTP请求中头部名字为Authentication,且以Basic开头的头信息。 

10. org.springframework.security.web.savedrequest.RequestCacheAwareFilter 
	通过HttpSessionRequestCache内部维护了一个RequestCache,用于缓存HttpServletRequest 

11. org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter 
	针对ServletRequest进行了一次包装,使得request具有更加丰富的API 

12. org.springframework.security.web.authentication.AnonymousAuthenticationFilter 
	当SecurityContextHolder中认证信息为空,则会创建一个匿名用户存入到SecurityContextHolder中。		spring security为了兼容未登录的访问,也走了一套认证流程,只不过是一个匿名的身份。 

13. org.springframework.security.web.session.SessionManagementFilter 
	SecurityContextRepository限制同一用户开启多个会话的数量 

14. org.springframework.security.web.access.ExceptionTranslationFilter 
	异常转换过滤器位于整个springSecurityFilterChain的后方,用来转换整个链路中出现的异常 
	
15. org.springframework.security.web.access.intercept.FilterSecurityInterceptor 
	获取所配置资源访问的授权信息,根据SecurityContextHolder中存储的用户信息来决定其是否有权限。 

好了!这一堆排山倒海的过滤器介绍完了。

那么,是不是spring security一共就这么多过滤器呢?答案是否定的!随着spring-security.xml配置的添加,还

会出现新的过滤器。

那么,是不是spring security每次都会加载这些过滤器呢?答案也是否定的!随着spring-security.xml配置的修

改,有些过滤器可能会被去掉。

2、Spring Security过滤器链加载原理

通过前面十五个过滤器功能的介绍,对于SpringSecurity简单入门中的疑惑是不是在心中已经有了答案了呀?

它们都是怎么被加载出来的?

2.1 DelegatingFilterProxy

首先是名称为springSecurityFilterChain的过滤器DelegatingFilterProxy,接下我直接对

DelegatingFilterProxy源码里重要代码进行说明,其中删减掉了一些不重要的代码,大家注意我写的注释就行了!

public class DelegatingFilterProxy extends GenericFilterBean { 

@Nullable 

private String contextAttribute; 

@Nullable 

private WebApplicationContext webApplicationContext; 

@Nullable 

private String targetBeanName; 

private boolean targetFilterLifecycle; 

@Nullable 

private volatile Filter delegate;//注:这个过滤器才是真正加载的过滤器 

private final Object delegateMonitor; 

//注:doFilter才是过滤器的入口,直接从这看! 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain 

filterChain) throws ServletException, IOException { 

Filter delegateToUse = this.delegate; 

if (delegateToUse == null) { 

synchronized(this.delegateMonitor) { 

delegateToUse = this.delegate; 

if (delegateToUse == null) { 

WebApplicationContext wac = this.findWebApplicationContext(); 

if (wac == null) { 

throw new IllegalStateException("No WebApplicationContext found: no 

ContextLoaderListener or DispatcherServlet registered?"); 

}

//第一步:doFilter中最重要的一步,初始化上面私有过滤器属性delegate 

delegateToUse = this.initDelegate(wac); 

}

this.delegate = delegateToUse; 

} 

}

//第三步:执行FilterChainProxy过滤器 

this.invokeDelegate(delegateToUse, request, response, filterChain); 

}

//第二步:直接看最终加载的过滤器到底是谁 

protected Filter initDelegate(WebApplicationContext wac) throws ServletException { 

//debug得知targetBeanName为:springSecurityFilterChain 

String targetBeanName = this.getTargetBeanName(); 

Assert.state(targetBeanName != null, "No target bean name set"); 

//debug得知delegate对象为:FilterChainProxy 

Filter delegate = (Filter)wac.getBean(targetBeanName, Filter.class); 

if (this.isTargetFilterLifecycle()) { 

delegate.init(this.getFilterConfig()); 

}

return delegate; 
}       

第二步debug结果如下:

由此可知,DelegatingFilterProxy通过springSecurityFilterChain这个名称,得到了一个FilterChainProxy过滤器,

最终在第三步执行了这个过滤器。

2.2 FilterChainProxy

注意代码注释!注意代码注释!注意代码注释!

protected void invokeDelegate(Filter delegate, ServletRequest request, ServletResponse 

response, FilterChain filterChain) throws ServletException, IOException { 

delegate.doFilter(request, response, filterChain); 

} 

}

public class FilterChainProxy extends GenericFilterBean { 

private static final Log logger = LogFactory.getLog(FilterChainProxy.class); 

private static final String FILTER_APPLIED = 

FilterChainProxy.class.getName().concat(".APPLIED"); 

private List<SecurityFilterChain> filterChains; 

private FilterChainProxy.FilterChainValidator filterChainValidator; 

private HttpFirewall firewall; 

//咿!?可以通过一个叫SecurityFilterChain的对象实例化出一个FilterChainProxy对象 

//这FilterChainProxy又是何方神圣?会不会是真正的过滤器链对象呢?先留着这个疑问! 

public FilterChainProxy(SecurityFilterChain chain) { 

this(Arrays.asList(chain)); 

}

//又是SecurityFilterChain这家伙!嫌疑更大了! 

public FilterChainProxy(List<SecurityFilterChain> filterChains) { 

this.filterChainValidator = new FilterChainProxy.NullFilterChainValidator(); 

this.firewall = new StrictHttpFirewall(); 

this.filterChains = filterChains; 

}

//注:直接从doFilter看 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 

throws IOException, ServletException { 

boolean clearContext = request.getAttribute(FILTER_APPLIED) == null; 

if (clearContext) { 

try {

request.setAttribute(FILTER_APPLIED, Boolean.TRUE); 

this.doFilterInternal(request, response, chain); 

} finally { 

SecurityContextHolder.clearContext(); 

request.removeAttribute(FILTER_APPLIED); 

} 

} else { 

//第一步:具体操作调用下面的doFilterInternal方法了 

this.doFilterInternal(request, response, chain); 

} 

}

private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain 

chain) throws IOException, ServletException { 

FirewalledRequest fwRequest = 

this.firewall.getFirewalledRequest((HttpServletRequest)request); 

HttpServletResponse fwResponse = 

this.firewall.getFirewalledResponse((HttpServletResponse)response); 

//第二步:封装要执行的过滤器链,那么多过滤器就在这里被封装进去了! 

List<Filter> filters = this.getFilters((HttpServletRequest)fwRequest); 

if (filters != null && filters.size() != 0) { 

FilterChainProxy.VirtualFilterChain vfc = new 

FilterChainProxy.VirtualFilterChain(fwRequest, chain, filters); 

//第四步:加载过滤器链 

vfc.doFilter(fwRequest, fwResponse); 

} else { 

if (logger.isDebugEnabled()) { 

logger.debug(UrlUtils.buildRequestUrl(fwRequest) + (filters == null ? " has no 

matching filters" : " has an empty filter list")); 

}

fwRequest.reset(); 

chain.doFilter(fwRequest, fwResponse); 

} 

}

private List<Filter> getFilters(HttpServletRequest request) { 

Iterator var2 = this.filterChains.iterator(); 

//第三步:封装过滤器链到SecurityFilterChain中! 

SecurityFilterChain chain; 

do {

if (!var2.hasNext()) { 

return null; 

} 

第二步debug结果如下图所示,惊不惊喜?十五个过滤器都在这里了!

再看第三步,怀疑这么久!原来这些过滤器还真是都被封装进SecurityFilterChain中了。

2.3 SecurityFilterChain

最后看SecurityFilterChain,这是个接口,实现类也只有一个,这才是web.xml中配置的过滤器链对象!

chain = (SecurityFilterChain)var2.next(); 

} while(!chain.matches(request)); 

return chain.getFilters(); 

} 

}

//接口 

public interface SecurityFilterChain { 

boolean matches(HttpServletRequest var1); 

List<Filter> getFilters(); 

}

//实现类 

public final class DefaultSecurityFilterChain implements SecurityFilterChain { 

private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class); 

private final RequestMatcher requestMatcher; 

private final List<Filter> filters; 

public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) { 

总结:通过此章节,我们对SpringSecurity工作原理有了一定的认识。但理论千万条,功能第一条,探寻底层,是为了更好的使用框架。


SpringSecurity6从入门到上天系列第五篇:详解SpringSecurity6中的Security Filters的作用和原理以及默认的15个核心Security Filters 本文是SpringSecurity6从入门到上天系列第五篇,详细介绍了SpringSecurity6中的Security Filters的作用和原理以及默认的15个核心Security Filters 阅读详情

相关推荐

SpringSecurity(十二)过滤器链分析(上)

前言 说到Spring Security的实现原理,大部分都知道是通过过滤器链。因为Spring Security中的所有功能都是通过过滤器链来实现的,这些过滤器组成一个完整的过滤器链。那么这些过滤器链是如何初始化的?我们之前说的AuthenticationManager又是如何初始化的?前面我们对Spring Security的一些核心过滤器以及组件有了一定的了解。由于初始化流程相对复杂,因此我们并没有一开始从这一块分析。 初始化流程分析 Spring Security初始化流程整体上来说还是很好理解的,

陈橙橙 2268

Spring Security过滤链FilterChain

Spring Security过滤链FilterChain1.Filters概述2.DelegatingFilterProxy3.FilterChainProxy4.SecurityFilterChain5.常见Security Filters(按顺序) 众所周知,spring security是一个集认证,授权和泄露保护于一体的安全框架,让我们来探讨一下它的过滤链机制! 1.Filters概述 图1 过滤链 当客户端发送一个请求到应用时,容器会创建一个过滤链FilterChain,该过滤链包含了Filt

Jianyang_usst的博客 1万+

Spring Security 6 系列之三 - Filter过滤器

关于Spring Security的底层原理大概讲这么多。Spring Security的过滤器有那么多,我们这里主要讲的是几个经常使用到的,其它的过滤器后续遇到需要自定义配置的时候,我们再讲解。Spring Security默认配置显然不能符合一个真正的业务需求,那么下一章我们就要开始做各种自定义配置。

代码让AI扣 2262

【坚如磐石】一文带你理解Spring Security认证环节

本文介绍了Spring Security框架的核心功能与工作原理。作为Spring家族的安全框架,Spring Security提供认证、授权和漏洞保护三大功能,通过一系列过滤器链实现安全控制。文章重点解析了DelegatingFilterProxy作为连接原生过滤器与Spring Security过滤器的"胶水"角色,以及FilterChainProxy如何通过SecurityFilterChain调用具体安全过滤器。作者通过源码分析揭示了Spring Security的底层实现机制,

不堪提 3774

Spring Security详解(三)认证之核心过滤器

这章主要用来分析Spring Security中的过滤器链包含了哪些关键的过滤器,并且各自的作用是什么。 3 核心过滤器 3.1 概述 Filter顺序 Spring Security的官方文档向我们提供了filter的顺序,无论实际应用中你用到了哪些,整体的顺序是保持不变的: - ChannelProcessingFilter,重定向到其他协议的过滤器。也就是说如果你访问的...

Jagger的博客 7685

Spring Security之过滤器链【探案】+源码剖析

Spring Security之过滤器链【探案】 Spring Security常用过滤器介绍 过滤器是一种典型的AOP思想,关于什么是过滤器,就不赘述了,接下来咱们就一起看看Spring Security中这些过滤器都是干啥用的,有名字,大家可以自己在IDEA中Double Shift找到它们。 1.org.springframework.security.web.context.Securit...

Crown_123的博客 1021

Spring Security 详解

​ Spring Security 是 Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。一般来说中大型的项目都是使用SpringSecurity来做安全框架。小项目有Shiro的比较多,因为相比与SpringSecurity,Shiro的上手更加的简单。​ 一般Web应用的需要进行认证和授权。​ 而认证和授权也是SpringSecurity作为安全框架的核心功能。视频地址:​ 我们先要搭建一个简单的SpringBoot工程① 设置父工

qq_22075913的博客 12万+

Spring Security 实战内容:图解Spring Security中的Servlet过滤器体系

1. 前言 Spring Security真正的过滤器体系才是我们了解它是如何进行"认证"、“授权”、“防止利用漏洞”的关键。 2. Servlet Filter体系 这里我们以Servlet Web为讨论目标,Reactive Web暂不讨论。我们先来看下最基础的Servlet体系,在Servlet体系中客户端发起一个请求过程是经过0到N个Filter然后交给Servlet处理。 Filter不但可以修改HttpServletRequest和HttpServletResponse,可以让我们在请求响应的

m0_66876551的博客 407

spring security 过滤器链相关初始化过程

Spring Security 的过滤器链(Filter Chain)初始化流程是其安全机制的核心实现,其设计目标是按特定顺序组装多个安全过滤器,形成一个完整的请求处理链。通过理解过滤器链的初始化流程,开发者可以更高效地定制安全策略,并快速定位安全配置相关的问题。Spring Security 过滤器链的初始化由。:检查 URL 路径匹配规则和过滤器的注册位置。,并注册到 Servlet 容器的过滤器链中。忽略静态资源路径,避免不必要的过滤器执行。:跟踪自定义过滤器的插入位置。:未将过滤器添加到正确的。

LCY133的博客 1233

spring security原理和机制 | Spring Boot 35

一、SpringSecurity 框架简介 Spring 是非常流行和成功的 Java 应用开发框架,Spring Security 正是 Spring 家族中的 成员。Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方 案。 正如你可能知道的关于安全方面的两个主要区域是“认证”和“授权”(或者访问控 制),一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权 (Authorization)两个部分,这两点也是 Spring

学Java,找哪吒 5万+

Spring Security 6.x 系列【4】源码篇之默认过滤器

本篇文档主要介绍中默认的15个过滤器相关作用。

记录知识、锤炼自我 3018

Spring Security06 - 过滤器实现

Spring Security06 - 过滤器实现

qq_43350524的博客 1261

开关电源EMC整改案例-辐射骚扰

2.4.1 获得原始数据。同样的分析可以应用在差模电流的情况, 唯一不同的是, 两根导线的磁场分布是相反的, 磁 场互相抵消, 由于导线中的电流大小相等, 产生的磁场 H 大小相同, 在互相靠近的情况下, 在磁 环内的两个感应磁场大小相同、方向相反, 因此合成之后的感应磁场 B 几乎为 0,对任意一根导 线而言,相当于是一段“无感导线”,对差模电流不会产生任何抑制作用。众所周知, 共模电感的匝数越多, 感量越大, 按道 理来说对共模干扰电流的抑制也会越强烈,对抗辐射 也越有利,然而事实真的如此吗?

经营范围: CTA、SRRC、CCC、移动、电信、联通入库 3504

Gateway 整合 Spring Security鉴权

Gateway 整合 Spring Security鉴权

qq_42394862的博客 1万+

音视频开发—H264相关概念和压缩原理详解(GOP、宏块、帧内压缩、帧间压缩)

本文讲述了H264相关概念和原理——GOP概念,SPS与PPS,帧内压缩原理,帧间压缩原理,解释了什么是运动补偿,什么运动矢量等等概念

weixin_46999174的博客 3982

毫米波雷达之CFAR 目标检测

恒虚警率(CFAR)算法是一种广泛应用于雷达目标检测的算法,其主要目 标是减少由于杂波与回波之间强度不对称而引起的误报,以确保相对恒定的虚警 率。如图 3.4(a)所示,表示由距离单元组成的一维数据。在待测单元 D 周围选 择若干个背景杂波功率的蓝色单元构成参考滑窗,称为参考单元;而待测单元 D 相邻的若干个不用于背景估计的单元则称为保护单元。当参考单元和保护单元的 维度从一维扩展到二维时,相应的 CFAR 检测由一维 CFAR 演变为二维 CFAR 以处理参考窗口,如图 3.4 (b)所示。

m0_56120826的博客 4922

Spring Security 过滤链流程:7 大核心过滤器执行顺序详解

Spring Security 本质上是一个过滤器链每个请求进来后,像流水线上的产品一样,逐个经过每个过滤器。只要有一个过滤器决定「这个请求不合法」,请求就到此为止。请求 → Filter1 → Filter2 → Filter3 → ... → Controller过滤器顺序决定异常归宿:自定义过滤器放在后面,抛出的认证异常才能被统一捕获;放在前面,异常直接冲到 Tomcat 返回 500。

2401_83135864的博客 631

COMSOL报错调试总结(不定期更新)

COMSOL报错调试总结1. 可定位错误1.1 除零错误1.2 未定义变量值1.3 边界条件/材料属性等缺失2. 难定位错误2.1. 装配期间内存不足 官方给的案例总是非常完美,运行流畅,结果完美。但是自己做模型时候就总是报错,而且不像自己coding的程序那样可以明确定位哪里出了bug。这里把我碰到的一些报错问题以及调试方法记录下来~ 部分来源于以下参考来源: http://wap.sciencenet.cn/blog-1467490-1118453.html?mobile=1 1. 可定位错误 以下错误

jessica0307的博客 8万+

Spring Security 深度学习(五): 过滤器链与自定义过滤器

SpringSecurity深入学习系列!🎉

qq_56158663的博客 1703

Altium Designer 16安装教程(Windows11、小白教程)

Altium Designer 16在Windows11中的超详细安装教程

qq_47003770的博客 1万+

分布式存储系统关于GDPR条例中的数据清除原则

文章目录前言HDFS存储系统数据的完全删除基于加解密的输入输出流的数据保护方案 前言 关于GDPR是什么,可能许多同学之前并不太了解,至少笔者在之前也是不清楚的。GDPR全称为通用数据保护条例,General Data Protection Regulation。它是一项来自欧盟的关于计算机数据保护相关的条约,旨在规范系统如何收集,管控用户私人数据的种种行为。但是当前的一些存储系统并没有完全符合...

走在前往架构师的路上 3628

Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃

Spring Security 5.7.1 最新配置细节,WebSecurityConfigurerAdapter 已废弃

江帅帅 3万+

YOLOv12超参数智能优化:基于内置Ray Tune的自动化调优实战指南

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有! 目标检测模型的性能瓶颈往往源于超参数配置不当。传统手动调优方式不仅耗时耗力,且难以找到全局最优解。YOLOv12集成的Ray Tune框架为解决这一难题提供了完整方案,通过分布式异步优化算法,可实现超参数搜索效率的指数级提升。实际测试表明,采用Ray Tune自动调优的YOLOv12模型,在COCO数据集上mAP指标平均提升3.8%,收敛速度加快2.1倍。在VisDrone无人机数据集上的跨域测试

LXY_LOVE36的博客 119

spring security的过滤器链

请求按过滤器链的顺序依次通过每个过滤器,每个过滤器可选择处理请求或传递给下一个过滤器。理解过滤器链的组成和执行逻辑,是调试安全问题和实现复杂安全需求的关键。:当某个过滤器处理完请求并直接返回响应时,后续过滤器不再执行。Spring Security 的安全功能通过一系列。捕获异常 → 触发登录页跳转或返回 403。Spring Security 的过滤器链通过。最终验证权限 → 若未授权则抛出。提取凭证并认证 → 存储。

LCY133的博客 1392

ICM20948 DMP代码详解(54)

ICM20948 DMP代码详解(54)

phmatthaus的专栏 427

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Spring Security深入剖析

关键源码 io.undertow.servlet.core.ManagedFilter:42 io.undertow.servlet.handlers.FilterHandler:58 org.springframework.web.filter.OncePerRequestFilter:42 org.apache.catalina.core.ApplicationFilterChain org.springframework.security.web.savedrequest.HttpSessionReq

潘顾昌的博客 1575

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

上一篇: 6、Spring Security介绍
下一篇: 8、权限模型RABC建表SQL
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白de成长之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值