SpringBoot整合spring-security-oauth2完整實現例子

EalenXie發表於2021-02-03

SpringBoot整合spring-security-oauth2完整實現例子

技術棧 : springboot + spring-security + spring-oauth2 + mybatis-plus

完整的專案地址 : https://github.com/EalenXie/spring-oauth2-authenticator

OAuth2.0是當下最主流的授權機制,如若不清楚什麼是OAuth2.0,請移步Oauth2詳解-介紹(一)OAuth 2.0 的四種方式 - 阮一峰的網路日誌等文章進行學習。

此例子基本完整實現了OAuth2.0四種授權模式。

1. 客戶端憑證式(此模式不支援重新整理令牌)

請求示例 :

POST /oauth/token HTTP/1.1
Host: localhost:8080
Authorization: Basic QUJDOjEyMzQ1Ng==
Content-Type: application/x-www-form-urlencoded
Content-Length: 29

grant_type=client_credentials

此模式獲取令牌介面 grant_type固定傳值 client_credentials,客戶端認證資訊通過basic認證方式。

2. 使用者密碼模式

請求示例 :

POST /oauth/token HTTP/1.1
Host: localhost:8080
Authorization: Basic QUJDOjEyMzQ1Ng==
Content-Type: application/x-www-form-urlencoded
Content-Length: 52

grant_type=password&username=ealenxie&password=admin

此模式獲取令牌介面 grant_type固定傳值 password並且攜帶使用者名稱密碼進行認證。(本例子中筆者對此模式做了改造,客戶端仍然需要進行basic認證,目的是在一個認證授權中心裡面,為了確認客戶端和使用者均有效且能夠建立信任關係)

3. 授權碼模式

此模式過程相對要複雜一些,首先需要認證過的使用者先進行授權,獲取到授權碼code(通過回撥url傳遞回來)之後,再向認證授權中心通過code去獲取令牌。

3.1 使用者認證(登入)

請求示例 :

POST /login HTTP/1.1
Host: localhost:8080
Authorization: Basic QUJDOjEyMzQ1Ng==
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

username=ealenxie&password=admin

認證成功後,會在瀏覽器寫入cookie內容。

3.2 獲取授權碼

請求示例 :

GET /oauth/authorize?client_id=ABC&response_type=code&grant_type=authorization_code HTTP/1.1
Host: localhost:8080
Cookie: JSESSIONID=D329015F6B61C701BD69AE21CA5112C4

瀏覽器此介面呼叫成功後,會302到對應的redirect_uri,並且攜帶上code值。

3.3 授權碼模式獲取令牌

獲取到code之後,再次呼叫獲取令牌介面

POST /oauth/token HTTP/1.1
Host: localhost:8080
Authorization: Basic QUJDOjEyMzQ1Ng==
Content-Type: application/x-www-form-urlencoded
Content-Length: 90

grant_type=authorization_code&redirect_uri=http://localhost:9528/code/redirect&code=3EZOug

4. 簡化模式

此模式首先需要認證過的使用者(見3.1 使用者認證)直接進行授權,瀏覽器此介面呼叫授權介面成功後,會直接302到對應的redirect_uri,並且攜帶上token值,此時token以錨點的形式返回。
本例子中我在後臺配置 redirect_uri 假設為 www.baidu.com 如下 :

5. 重新整理令牌

本例中,設定的令牌有效期access_token_validity為7199秒,即兩個小時。
重新整理令牌的有效期refresh_token_validity為2592000秒,即30天。
access_token過期且refresh_token未過期時,可以通過refresh_token進行重新整理令牌,獲取新的access_tokenrefresh_token

POST /oauth/token HTTP/1.1
Host: localhost:8080
Authorization: Basic QUJDOjEyMzQ1Ng==
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=BC4B6A26370829BB3CAD6BED398F72C8
Content-Length: 391

grant_type=refresh_token&refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9xxxx.....

此模式獲取令牌介面 grant_type固定傳值 refresh_token

6. 檢查令牌是否有效

當需要進行確定令牌是否有效時,可以進行check_token

POST /oauth/check_token?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiY2xvdWQtYXBpLXBsYXRmb3JtIl0sImV4cCI6MTYxMjM3OTkxMSwidXNlcl9uYW1lIjoiZWFsZW54aWUiLCJqdGkiOiJhZWVmMDhkZS02YTExLTQ3NDAtYTQzNS0wNTMyMThkYTMyYzkiLCJjbGllbnRfaWQiOiJBQkMiLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXX0.NPTkpwwdnaKSiPzUgILnnhjawgAuw-ZZWk_4HbkfYzM HTTP/1.1
Host: localhost:8080
Authorization: Basic QUJDOjEyMzQ1Ng==
Cookie: JSESSIONID=4838A3CFD6327A1644D1DAB0B095CC58

本例執行先決條件

  1. 因為本例子中使用的資料庫方式儲存令牌,使用者等等。需要準備spring_oauth2的相關資料表,執行本專案下的db指令碼(裡面配置了oauth2的基礎表和客戶端及使用者賬號資訊)。
  2. 執行專案

相關文章