开发者学堂课程【Spring Security知识精讲与实战演示(一):Spring Security过滤器链加载原理】学习笔记与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/730/detail/13032
Spring Security过滤器链加载原理
过滤器链加载原理
Spring Security 常用的十五个过滤器,但是我们并没有在项目中配置如此多的过滤器,这些过滤器从哪来的呢?
在代码 web.xml 中只配置了如下:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
那么多个过滤器从哪来呢?点击 DelegatingFilterProxy,点进后是一个过滤器,查找doFilter,核心代码为 delegateToUse = this.initDelegate(wac)
;经过一系列if判断,然后进行初始化 Delegate,然后this.invokeDelegate(delegateToUse,request,response,filterChain)
执行,让过滤器起作用,真正封装过滤器、过滤器加载是在initDelegate中。点击initDelegate 进入查看真正封装代码:
protected Filter initDelegate(WebApplicationContext wac)throws ServletException{
String targetBeanName = this.getTargetBeanName() ;
Assert.state( expression: targetBeanName != null, message:"No target bean name set");
Filter delegate = (Filter)wac.getBean(targetBeanName,Filter.class) ;
if (this.isTargetFilterLifecycle()){
delegate.init(this.getFilterConfig());
}
可以先对第二行进行断点,注意这些过滤器必须在项目启动时加载,点击debug关闭。
显示:targetBeanName 是目标对应名称, targetBeanName=”springSecurityFilterChain”。
getBean是通过id取名称即通过对象的id获取对象,所以 targetBeanName 不能乱写。targetBeanName 通过名字 springSecurityFilterChain 去获取对象。
控制台中再点击下一步查看 delegate,显示delegate={FilterChainProxy@4684}”FilterChainProxy[Filter Chains:[[any request,[org.springframework.security.web.context.SecurityContext...]]”
并不是有关十五个过滤器,所以继续向下查看
delegate 是得到对象后返回,但是返回的不是 springSecurityFilterChain,所以追踪 springSecurityFilterChain 对象继续寻找。
刚才讲解了 DelegatingFilterProxy,查找到 FilterChainProxy。所以在代码中查找FilterChainProxy,找到 FilterChainProxy.class中的FilterChainProxy,还是过滤器,所以继续找dofilter。在寻找之前会发现存在SecurityFilterChain,与上述的springSecurityFilterChain接近。找到doFilter,看到代码中无论if或是else都执行doFilterInternal,点进doFilterInternal。不能看懂原理继续打断点,点debug,代码中存在很多过滤器,查看List<Filter>filters = this.getFilters((HttpServletRequest)fwRequest)
是否是我们需要的过滤器,结果显示
再往下可以看到显示讲解的十五个过滤器,所以理解其中的过滤器链是FilterChainProxy 在封装,但是还不能确定过滤器链。
继续在 debug中查看,已经找到了十五个过滤器,之后运行了getFilters,再点进getFilters,发现过滤器链确实存在 SecurityFilterChain中。点进SecurityFilterChain,可以查看它的实现类只有一个 DefaultSecurityfFilterChain。
总结getFilters放置过滤器链,配置 springSecurityFilterChain,实际上过滤器链在SecurityFilterChain中进行存放,实现类为 DefaultSecurityfFilterChain。即springSecurity中的过滤器链中的过滤器由对象SecurityFilterChain封装。
以上就是过滤器链加载的原理。