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源码里重要代码进行说明,其中删减掉了一些不重要的代码。
dofilter是过滤器的入口,找到dofilter
第二步:看最终加载的过滤器是谁
第三步:执行FilterChainProxy过滤器
附debug结果:
按下F8,
由此可知,DelegatingFilterProxy通过springSecurityFilterChain这个名称,得到了一个FilterChainProxy过滤器, 最终在第三步执行了这个过滤器。
FilterChainProxy
话不多说,直接上源码
我们同样是找到dofilter,
好了,准备debug,
惊不惊喜?十三个过滤器都在这里了!诶,不是十五个嘛?咋就才十三个了。这里给大家说明一下,我用的Spring Security版本是4.1.0.RELEASE。这也说明了随着版本更新会出现更多的过滤器。5.1.5.RELEASE有十五个过滤器。原来这些过滤器还真是都被封装进SecurityFilterChain中了。
SecurityFilterChain
最后看SecurityFilterChain,这是个接口,实现类也只有一个,这才是web.xml中配置的过滤器链对象。
这是一个接口,Ctrl+H看实现类
理论千万条,功能第一条,探寻底层,是为了更好的使用框架。(更多的Java学习知识可关注vx公众号: 进阶的coder)