上篇回顧
- 框架的核心是一個過濾器,這個過濾器
名字
叫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的運行過程》