Spring Security 的功能點入口是 FilterChainProxy,在 FilterChainProxy 中管理着多個過濾器鏈 SecurityFilterChain。
Spring Security 中是通過調用 HttpSecurity 的 build() 方法實例化 SecurityFilterChain。
過濾器鏈 SecurityFilterChain 是多個過濾器的集合。(注意區分 Servlet 容器中的 Filter 過濾器 和 Spring Security 的 Security Filter 過濾器,參考前面的文章 DelegatingFilterProxy與FilterChainProxy關系 )
FilterChainProxy 與 SecurityFilterChain 關系
二者關系參考下圖(摘自 Spring Security 官網的圖):
在 FilterChainProxy 里面有個屬性為 filterChains,這是一個 List 集合,其中的元素就是 SecurityFilterChain
在 SecurityFilterChain 中定義了 getFilters() 方法,其返回值是一個 List 集合,其中的元素是 Filter
SecurityFilterChain 的唯一實現類是 DefaultSecurityFilterChain
SecurityFilterChain 初始化
FilterChainProxy 的初始化過程在前面的文章 啟動時初始化FilterChainProxy 已經提到了。那 SecurityFilterChain 是如何初始化的?
這需要重新查看 webSecurity.build() 方法實例化 FilterChainProxy 的邏輯,參考前面的文章 通過WebSecurity構建FilterChainProxy 。
在調用 webSecurity.build() 方法時,會走到下面兩個重要的節點:
init
查看 init() 的方法體:
這里會調用 configurer.init((B) this) 方法,這里 configurer 其實是 WebSecurityConfigurerAdapter 實例,查看 WebSecurityConfigurerAdapter 的 init() 方法體:
通過上面的源碼可以看到:
- 先創建了一個 HttpSecurity 的實例
- 調用 WebSecurity 的 addSecurityFilterChainBuilder 方法
接着查看 WebSecurity 的 addSecurityFilterChainBuilder 方法體:
可以看到 HttpSecurity 的實例被加到 WebSecurity 的 securityFilterChainBuilders 屬性中,這里的 securityFilterChainBuilders 是一個 List 集合 。
這樣 init 方法就執行完了。
performBuild
接着查看 performBuild() 方法體:
通過上面源碼可以看到:
- 先創建了一個名為 securityFilterChain 的 List
- 遍歷 securityFilterChainBuilders 中的元素,然后調用元素中 build() 方法,將返回值添加到 securityFilterChain 中
- 最后將 securityFilterChain 放到 FilterChainProxy 中
在上一步中 init 方法中可以知道 securityFilterChainBuilders 中的元素是 HttpSecurity,調用 HttpSecurity 的 build() 方法返回 SecurityFilterChain 實例。
至此 SecurityFilterChain 初始化就完成了。