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

Spring Security之过滤器链【探案】

Spring Security常用过滤器介绍

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

SecurityContextPersistenceFilter主要是使用SecurityContextRepository在session中保存或更新一个 SecurityContext,并将SecurityContext给以后的过滤器使用,来为后续filter建立所需的上下文。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配置的修改,有些过滤器可能也用不上。

Spring Security过滤器链加载原理

我们并没有在web.xml中配置这些过滤器啊?它们都是怎么被加载出来的?

DelegatingFilterProxy
我们在web.xml中配置了一个名称为springSecurityFilterChain的过滤器DelegatingFilterProxy,接下我直接对 DelegatingFilterProxy源码里重要代码进行说明,其中删减掉了一些不重要的代码。

Spring Security之过滤器链【探案】+源码剖析
dofilter是过滤器的入口,找到dofilter
Spring Security之过滤器链【探案】+源码剖析
第二步:看最终加载的过滤器是谁
Spring Security之过滤器链【探案】+源码剖析
第三步:执行FilterChainProxy过滤器
Spring Security之过滤器链【探案】+源码剖析
附debug结果:
Spring Security之过滤器链【探案】+源码剖析
按下F8,
Spring Security之过滤器链【探案】+源码剖析
由此可知,DelegatingFilterProxy通过springSecurityFilterChain这个名称,得到了一个FilterChainProxy过滤器, 最终在第三步执行了这个过滤器。

FilterChainProxy
话不多说,直接上源码
Spring Security之过滤器链【探案】+源码剖析
我们同样是找到dofilter,
Spring Security之过滤器链【探案】+源码剖析
Spring Security之过滤器链【探案】+源码剖析
好了,准备debug,
Spring Security之过滤器链【探案】+源码剖析
惊不惊喜?十三个过滤器都在这里了!诶,不是十五个嘛?咋就才十三个了。这里给大家说明一下,我用的Spring Security版本是4.1.0.RELEASE。这也说明了随着版本更新会出现更多的过滤器。5.1.5.RELEASE有十五个过滤器。原来这些过滤器还真是都被封装进SecurityFilterChain中了。

SecurityFilterChain
最后看SecurityFilterChain,这是个接口,实现类也只有一个,这才是web.xml中配置的过滤器链对象。
Spring Security之过滤器链【探案】+源码剖析
这是一个接口,Ctrl+H看实现类
Spring Security之过滤器链【探案】+源码剖析
理论千万条,功能第一条,探寻底层,是为了更好的使用框架。(更多的Java学习知识可关注vx公众号: 进阶的coder