1. 概述
Spring Security 框架提供了 WebSecurity 和 HttpSecurity 類,以提供全局和資源特定機制,從而限制對 API 和資產的訪問。 WebSecurity 類有助於在全局層面配置安全,而 HttpSecurity 提供了用於為特定資源配置安全性的方法。
在本教程中,我們將詳細瞭解 HttpSecurity 和 WebSecurity 的關鍵用法。 此外,我們還將看到這兩種類的區別。
2. <em>HttpSecurity</em>
The <em>HttpSecurity</em> 類用於配置特定 HTTP 請求的安全性。
Also, it permits using the <em>requestMatcher() </em> 方法來限制安全配置應用於特定的 HTTP 端點。
Furthermore, it provides flexibility to configure authorization for a specific HTTP request. We can create a role-based authentication with the <em>hasRole() </em> 方法。
Here’s an example code that uses the <em>HttpSecurity</em> 類來限制對“/admin/**”的訪問:
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((authorize) -> authorize.requestMatchers("/admin/**")
.authenticated()
.anyRequest()
.permitAll())
.formLogin(withDefaults());
return http.build();
}在上述代碼中,我們使用 HttpSecurity 類來限制對 “/admin/**” 端點的訪問。任何對該端點的請求都需要在訪問之前進行身份驗證。
此外,HttpSecurity 提供了配置受限端點授權的方法。讓我們修改我們的示例代碼,僅允許具有管理員角色的用户訪問 “/admin/**” 端點:
// ...
http.authorizeHttpRequests((authorize) -> authorize.requestMatchers("/admin/**").hasRole("ADMIN")
// ...在此,我們通過僅允許具有“ADMIN”角色的用户訪問端點,為請求提供更多安全層。
此外,HttpSecurity 類有助於在 Spring Security 中配置 CORS 和 CSRF 保護。
3. WebSecurity
WebSecurity 類有助於在 Spring 應用程序中以全局級別配置安全性。我們可以通過暴露 WebSecurityCustomizer Bean 來自定義WebSecurity。
與 HttpSecurity 類不同,HttpSecurity 類有助於為特定 URL 模式或單個資源配置安全規則,WebSecurity 配置則全局應用於所有請求和資源。
此外,它還提供方法用於調試 Spring Security 過濾器日誌記錄、忽略某些請求和資源的安全性檢查,或為 Spring 應用程序配置防火牆。
3.1. 忽略() 方法
此外,WebSecurity 類還提供了一個名為 ignoring() 的方法。 ignoring() 方法允許 Spring Security 忽略一個 RequestMatcher 實例。 建議註冊請求僅限於靜態資源。
下面是一個使用 ignoring() 方法忽略 Spring 應用程序中靜態資源的示例:
@Bean
WebSecurityCustomizer ignoringCustomizer() {
return (web) -> web.ignoring().requestMatchers("/resources/**", "/static/**");
}在這裏,我們使用 ignoring() 方法來繞過靜態資源的安全檢查。
值得注意的是,Spring 建議 ignoring() 方法不應用於動態請求,而僅用於靜態資源,因為它繞過了 Spring Security 過濾器鏈。 這種做法適用於 CSS、圖像等靜態資產。
但是,動態請求需要通過身份驗證和授權來提供不同的訪問規則,因為它們攜帶敏感數據。 此外,如果我們完全忽略動態端點,我們將失去對應用程序的整體安全控制,這可能會使應用程序容易受到諸如跨站請求偽造攻擊或 SQL 注入等攻擊。
3.2. debug() 方法
此外,debug() 方法允許將 Spring Security 內部日誌記錄到日誌中,以協助調試配置或請求失敗。這在診斷安全規則時,無需使用調試器也可能很有幫助。
以下是一個使用 debug() 方法調試安全性的示例代碼:
@Bean
WebSecurityCustomizer debugSecurity() {
return (web) -> web.debug(true);
}此處,我們調用 debug() 函數於 WebSecurity 實例上,並將其設置為 true。 這全局啓用所有安全過濾器中的調試日誌。
3.3. httpFirewall() 方法
WebSecurity 類還提供 httpFirewall() 方法,用於為 Spring 應用程序配置防火牆。該方法有助於設置全局允許的規則。
讓我們使用 httpFirewall() 方法來確定應用程序中允許的 HTTP 方法:
@Bean
HttpFirewall allowHttpMethod() {
List<String> allowedMethods = new ArrayList<String>();
allowedMethods.add("GET");
allowedMethods.add("POST");
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowedHttpMethods(allowedMethods);
return firewall;
}
@Bean
WebSecurityCustomizer fireWall() {
return (web) -> web.httpFirewall(allowHttpMethod());
}
在上述代碼中,我們暴露了 HttpFirewall Bean,用於配置 HTTP 方法的防火牆。默認情況下,允許 DELETE、GET、HEAD、OPTIONS、PATCH、POST 和 PUT 方法。但是,在我們的示例中,我們配置應用程序僅允許 GET 和 POST 方法。
我們創建了一個 StrictHttpFirewall 對象,並調用其 setAllowedHttpMethods 方法。該方法接受一個包含允許的 HTTP 方法的列表作為參數。
最後,我們暴露了一個 WebSecurityCustomizer Bean,通過將 allowHttpMethod 方法傳遞給 httpFirewall 方法,全局配置防火牆。任何非 GET 或 POST 的請求都會因為防火牆而返回 HTTP 錯誤。
4. 關鍵差異
<em>HttpSecurity</em> 和 <em>WebSecurity</em> 的配置並非相互衝突,而是可以協同工作,為提供全局和資源特定級別的安全規則提供支持。
然而,如果同時在兩者中配置了相似的安全規則,則 <em>WebSecurity</em> 的配置優先級更高。
@Bean
WebSecurityCustomizer ignoringCustomizer() {
return (web) -> web.ignoring().antMatchers("/admin/**");
}
// ...
http.authorizeHttpRequests((authorize) -> authorize.antMatchers("/admin/**").hasRole("ADMIN")
// ...在這裏,我們全局忽略“/admin/**”路徑,但在 WebSecurity 配置中也配置了對“/admin/**”路徑的訪問規則,同時在 HttpSecurity 中配置訪問規則。
在這種情況下,WebSecurity 的 ignoring() 配置將覆蓋 HttpSecurity 的授權規則對“/admin/**”路徑的授權。
此外,在 SecurityFilterChain, WebSecurity 配置在構建過濾器鏈時首先執行。然後評估 HttpSecurity 的規則。
下表顯示了 HttpSecurity 和 WebSecurity 類之間的主要差異:
| 功能 | WebSecurity | HttpSecurity |
| 作用域 | 全局默認安全規則 | 資源特定安全規則 |
| 示例 | 防火牆配置、路徑忽略、調試模式 | URL 規則、授權、CORS、CSRF |
| 配置方式 | 按資源條件配置 | 全局可重用安全配置 |
5. 結論
在本文中,我們學習了 <em>HttpSecurity</em> 和 <em>WebSecurity</em> 的關鍵用法,並提供了示例代碼。 此外,我們還了解了 <em>HttpSecurity</em> 如何允許為特定資源配置安全規則,而 <em>WebSecurity</em> 則設置全局默認規則。
將兩者結合使用,可以靈活地在全局和資源級別上安全地保護 Spring 應用程序。