Spring Security 實戰干貨:自定義配置類入口WebSecurityConfigurerAdapter


1. 前言

今天我們要進一步的的學習如何自定義配置 Spring Security 我們已經多次提到了 WebSecurityConfigurerAdapter ,而且我們知道 Spring Boot 中的自動配置實際上是通過自動配置包下的 SecurityAutoConfiguration 總配置類上導入的 Spring Boot Web 安全配置類 SpringBootWebSecurityConfiguration 來配置的。所以我們就拿它開刀。如果還是一頭霧水建議通過 https://felord.cn 查看 Spring Security 實戰

2. 自定義 Spring Boot Web 安全配置類

我們使用我們最擅長的 Ctrl CCtrl V 抄源碼中的 SpringBootWebSecurityConfiguration ,命名為我們自定義的 CustomSpringBootWebSecurityConfiguration :

  @Configuration
  @ConditionalOnClass(WebSecurityConfigurerAdapter.class)
  @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
  public class CustomSpringBootWebSecurityConfiguration {
  
      @Configuration
      @Order(SecurityProperties.BASIC_AUTH_ORDER)
      static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {
          @Override
          protected void configure(AuthenticationManagerBuilder auth) throws Exception {
              super.configure(auth);
          }
  
          @Override
          public void configure(WebSecurity web) throws Exception {
              super.configure(web);
          }
  
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              super.configure(http);
          }
      }
  }

相信已經有人注意到了上面 DefaultConfigurerAdapter 中我覆寫(@Override)了三個方法,我們一般會通過自定義配置這三個方法來自定義我們的安全訪問策略。

2.1 認證管理器配置方法

void configure(AuthenticationManagerBuilder auth) 用來配置認證管理器AuthenticationManager。說白了就是所有 UserDetails 相關的它都管,包含 PasswordEncoder 密碼機。如果你不清楚可以通過 Spring Security 中的 UserDetail 進行了解。本文對 AuthenticationManager 不做具體分析講解,后面會有專門的文章來講這個東西 。 可通過 Spring Security 實戰系列 進行學習。

2.2 核心過濾器配置方法

void configure(WebSecurity web) 用來配置 WebSecurity 。而 WebSecurity 是基於 Servlet Filter 用來配置 springSecurityFilterChain 。而 springSecurityFilterChain 又被委托給了 Spring Security 核心過濾器 Bean DelegatingFilterProxy 。 相關邏輯你可以在 WebSecurityConfiguration 中找到。我們一般不會過多來自定義 WebSecurity , 使用較多的使其ignoring() 方法用來忽略 Spring Security 對靜態資源的控制。

2.3 安全過濾器鏈配置方法

void configure(HttpSecurity http) 這個是我們使用最多的,用來配置 HttpSecurityHttpSecurity 用於構建一個安全過濾器鏈 SecurityFilterChainSecurityFilterChain 最終被注入核心過濾器HttpSecurity 有許多我們需要的配置。我們可以通過它來進行自定義安全訪問策略。所以我們單獨開一章來講解這個東西。

3. HttpSecurity 配置

HttpSecurity 是后面幾篇文章的重點,我們將實際操作它來實現一些實用功能。所以本文要着重介紹它。

3.1 默認配置

 	protected void configure(HttpSecurity http) throws Exception {
 		logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
 
 		http
 			.authorizeRequests()
 				.anyRequest().authenticated()
 				.and()
 			.formLogin().and()
 			.httpBasic();
 	}

上面是 Spring SecuritySpring Boot 中的默認配置。通過以上的配置,你的應用具備了一下的功能:

  • 所有的請求訪問都需要被授權。
  • 使用 form 表單進行登陸(默認路徑為/login),也就是前幾篇我們見到的登錄頁。
  • 防止 CSRF 攻擊、 XSS 攻擊。
  • 啟用 HTTP Basic 認證

3.2 常用方法解讀

HttpSecurity 使用了builder 的構建方式來靈活制定訪問策略。最早基於 XML 標簽對 HttpSecurity 進行配置。現在大部分使用 javaConfig方式。常用的方法解讀如下:

方法 說明
openidLogin() 用於基於 OpenId 的驗證
headers() 將安全標頭添加到響應,比如說簡單的 XSS 保護
cors() 配置跨域資源共享( CORS )
sessionManagement() 允許配置會話管理
portMapper() 允許配置一個PortMapper(HttpSecurity#(getSharedObject(class))),其他提供SecurityConfigurer的對象使用 PortMapper 從 HTTP 重定向到 HTTPS 或者從 HTTPS 重定向到 HTTP。默認情況下,Spring Security使用一個PortMapperImpl映射 HTTP 端口8080到 HTTPS 端口8443,HTTP 端口80到 HTTPS 端口443
jee() 配置基於容器的預認證。 在這種情況下,認證由Servlet容器管理
x509() 配置基於x509的認證
rememberMe 允許配置“記住我”的驗證
authorizeRequests() 允許基於使用HttpServletRequest限制訪問
requestCache() 允許配置請求緩存
exceptionHandling() 允許配置錯誤處理
securityContext() 在HttpServletRequests之間的SecurityContextHolder上設置SecurityContext的管理。 當使用WebSecurityConfigurerAdapter時,這將自動應用
servletApi() 將HttpServletRequest方法與在其上找到的值集成到SecurityContext中。 當使用WebSecurityConfigurerAdapter時,這將自動應用
csrf() 添加 CSRF 支持,使用WebSecurityConfigurerAdapter時,默認啟用
logout() 添加退出登錄支持。當使用WebSecurityConfigurerAdapter時,這將自動應用。默認情況是,訪問URL”/ logout”,使HTTP Session無效來清除用戶,清除已配置的任何#rememberMe()身份驗證,清除SecurityContextHolder,然后重定向到”/login?success”
anonymous() 允許配置匿名用戶的表示方法。 當與WebSecurityConfigurerAdapter結合使用時,這將自動應用。 默認情況下,匿名用戶將使用org.springframework.security.authentication.AnonymousAuthenticationToken表示,並包含角色 “ROLE_ANONYMOUS”
formLogin() 指定支持基於表單的身份驗證。如果未指定FormLoginConfigurer#loginPage(String),則將生成默認登錄頁面
oauth2Login() 根據外部OAuth 2.0或OpenID Connect 1.0提供程序配置身份驗證
requiresChannel() 配置通道安全。為了使該配置有用,必須提供至少一個到所需信道的映射
httpBasic() 配置 Http Basic 驗證
addFilterBefore() 在指定的Filter類之前添加過濾器
addFilterAt() 在指定的Filter類的位置添加過濾器
addFilterAfter() 在指定的Filter類的之后添加過濾器
and() 連接以上策略的連接器,用來組合安全策略。實際上就是"而且"的意思

4. 總結

到今天為止,我們已經由淺入深學習了很多關於 Spring Security 的知識。已經具有開始自定義來實現一些實用的功能了,在后面的文章開始我們將結合實際開發場景進行一些實戰操作。敬請關注公眾號:Felordcn 以第一時間獲取相關教程。

關注公眾號:Felordcn獲取更多資訊

個人博客:https://felord.cn


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM