當前位置:名人名言大全網 - 端午節短信 - 單點登錄JWT和Spring Security OAuth

單點登錄JWT和Spring Security OAuth

通過將JWT與Spring Security OAuth2結合使用,可以避免為每個請求遠程分派認證和授權服務。資源服務器只需要從授權服務器認證壹次並返回JWT。返回的JWT包含用戶的所有信息,包括權限信息。

1.什麽是JWT?

JSON Web Token(JWT)是壹個開放標準(RFC 7519)。JWT定義了壹個緊湊的、自包含的標準,旨在將各個主題的信息打包成JSON對象。主題信息通過數字簽名進行加密和驗證。HMAC算法或RSA(公鑰/私鑰非對稱加密)算法常用於JWT簽名,安全性高。

2.JWT的結構

JWT的結構由三部分組成:報頭、有效載荷和簽名。所以JWT通常的格式是xxxxx.yyyyy.zzzzz

2.1.頁眉

報頭通常由兩部分組成:令牌類型(即JWT)和使用的算法類型,如HMAC、SHA256和RSA。例如:

使用Base64作為JWT的第壹部分,不建議將敏感信息放在JWT的報頭中。

2.2.有效載荷

以下是有效負載部分的示例:

作為JWT的第二部分,不建議將敏感信息放在JWT的有效載荷中。

2.3.簽名

要創建簽名部分,您需要用密鑰加密Base64編碼的頭和有效負載。加密算法的公式如下:

簽名可用於驗證郵件在傳遞過程中是否已被更改。對於用私鑰簽名的令牌,它還可以驗證JWT的發送者是否是它所說的那個人。

3.JWT是如何運作的

客戶端獲得JWT後,對於後續的每個請求,不再需要通過授權服務判斷請求用戶和用戶的權限。在微服務系統中,使用JWT可以實現單點登錄。認證流程圖如下:

4.案例工程結構

工程原理示意圖如下:

5.構建授權服務授權服務。

UserServiceDetail.java

UserRepository.java

實體類用戶需要實現UserDetails接口,實體類角色需要實現GrantedAuthority接口。

User.java

Role.java

Jks文件生成需要使用Java keytool工具,保證Java環境變量ok。輸入以下命令:

其中,-alias選項是別名,-keyalg是加密算法,-keypass和-storepass是密碼選項,-keystore是jks的文件名,-validity是配置的jks文件的過期時間(單位:天)。

生成的jks文件被用作私鑰,該私鑰只允許由授權服務持有,並用於通過加密生成JWT。只需將生成的jks文件放在auth-service模塊的src/main/resource目錄下即可。

對於諸如用戶服務之類的資源服務,需要使用jks的公鑰來解密JWT。獲取jks文件公鑰的命令如下:

該命令要求安裝openSSL下載地址,然後手動將openssl.exe的安裝目錄配置到環境變量中。

輸入密碼fzp123後,會顯示很多信息。只需提取公鑰,如下所示:

創建壹個新的public.cert文件,將上述公鑰信息復制到public.cert文件中並保存。並將該文件放在資源服務(如user-service)的src/main/resources目錄中。至此,auth-service已經建立。

Maven在編譯項目時可能會編譯jks文件,導致jks文件亂碼,最終無法使用。您需要向pom.xml文件添加以下內容:

6.構建用戶服務資源服務

註入壹個JwtTokenStore類型的Bean,初始化JWT轉換器JwtAccessTokenConverter,並設置用於解密JWT的公鑰。

要配置資源服務的身份驗證管理,除了用於註冊和登錄的接口之外,所有接口都需要進行身份驗證。

創建壹個新的配置類GlobalMethodSecurityConfig,並通過註釋@EnableGlobalMethodSecurity打開方法級安全驗證。

將授權服務模塊的用戶、角色和用戶資料檔案庫復制到該模塊。寫壹個方法在服務層的userService中插入壹個用戶,代碼如下:

為用戶密碼加密配置工具類BPwdEncoderUtil:

為用戶註冊實現壹個API接口/用戶/註冊。代碼如下:

在服務層的userServicedetail中添加壹個login()方法,代碼如下:

AuthServiceClient作為佯裝客戶端,通過遠程調用auth-service interface/oauth/token獲得JWT。在request /oauth/token的API接口中,需要將授權信息、認證類型(grant_type)、用戶名(username)和密碼(password)傳入請求頭,代碼如下:

其中AuthServiceHystrix是AuthServiceClient的保險絲,代碼如下:

JWT包含access_token、token_type、refresh_token等信息,代碼如下:

UserLoginDTO包含用戶和JWT成員屬性,用於返回數據的實體:

登錄異常類UserLoginException

全局異常處理部分類ExceptionHandle

在Web層的UserController類中添加壹個登錄API接口/user/login,如下所示:

啟動三個服務:尤裏卡服務、授權服務和用戶服務。

7.使用郵遞員測試

由於沒有權限,訪問被拒絕。在數據庫中手動添加ROLE_ADMIN權限,並將其與用戶相關聯。再次登錄並獲取JWT,然後再次請求/user/foo接口。

在這種情況下,用戶通過登錄界面獲得授權服務的加密JWT。在用戶成功獲得JWT之後,他們需要在將來訪問資源服務的每個請求中攜帶JWT。資源服務通過公鑰解密JWT。解密成功後,可以獲得用戶信息和權限信息,從而判斷JWT對應的用戶是誰,擁有什麽權限。

壹次獲得壹個令牌,多次使用,資源服務就不再每次訪問令牌對應的用戶信息和用戶權限信息。

壹旦用戶信息或權限信息發生變化,令牌中存儲的相關信息並未發生變化,需要重新登錄才能獲得新的令牌。即使重新獲得令牌,如果原始令牌沒有過期,它仍然可以使用。壹種改進的方法是在成功登錄後將獲得的令牌緩存在網關中。如果用戶的權限更改,請刪除網關上的緩存令牌。當請求通過網關時,判斷所請求的令牌是否存在於緩存中,如果不存在,則提示用戶重新登錄。