1、POM依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>2.2.0 RELEASE<version> </dependency>
2、 默認配置
添加依賴後,便可實現Spring Security的默認配置。
spring-boot-autoconfigurer項目下的WebSecurityEnablerConfiguration 自動加載Spring Security 默認配置[WebSecurityConfigurerAdapter]web
Spring Security 默認配置主要以下:spring
3、過濾器鏈
若是你是第一次使用Spring Security,必定會以爲很cool!Spring Security是如何作到的。api
Spring Security主要基於過濾器(責任鏈模式)和AOP實現。session
過濾器的結構大體是這麼個意思
app
那麼FilterChainProxy是如何構建出來的?異步
Spring Security提供了兩個接口ide
Spring Security基於構造器模式,經過SecurityBuilder構造器構建對象,而SecurityConfigurer則負責對構造器進行初始化和配置。spring-boot
FilterChainProxy經過WebSecurity構造器構建。post
默認的WebSecurity在WebSecurityConfiguration.setFilterChainProxySecurityConfigurer()完成初始化,
並從Spring容器中獲取SecurityConfigurers<Filter, WebSecurity>列表實現對構造器的初始化和配置。ui
package org.springframework.security.config.annotation.web.configuration; @Configuration(proxyBeanMethods = false) public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware { private WebSecurity webSecurity; private List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers; ... // 經過WebSecurity完成FilterChainProxy構建並註冊到Spring容器 @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) public Filter springSecurityFilterChain() throws Exception { ... return webSecurity.build(); } ... // 1 從spring容器中獲取SecurityConfigurers<Filter, WebSecurity>配置列表 // 2 建立WebSecurity // 3 將配置列表添加到WebSecurity @Autowired(required = false) public void setFilterChainProxySecurityConfigurer( ObjectPostProcessor<Object> objectPostProcessor, @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers) throws Exception { webSecurity = objectPostProcessor .postProcess(new WebSecurity(objectPostProcessor)); ... for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) { webSecurity.apply(webSecurityConfigurer); } ... } ... }
SecurityFilterChain經過HttpSecurity構造器構建。
默認的HttpSecurity在WebSecurityConfigurerAdapter.init()完成初始化,該方法是WebSecurity在構建FilterChainProxy的過程當中觸發,並最終完成SecurityFilterChain構建添加到FilterChainProxy中。
package org.springframework.security.config.annotation.web.configuration; @Order(100) public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> { ... private HttpSecurity http; private boolean disableDefaults; ... // 初始化WebSecurity,在WebSecurity構建FilterChainProxy的過程當中觸發 public void init(final WebSecurity web) throws Exception { final HttpSecurity http = getHttp(); web.addSecurityFilterChainBuilder(http)...; } ... // 配置WebSecurity public void configure(WebSecurity web) { } ... // 建立並返回HttpSecurity @SuppressWarnings({ "rawtypes", "unchecked" }) protected final HttpSecurity getHttp() throws Exception { if (http != null) { return http; } ... http = new HttpSecurity(objectPostProcessor, authenticationBuilder, sharedObjects); if (!disableDefaults) { http .csrf().and() .addFilter(new WebAsyncManagerIntegrationFilter()) .exceptionHandling().and() .headers().and() .sessionManagement().and() .securityContext().and() .requestCache().and() .anonymous().and() .servletApi().and() .apply(new DefaultLoginPageConfigurer<>()).and() .logout(); ClassLoader classLoader = this.context.getClassLoader(); List<AbstractHttpConfigurer> defaultHttpConfigurers = SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader); for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) { http.apply(configurer); } } configure(http); return http; } ... // 配置HttpSecurity protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic(); } ... }
下面則列出了一些"苦力"過濾器(默認過濾器列表)
固然,如下過濾器一般有對應的securityConfigurer完成構建。
構建邏輯在HttpSecurity的構建過程當中,觸發在其對應的SecurityConfigurer.configure(H http)中建立過濾器實例並添加到HttpSecurity中,最終添加到FilterChainProxy實例中。
1. WebAsyncManagerIntegrationFilter 支持集成Spring的異步調用 2. SecurityContextPersistenceFilter 從Session中獲取SecurityContext,沒有則新建,最終放入SecurityContextHolder中。 3. HeaderWriterFilter 往響應對象response中寫入Header屬性(Like X-Frame-Options, X-XSS-Protection and X- Content-Type-Options) 4. CsrfFilter csrf校驗 5. LogoutFilter 默認攔截[POST]/logout 處理登出邏輯 6. UsernamePasswordAuthenticationFilter 默認攔截[POST]/login 處理登陸認證邏輯 6.1 第一步 封裝Authentication(從request中獲取認證信息封裝爲UsernamePasswordAuthenticationToken) 6.2 第二步 獲取AuthenticationManager實例[ProviderManager] 6.3 第三步 ProviderManager基於委託者模式經過AuthenticationProvider列表完成認證 6.4 第四步 認證經過後,將Authentication放入SecurityContextHolder的SecurityContext中。 7. DefaultLoginPageGeneratingFilter 默認攔截[GET]/login 生成登陸頁面 8. DefaultLogoutPageGeneratingFilter 默認攔截[POST]/login 生成登出頁面 9. BasicAuthenticationFilter 認證Basic [Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==] 10. RequestCacheAwareFilter 用於用戶登陸成功後,從新恢復由於登陸被打斷的請求 11. SecurityContextHolderAwareRequestFilter 包裝request實現servlet api的一些接口方法isUserInRole、getRemoteUser 12. AnonymousAuthenticationFilter 匿名用戶認證、信息填充 13. SessionManagementFilter Session管理 14. ExceptionTranslationFilter 異常處理 15. FilterSecurityInterceptor 權限校驗、未登陸攔截、無權限攔截 ...
4、自定義配置