SecurityContextPersistenceFilter和SecurityContextHolder的作用
SecurityContextPersistenceFilter和SecurityContextHolder的作用
SecurityContextHolder
SecurityContextHolder
是Spring Security
中最基本的组件,SecurityContextHolder
是一个工具类,只提供一些静态方法。这个工具类的目的是用来保存应用程序中当前使用人的安全上下文。
SecurityContext securityContext = SecurityContextHolder.getContext();
默认情况下:
SecurityContextHolder
使用了ThreadLocal
机制来保存每个使用者的安全上下文。- 根据
Servlet
规范,一个Servlet request
的处理不管经历了多少个Filter
,自始至终都由同一个线程来完成。
这意味着,只要针对某个使用者的逻辑执行都是在同一个线程中进行,即使不在各个方法之间以参数的形式传递其安全上下文,各个方法也能通过SecurityContextHolder
工具获取到该安全上下文。并且因为SecurityContextHolder
使用了ThreadLocal
机制来保存每个使用者的安全上下文,所以在一个请求处理的逻辑执行中都在同一个线程中进行,而请求对应的安全上下文就保存在SecurityContextHolder
中。所以我们才可以通过SecurityContextHolder.getContext();
每个请求自己独立的安全上下文。
需要注意的一点是,这里说的是一次请求,而非一次会话,而如何将请求的信息保存在session中就要看下面的SecurityContextPersistenceFilter的工作原理了。
SecurityContextHolder的其他工作模式
根据不同的web应用可以有不同的上下文保存和管理方式,而SecurityContextHolder一共提供了三种工作模式,而每一种工作模式就对应着一个一种上下文管理方式。
SecurityContextHolder
有以下三种模式:
MODE_THREADLOCAL
(缺省工作模式,也就是默认模式)MODE_GLOBAL
MODE_INHERITABLETHREADLOCAL
MODE_GLOBAL
这个称之为全局模式,该模式下的JVM
中所有的线程使用同一个安全上下文,所以所以请求的线程都是共用一个上下文,而不存在MODE_THREADLOCAL模式中的使用ThreadLocal
机制来保存每个使用者的安全上下文。
MODE_INHERITABLETHREADLOCAL
根据名字可以猜测出这是一个继承MODE_THREADLOCAL的一种模式,在该模式下,用户可以自定义自己的线程创建,并且希望这些自定义的新建线程也能使用创建者的安全上下文。
SecurityContextPersistenceFilter
SecurityContextPersistenceFilter
其实是spring security中filterchainproxy中的一个Filter,而跨请求安全上下文SecurityContext
的保持,是通过SecurityContextPersistenceFilter
来实现的,SecurityContextPersistenceFilter
将安全上下文SecurityContext
对象保存为当前用户HttpSession
对象的一个属性。
SecurityContextPersistenceFilter
除了负责安全上下文的持久化,在一些restful api的非持久化的请求场景中,SecurityContextPersistenceFilter
还负责该安全上下文的销毁。
SecurityContextPersistenceFilter有两个主要任务:
- 在请求到达时处理之前,从SecurityContextRepository中获取安全上下文信息填充到SecurityContextHolder;
- 在请求处理结束后返回响应时,将SecurityContextHolder中的安全上下文信息保存回SecurityContextRepository,并清空SecurityContextHolder。
SecurityContextPersistenceFilter的工作过程
对于一些要求跨 request 请求保持的场景,我们都是通过session来保存一次request中的信息,当下次请求过来的时候,我们可以通过session获取之前请求中的信息。SecurityContextPersistenceFilter
这个filter就是处理请求最后的保存操作。
具体来讲,操作如下:
- 一个安全上下文在某个请求1处理过程中被创建并记录到SecurityContextHolder(准确来说是SecurityContextHolder中对应的ThreadLocal);
- 请求1的处理结束时返回响应时,SecurityContextPersistenceFilter会将SecurityContextHolder中的安全上下文保存到HttpSession(SecurityContextRepository负责安全上下文的持久);
- 后续该用户会话中的另外一个请求2处理过程开始时,SecurityContextPersistenceFilter会将安全上下文从HttpSession恢复到SecurityContextHolder;
- 请求2处理过程结束时,SecurityContextPersistenceFilter会将SecurityContextHolder中的安全上下文保存到HttpSession;
- 后续其他请求的处理过程会重复和上面请求2处理过程中一样的使用SecurityContextPersistenceFilter重置/恢复SecurityContext的动作。
在现实场景中,处理在一些restful api的非持久化的请求场景中,SecurityContextPersistenceFilter负责安全上下文的销毁,具体操作如下:
- 一个安全上下文在某个请求1处理过程中被创建并记录到SecurityContextHolder
- 请求1的处理结束时,SecurityContextPersistenceFilter会将SecurityContextHolder中的安全上下文进行销毁
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)