首頁 > 後端開發 > Golang > 了解 JWT 身份驗證:Spring Security 的架構​​和 Go 實現

了解 JWT 身份驗證:Spring Security 的架構​​和 Go 實現

Patricia Arquette
發布: 2024-12-01 14:15:11
原創
355 人瀏覽過

設定 JWT 無狀態身份驗證(可在此處取得)後,我想透過識別關鍵元件及其互動來了解 Spring Security 抽像下發生的情況。為了讓這種探索更具吸引力,我使用標準 HTTP 庫在 Go 中重新實作了一個最小版本。透過分解三個核心流程 - 註冊、令牌產生和受保護的資源存取 - 並在 Go 中重建它們,我開始將 Spring Security 的身份驗證模式對應到更簡單的元件。

這篇文章特別關注身份驗證流程 - 系統如何驗證使用者身份 - 而不是授權。我們將使用序列圖探索流程,這些序列圖透過 Spring Security 架構中的不同元件追蹤請求。

主要部件

系統提供三個端點:

  1. 使用者註冊:接受新使用者的使用者名稱和密碼
  2. 令牌產生(登入):當使用者使用有效憑證成功登入時建立 JWT 令牌
  3. 受保護的存取:使經過驗證的使用者能夠使用其令牌存取受保護的資源。 getAuthenticatedUser 端點作為範例,傳回經過驗證的令牌持有者的個人資料資訊

在以下部分中,我將解釋每個流程中涉及的核心元件,並為每個流程提供序列圖。

註冊流程

Understanding JWT Authentication: Spring Security

包含使用者名稱和密碼的註冊請求透過 Spring Security 過濾器鏈,由於註冊端點被配置為不需要在 SecurityConfiguration 中進行身份驗證,因此在該過濾器鏈中進行的處理最少。然後請求透過 Spring 的 DispatcherServlet,後者根據 URL 模式將其路由到 UserController 中的適當方法。請求到達 UserController 的註冊端點,其中使用者資訊與雜湊密碼一起儲存。

代幣生成流程

Understanding JWT Authentication: Spring Security

包含使用者名稱和密碼的登入要求透過 Spring Security 過濾器鏈,其中發生最少的處理,因為此端點也配置為不需要在 SecurityConfiguration 中進行身份驗證。請求透過 Spring 的 DispatcherServlet 移至 UserController 的登入端點,該端點委託給 AuthenticationManager。使用 ApplicationConfiguration 中定義的設定 bean,AuthenticationManager 根據儲存的憑證驗證提供的憑證。身份驗證成功後,UserController 使用 JwtService 產生包含使用者資訊和建立時間等元資料的 JWT 令牌,該令牌將傳回給客戶端以供後續經過驗證的請求。

受保護的資源存取流程

成功的身份驗證流程 (200)

Understanding JWT Authentication: Spring Security

身份驗證流程失敗 (401)

Understanding JWT Authentication: Spring Security

當授權標頭中包含 JWT 令牌的請求到達時,它會透過 JwtAuthenticationFilter - 自訂定義的 OncePerRequestFilter - 它使用 JwtService 處理令牌。如果有效,過濾器將透過 ApplicationConfiguration 中配置的 UserDetailsS​​ervice 檢索用戶,並在 SecurityContextHolder 中設定身份驗證。如果令牌遺失或無效,過濾器將允許請求繼續,而無需設定身份驗證。

在鏈的後面,AuthorizationFilter 檢查請求是否透過 SecurityContextHolder 進行了正確的身份驗證。當它偵測到缺少身份驗證時,它會拋出 AccessDeniedException。此異常由 ExceptionTranslationFilter 捕獲,它檢查使用者是否是匿名的,並委託給 SecurityConfiguration 中配置的 JwtAuthenticationEntryPoint 傳回 401 Unauthorized 回應。

如果所有過濾器都通過,請求將到達 Spring 的 DispatcherServlet,後者將其路由到 UserController 中的 getAuthenticatedUser 端點。此端點從過濾器鏈過程中填入的 SecurityContextHolder 檢索經過驗證的使用者資訊。

注意:Spring Security 採用豐富的過濾器和專用組件生態系統來處理各種安全問題。為了理解核心身份驗證流程,我只專注於 JWT 令牌驗證和使用者身份驗證中的關鍵參與者。

Go 實作:映射元件

Go 實作透過對應到關鍵 Spring Security 元件的簡化架構提供類似的功能:

濾鏈

  • 提供 Spring Security 過濾器鏈的最小版本
  • 依序處理每個請求的篩選器
  • 使用每個請求鏈實例(VirtualFilterChain)來實作執行緒安全

調度員

  • 映射到 Spring 的 DispatcherServlet
  • 安全過濾器處理後將請求路由到適當的處理程序

驗證上下文

  • 使用Go的上下文套件來儲存每個請求的驗證狀態
  • 映射到 Spring 的 SecurityContextHolder

JwtFilter

  • 直接相當於Spring的JwtAuthenticationFilter
  • 提取並驗證 JWT 令牌
  • 成功驗證後填入驗證上下文

驗證過濾器

  • Spring的AuthorizationFilter的簡化版
  • 專注於身份驗證
  • 檢查身份驗證上下文,如果缺失則回傳 401

JwtService

  • 類似Spring的JwtService
  • 處理令牌產生與驗證
  • 使用相同的核心 JWT 操作,但配置更簡單

測試覆蓋率

兩種實作都包含驗證金鑰驗證場景的整合測試(auth_test.go 和 AuthTest.java):

報名流程

  • 使用有效憑證成功使用者註冊
  • 重複的使用者名稱註冊嘗試

登入流程

  • 使用有效憑證成功登入
  • 嘗試使用不存在的使用者名稱登入
  • 嘗試使用錯誤密碼登入

受保護的資源存取

  • 使用有效令牌成功存取
  • 沒有 auth header 的訪問嘗試
  • 嘗試使用無效令牌格式進行存取
  • 使用過期令牌進行存取
  • 嘗試使用有效的令牌格式進行訪問,但使用者不存在

Java 實作包括詳細註釋,透過 Spring Security 的過濾器鏈解釋每個測試場景的流程。使用等效元件在 Go 實作中複製這些相同的流程。

旅程總結

我透過將 Spring Security 的 JWT 身份驗證分解為流程和測試案例來研究它。然後我將這些模式對應到 Go 元件。整合測試向我展示了請求如何流經 Spring Security 的過濾器鍊和元件。建立這些模式的簡單版本幫助我了解 Spring Security 的設計。測試證明兩種實作都以相同的方式處理身份驗證。透過分析、測試和重建,我對 Spring Security 的身份驗證工作原理有了更深入的了解。

以上是了解 JWT 身份驗證:Spring Security 的架構​​和 Go 實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板