在 RESTful API 中使用 Spring Security

介紹

在篇文章中,我們將學習如何使用 Spring 和 Spring Security 5 提供更安全的 REST API。

我們將使用 Java 配置來設置安全性,並將使用登錄和 Cookie 方法進行身份驗證。

啟用Spring Security

Spring Security 的體系結構完全基於 Servlet 過濾器。

註冊 Spring Security 過濾器的最簡單選擇是添加 @EnableWebSecurity 註解到我們的 config 類:

在 RESTful API 中使用 Spring Security

對於非 Spring Boot 應用,我們可以擴展
AbstractSecurityWebApplicationInitializer 並在其構造函數中傳遞 config 類:

在 RESTful API 中使用 Spring Security

或者我們可以在應用的 web.xml 中聲明它:

在 RESTful API 中使用 Spring Security

我們應該將過濾器命名為 “springSecurityFilterChain”,以匹配容器中 Spring Security 創建的默認 bean。

注意,定義的過濾器不是實現安全邏輯的實際類。相反,它是一個委託 filterproxy,將篩選器的方法委託給內部 bean。這樣做是為了讓目標 bean 仍然能夠從 Spring 上下文的生命週期和靈活性中受益。

Spring Security Java配置

我們可以完全在 Java 類中進行安全配置,方法是創建一個擴展了
WebSecurityConfigurerAdapter 的配置類,並用 @EnableWebSecurity 對其進行註釋:

在 RESTful API 中使用 Spring Security

現在,讓我們在 SecurityJavaConfig 中創建不同角色的用戶,我們將使用這些用戶來驗證我們的 API 端點:

在 RESTful API 中使用 Spring Security

接下來,讓我們為我們的 API 端點配置安全性:

在 RESTful API 中使用 Spring Security

Http

在我們的代碼實現中,我們使用 antMatchers 創建安全的映射 /api/foos 和 /api/admin/**。
任何經過身份驗證的用戶都可以訪問 /api/foos。另一方面,/api/admin/** 只能被 admin 角色用戶訪問。

在標準的 web 應用程序中,當未經身份驗證的客戶機試圖訪問受保護的資源時,身份驗證過程可能會自動觸發。此過程通常重定向到登錄頁面,以便用戶可以輸入憑據。

然而,對於 REST Web 服務,這種行為沒有多大意義。我們應該能夠僅通過對正確URI的請求進行身份驗證,如果用戶沒有經過身份驗證,則所有請求都應該失敗,並帶有401未授權狀態碼。

Spring Security 使用 Entry Point 的概念處理身份驗證過程的自動觸發 ——這是配置中必需的一部分,可以通過 authenticationEntryPoint 方法注入。

在觸發時簡單地返回 401:

在 RESTful API 中使用 Spring Security

用於 REST 的登錄表單

有多種方法可以對 REST API 進行身份驗證。 Spring Security 提供的默認值之一是表單登錄,它使用身份驗證處理過濾器
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter。

formLogin 元素將創建這個過濾器,並提供額外的方法 successHandler 和 failureHandler 來分別設置我們的自定義身份驗證成功和失敗處理程序。

身份驗證應該返回 200 而不是 301

默認情況下,表單登錄將使用 301 狀態碼來回答成功的身份驗證請求,這在登錄後需要重定向的實際登錄表單的上下文中是有意義的。

然而,對於 RESTful web 服務,成功驗證所需的響應應該是 200 OK。

為此,我們在表單登錄篩選器中注入一個自定義身份驗證成功處理程序,以替換默認的處理程序。新的處理程序實現與默認的 org.springframe
.security.web.authentication 完全相同的登錄。


SavedRequestAwareAuthenticationSuccessHandler 有一個明顯的區別-它刪除了重定向邏輯:

在 RESTful API 中使用 Spring Security

身份驗證管理器和提供程序

身份驗證過程使用內存中的提供者來執行身份驗證。

我們創建了兩個用戶,即具有 USER 角色的 user 和具有 ADMIN 角色的 admin。

最後—針對正在運行的 REST 服務進行身份驗證

現在,讓我們看看如何針對不同的用戶針對REST API進行身份驗證。

登錄的 URL 為 /login,一個簡單的 curl 命令,用於對名為 user 和密碼 userPass 的用戶執行登錄。

在 RESTful API 中使用 Spring Security

此請求將返回 Cookie,我們可以將其用於針對 REST 服務的任何後續請求。

我們可以使用 curl 進行認證,並將它接收到的 cookie 保存在一個文件中

在 RESTful API 中使用 Spring Security

然後我們可以使用文件中的 cookie 來做進一步的認證請求:

在 RESTful API 中使用 Spring Security

由於用戶可以訪問 /api/foos/* 端點,這個經過身份驗證的請求將正確地得到一個 200 OK :

在 RESTful API 中使用 Spring Security

類似地,對於 admin 用戶,我們可以使用 curl 進行認證:

在 RESTful API 中使用 Spring Security

然後更新 cookies 訪問管理端點 /api/admin/* :

在 RESTful API 中使用 Spring Security

由於管理用戶可以訪問端點 /api/admin/*,所有響應成功:

在 RESTful API 中使用 Spring Security

XML 配置

我們也可以用 XML 代替 Java 配置來完成以上所有的安全配置:

在 RESTful API 中使用 Spring Security

結束語

在本教程中,我們介紹了使用 Spring security 5 實現 RESTful 服務的基本安全配置和實現。

我們學習瞭如何完全通過Java配置為 REST API 進行安全配置,並研究了其 web.xml 配置替代方案。

接下來,我們討論瞭如何為受保護的應用程序創建用戶和角色,以及如何將這些用戶映射到應用程序的特定端點。

最後,我們還研究瞭如何創建自定義身份驗證入口點和自定義成功處理程序,以便在控制安全性方面為應用程序提供更好的靈活性。

感謝大家的觀看,歡迎關注我的頭條號。


分享到:


相關文章: