核心关注FilterChainProxy的生成。
1、为webSecurity设置webSecurityConfigurers
org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration#setFilterChainProxySecurityConfigurer
通过#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}查找WebSecurityConfigurer.class类型的bean,我们自定义的SecurityConfig 就是。
2、生成filter chain
2.1 bean声明,最终返回springSecurityFilterChain
org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration#springSecurityFilterChain
3、webSecurity build操作
org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder#doBuild
3.1 根据自定义的WebSecurityConfigurerAdapter进行build操作,我们这里是SecurityConfig。SecurityConfig的init过程中见第4步骤说明。
3.2 调用performBuild
生成filter chain,包括FilterChainProxy
3.2.1 FilterChainProxy包含两部分,一部分是忽略请求列表,每一个配置url就是一个DefaultSecurityFilterChain;一部分是需要鉴权的chain,包含httpSecurity filter列表,是核心功能。
filters 在请求时候根据请求信息动态匹配。
3.2.2 部分filter说明如下
https://docs.spring.io/spring-security/site/docs/4.2.2.RELEASE/reference/htmlsingle/#filter-security-interceptor
Table 6.1. Standard Filter Aliases and Ordering
Alias |
Filter Class |
Namespace Element or Attribute |
CHANNEL_FILTER |
ChannelProcessingFilter(协议跳转) |
http/intercept-url@requires-channel |
SECURITY_CONTEXT_FILTER |
SecurityContextPersistenceFilter(SecurityContext保存到session中,给下一次web请求使用) |
http |
CONCURRENT_SESSION_FILTER |
ConcurrentSessionFilter(存放session信息,刷新请求时间;以及session失效后,触发登出操作) |
session-management/concurrency-control |
HEADERS_FILTER |
HeaderWriterFilter |
http/headers |
CSRF_FILTER |
CsrfFilter(csrf校验处理) |
http/csrf |
LOGOUT_FILTER |
LogoutFilter(登出逻辑实现) |
http/logout |
X509_FILTER |
X509AuthenticationFilter(X509证书认证) |
http/x509 |
PRE_AUTH_FILTER |
AbstractPreAuthenticatedProcessingFilterSubclasses |
N/A |
CAS_FILTER |
CasAuthenticationFilter(cas 单点登录) |
N/A |
FORM_LOGIN_FILTER |
UsernamePasswordAuthenticationFilter(用户名密码认证) |
http/form-login |
BASIC_AUTH_FILTER |
BasicAuthenticationFilter(basic认证) |
http/http-basic |
SERVLET_API_SUPPORT_FILTER |
SecurityContextHolderAwareRequestFilter |
http/@servlet-api-provision |
JAAS_API_SUPPORT_FILTER |
JaasApiIntegrationFilter(Jaas认证) |
http/@jaas-api-provision |
REMEMBER_ME_FILTER |
RememberMeAuthenticationFilter(remeber me 实现,借助cookie) |
http/remember-me |
ANONYMOUS_FILTER |
AnonymousAuthenticationFilter(无登录,补充一个默认认证) |
http/anonymous |
SESSION_MANAGEMENT_FILTER |
SessionManagementFilter(多会话管理) |
session-management |
EXCEPTION_TRANSLATION_FILTER |
ExceptionTranslationFilter(异常处理,页面跳转) |
http |
FILTER_SECURITY_INTERCEPTOR |
FilterSecurityInterceptor(权限控制) |
http |
SWITCH_USER_FILTER |
SwitchUserFilter |
N/A |
4、WebSecurityConfigurerAdapter init操作
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#init
4.1 生成AuthenticationManager, 执行自定义configure(localConfigureAuthenticationBldr)
4.1.1 disableLocalConfigureAuthenticationBldr为false
localConfigureAuthenticationBldr也是一个SecurityBuilder,构造返回ProviderManagement,包含多个AuthenticationProvider,用于登录鉴权处理,通过自定义SecurityConfig configure(AuthenticationManagerBuilder auth) 追加AuthenticationProvider。
4.1.2 disableLocalConfigureAuthenticationBldr为true
该逻辑中,走authenticationConfiguration逻辑,如果没有AuthenticationProvider bean,会创建DaoAuthenticationProvider。
4.2 执行自定义 configure(http) ,追加http相关配置,并将SecurityConfigurer追加到configurers集合中,如http中.logout()就会创建一个LogoutConfigurer放到集合中。
这些配置最终会生成filter,filter顺序是固定的,org.springframework.security.config.annotation.web.builders.FilterComparator#FilterComparator中存放了初始顺序。
4.3 最终追加http到web的securityFilterChainBuilders,用于后续filter生成等处理。
5、WebSecurityConfigurerAdapter configure 操作
该操作默认空操作,可以修改WebSecurity相关逻辑。
6、spring boot FilterChainProxy自动注入
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration#securityFilterChainRegistration 自动注入springSecurityFilterChain filter,也就是FilterChainProxy