Java 後端應用程式使用 Spring-security 實現基於 JWT 的身份驗證和授權,這是一個概念驗證專案,利用 Spring-security 實現基於 JWT 的身份驗證、API 訪問控制、Token 撤銷和洩露密碼檢測。
新發布的 Spring Security 6.3 版本新增了密碼洩露檢測功能,本專案提供的預設實現在底層使用了Have I Been Pwned API 。
向安全端點發出的任何請求都會被 JwtAuthenticationFilter.java 攔截,JwtAuthenticationFilter 會新增到安全過濾器鏈中,
並在 SecurityConfiguration.java 中進行配置。自定義過濾器負責驗證傳入訪問令牌的真實性並填充安全上下文。
關鍵元件:
- 公共 API 宣告:ApiEndpointSecurityInspector.java
- Token配置:TokenConfigurationProperties.java
- Token生成:JwtUtility.java
公共 API 宣告
任何需要公開的 API 都可以用@PublicEndpoint進行註釋。自定義安全過濾器不會評估對已配置 API 路徑的請求,其邏輯由ApiEndpointSecurityInspector.java控制。
下面是一個宣告為公共的示例控制器方法,它將免於身份驗證檢查:
@PublicEndpoint |
Token生成和配置
應用程式使用訪問令牌 (JWT) 和重新整理令牌,身份驗證成功後,這兩個令牌都會返回給客戶端。JWT 使用 RS512 非對稱金鑰對進行簽名和驗證,其中私鑰(PKCS#8 格式)用於簽名,相應的公鑰用於在呼叫私有端點時進行驗證,這些操作由JwtUtility.java處理。
重新整理令牌是RefreshTokenGenerator生成的隨機 256 位值,並由AuthenticationService根據使用者識別符號儲存在快取中。
可以在活動檔案中配置令牌有效性/到期時間(以分鐘為單位)和非對稱金鑰對.yml。配置的值填充在TokenConfigurationProperties中並由應用程式引用。以下是示例程式碼片段。
com: |
API 訪問控制
應用程式根據使用者在系統中的當前狀態實施訪問控制。相應的許可權嵌入到生成的 JWT 中,從而實現無狀態的訪問控制和授權過程。
洩露密碼檢測
為了保護使用者帳戶免遭在資料洩露中暴露的易受攻擊的密碼攻擊,該專案使用了 中新增的洩露密碼檢測功能spring-security:6.3。提供的預設實現在底層使用了Have I Been Pwned API 。
洩露密碼檢查在兩個關鍵場景中進行:
- 使用者建立:透過使用者建立 API 註冊新使用者時,將檢查提供的密碼。
- 使用者登入:即使在建立使用者時密碼未被洩露,但密碼也可能在之後被洩露。為了解決這個問題,登入 API 還加入了密碼洩露檢查。
如果在上述任何情況下檢測到密碼被洩露,伺服器將響應以下錯誤:
{ |
為了在登入期間恢復密碼洩露的情況,/users/reset-password我們公開了一個新的 API 端點 PUT。此端點接受以下請求主體負載:
{ |
在允許重置密碼之前,還會檢查新密碼是否被破解。