上篇回顾
- 框架的核心是一个过滤器,这个过滤器
名字
叫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的运行过程》