过滤器链加载原理

简介: 通过前文十五个过滤器的解析,我们揭开了Spring Security的神秘面纱。虽未显式配置,但这些过滤器由DelegatingFilterProxy通过名称springSecurityFilterChain自动加载,最终指向FilterChainProxy,并封装于DefaultSecurityFilterChain中执行。底层原理明晰后,方可更好实现自定义认证页面。

通过前面十五个过滤器功能的介绍,对于SpringSecurity简单入门中的疑惑是不是在心中已经有了答案了呀? 但新的问题来了!我们并没有配置这些过滤器啊?它们都是怎么被加载出来的?
1-DelegatingFilterProxy
我们在web.xml中配置了一个名称为springSecurityFilterChain的过滤器DelegatingFilterProxy,接下我直接对 DelegatingFilterProxy源码里重要代码进行说明,其中删减掉了一些不重要的代码,大家注意我写的注释就行了!
第二步debug结果如下:

由此可知,DelegatingFilterProxy通过springSecurityFilterChain这个名称,得到了一个FilterChainProxy过滤器, 最终在第三步执行了这个过滤器。
2-FilterChainProxy
注意代码注释!
第二步debug结果如下图所示,惊不惊喜?十五个过滤器都在这里了!
再看第三步,怀疑这么久!原来这些过滤器还真是都被封装进SecurityFilterChain中了。
3-SecurityFilterChain
最后看SecurityFilterChain,这是个接口,实现类也只有一个,这才是web.xml中配置的过滤器链对象!
Java
运行代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//接口
public interface SecurityFilterChain {
boolean matches(HttpServletRequest var1);
List 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) {
    this(requestMatcher, Arrays.asList(filters));
}

public DefaultSecurityFilterChain(RequestMatcher requestMatcher, 
                                  List<Filter> filters) {
    logger.info("Creating filter chain: " + requestMatcher + ", " + filters);
    this.requestMatcher = requestMatcher;
    this.filters = new ArrayList(filters);
}

public RequestMatcher getRequestMatcher() {
    return this.requestMatcher;
}

public List<Filter> getFilters() {
    return this.filters;
}

public boolean matches(HttpServletRequest request) {
    return this.requestMatcher.matches(request);
}

public String toString() {
    return "[ " + this.requestMatcher + ", " + this.filters + "]";
}

}
总结:通过此章节,我们对SpringSecurity工作原理有了一定的认识。但理论千万条,功能第一条,探寻底层,是为了更好的使用框架。 那么,言归正传!到底如何使用自己的页面来实现SpringSecurity的认证操作呢?要完成此功能,首先要有一套自己的页面!

相关文章
|
3月前
|
安全 JavaScript Java
若依后台权限核心:Spring Security 认证授权详解
若依(RuoYi)框架整合 Spring Security 的具体实现方式,我会从核心原理、整合步骤、关键配置、实战示例四个维度,结合若依前后端分离版(Spring Boot + Vue)的特点,给出可直接落地的整合方案,帮你理解若依是如何基于 Spring Security 实现权限管控
296 4
|
5月前
|
缓存 Dubbo Java
什么是API网关
API网关是一种架构思想,用于统一接收外部请求并转发至后端服务,实现协议转换、路由、鉴权、限流、熔断降级等功能。通过网关,可简化客户端调用,提升系统安全性与可维护性。常见实现如Kong、Zuul、Spring Cloud Gateway等,广泛应用于微服务架构中,支持异步处理、全链路监控与多维度流量控制。
|
5月前
|
缓存 安全
Watcher机制(二)WatchManager
本文深入分析ZooKeeper源码中的WatchManager类,重点解析其内部两个核心映射结构:watchTable(路径到Watcher集合)和watch2Paths(Watcher到路径集合)。详细解读addWatch、removeWatcher、triggerWatch等同步方法的实现机制,揭示Watcher注册、删除与事件触发的底层逻辑,展现其在分布式协调中高效的事件管理能力。
|
5月前
|
存储 缓存 安全
One Trick Per Day
初始化Map应避免默认容量导致扩容,推荐Guava的`newHashMapWithExpectedSize`;禁用Executors创建线程池,防止OOM,应手动通过`ThreadPoolExecutor`设置合理参数;`Arrays.asList`返回不可变列表,禁止修改操作;遍历Map使用`entrySet`提升性能;`SimpleDateFormat`非线程安全,建议用`ThreadLocal`或Java8时间类;并发修改记录需加锁,优先乐观锁,冲突高则用悲观锁。
|
5月前
|
存储 缓存 监控
EFC&CTO:缓存引发数据不一致问题排查与深度解析
EFC客户端更新缓存架构后,CTO测试出现data mismatch。经排查,因分布式缓存版本号回退,导致旧NULL数据被读入pagecache并刷入文件系统,破坏了NAS数据一致性。修复后10轮测试通过。
|
5月前
|
运维 安全 Devops
生产环境缺陷管理
git-poison基于go-git实现分布式bug追溯,解决多分支开发中bug漏修、漏发等问题。通过“投毒-解毒”机制,自动化卡点发布流程,降低协同成本,避免人为失误,已在大型团队落地应用,显著提升发布安全与效率。
|
5月前
|
Java 测试技术 API
从Google线上故障,谈灰度发布的重要性
2025年6月12日,Google Cloud因未灰度发布的新配置引发空指针异常,导致Gmail、YouTube等服务中断超7小时。故障暴露了缺乏配置灰度与错误处理机制的风险。本文结合Nacos等配置中心的IP/标签灰度方案,探讨如何通过渐进式发布保障系统稳定性,避免全局故障。
|
5月前
|
消息中间件 监控 Java
RocketMQ:底层Netty频繁OS OOM
本文记录了一例Java应用因多ClassLoader加载多个Netty的PooledByteBufAllocator导致堆外内存超限,引发OS OOM的排查过程。尽管MaxDirectMemorySize设为1G,但多个中间件独立占用堆外内存,总量远超限制。通过NMT、Arthas等工具定位到RocketMQ客户端为主要占用者。最终建议短期调小堆内存以腾出空间,并推动中间件优化。
|
5月前
|
Java 数据安全/隐私保护
脱敏工具
提供身份证、姓名、手机号脱敏的Java实现,通过正则替换隐藏敏感信息:身份证保留前后部分,中间用*代替;姓名仅显示首尾字符;手机号显示前3后4位,中间4位脱敏,保障数据安全。
|
5月前
|
Java 测试技术 Linux
生产环境发布管理
本文介绍大型团队如何通过自动化部署平台实现多环境(dev/test/pre/prod)高效发布与运维。涵盖各环境职责、基于Jenkins+K8S的CI/CD流程、分支管理、一键发布及日志排查方案,结合Skywalking实现链路追踪,提升发布效率与问题定位能力。(238字)