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認證方式(例子中輸入username為 ABC,密碼為123456)。
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並且攜帶用戶名密碼進行認證。
3. 授權碼模式
此模式過程相對要復雜一些,首先需要認證過的用戶先進行授權,獲取到授權碼code(通過回調url傳遞回來)之后,再向認證授權中心通過code去獲取令牌。
3.1 用戶認證(登錄)
(本例子中筆者對此模式的第一步登錄做了改造,用戶登錄授權服務器需要也進行basic認證,目的是在一個認證授權中心里面,為了確認客戶端和用戶均有效且能夠建立信任關系)
請求示例 :
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_token
和refresh_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
本例運行先決條件
- 因為本例子中使用的數據庫方式存儲令牌,用戶等等。需要准備spring_oauth2的相關數據表,執行本項目下的db腳本(里面配置了oauth2的基礎表和客戶端及用戶賬號信息)。
- 運行項目