上篇回顾
- 框架的核心是一个过滤器,这个过滤器
名字叫springSecurityFilterChain,类型是FilterChainProxy WebSecurity和HttpSecurity都是建造者WebSecurity构建目标是FilterChainProxy对象HttpSecurity的构建目标仅仅是FilterChainProxy中的一个SecurityFilterChain。@EnableWebSecurity注解,导入了WebSecurityConfiguration类WebSecurityConfiguration中创建了建造者对象WebSecurity,和核心过滤器FilterChainProxy
从WebSecurityConfiguration开始
WebSecurityConfiguration中需要关注两个方法:
setFilterChainProxySecurityConfigurer()方法创建了
WebSecurity建造者对象,用于后面建造FilterChainProxy过滤器springSecurityFilterChain()方法调用
WebSecurity.build(),建造出FilterChainProxy过滤器对象
WebSecurity的创建过程:setFilterChainProxySecurityConfigurer()方法
该方法负责收集配置类对象列表webSecurityConfigurers,并创建WebSecurity:
@Value("#{}") 是SpEl表达式通常用来获取bean的属性或者调用bean的某个方法。
方法执行时,会先得到
webSecurityConfigurers并排序(所有实现了WebSecurityConfigurerAdapter的配置类实例)
new出websecurity对象,并使用Spring的容器工具初始化判断
webSecurityConfigurers内元素的@Order是否有相同,相同的order会抛异常。默认
order等于LOWEST_PRECEDENCE = 2147483647(参考Integer order = AnnotationAwareOrderComparator.lookupOrder(config))将
WebSecurityConfigurerAdapter的子类apply()放入websecurity的List<SecurityConfigurer<O, B>> configurersAddedInInitializing中。
下图是通过
AutowiredWebSecurityConfigurersIgnoreParents的getWebSecurityConfigurers()方法,获取所有实现WebSecurityConfigurer的配置类
FilterChainProxy的创建过程:springSecurityFilterChain()方法
在
springSecurityFilterChain()方法中调用webSecurity.build()创建了FilterChainProxy。
PS:根据下面代码,我们可以知道如果创建的
MySecurityConfig类没有被sping扫描到,
框架会新new 出一个WebSecurityConfigureAdapter对象,这会导致我们配置的用户名和密码失效。
我们继续看
FilterChainProxy的创建过程:
WebSecurity是一个建造者,所以我们去看这些方法build(); doBuild(); init(); configure(); performBuild();
build()方法定义在WebSecurity对象的父类AbstractSecurityBuilder中:
build()方法会调用WebSecurity对象的父类AbstractConfiguredSecurityBuilder#doBuild():
doBuild()先调用init();configure();等方法
我们上面已经得知了configurersAddedInInitializing里是所有的配置类对象
如下图,这里会依次执行配置类的configure();init()方法
doBuild()最后调用了WebSecurity对象的perfomBuild(),来创建了FilterChainProxy对象
performBuild()里遍历securityFilterChainBuilders建造者列表
把每个SecurityBuilder建造者对象构建成SecurityFilterChain实例
最后创建并返回FilterChainProxy
securityFilterChainBuilders建造者列表是什么时候初始化的呢
这时候要注意到
WebSecurityConfigurerAdapter,这个类的创建了HttpSecurity并放入了securityFilterChainBuilders
WebSecurityConfigurerAdapter是一个安全配置器,我们知道建造者在performBuild()之前都会把循环调用安全配置器的init();configure();方法,然后创建HttpSecurity并放入自己的securityFilterChainBuilders里。
PS: 前面已经提到了,在
WebSecurity初始化时,会依次将WebSecurityConfigurerAdapter的子类放入WebSecurity。
public abstract class WebSecurityConfigurerAdapter implements
WebSecurityConfigurer<WebSecurity> {
}
public interface WebSecurityConfigurer<T extends SecurityBuilder<Filter>> extends
SecurityConfigurer<Filter, T> {
}
系列文章:《深入浅出Spring Security(一):三句话解释框架原理》
本文链接:《深入浅出Spring Security(二):FilterChainProxy的创建过程》
系列文章:《深入浅出Spring Security(三):FilterChainProxy的运行过程》