參數:https://datatracker.ietf.org/doc/html/rfc7523
oauth2.0中的三方另類授權
瞭解OAuth 2.0中特定的授權類型(Grant Type)對於構建安全的認證流程至關重要。下面為你詳細介紹這三種基於URN聲明的擴展授權類型。
🔐 設備代碼授權 (urn:ietf:params:oauth:grant-type:device_code)
這種授權模式專為輸入能力受限或沒有瀏覽器的設備設計,比如智能電視、遊戲機、IoT設備或命令行工具(CLI)。
-
工作原理:其核心是一個兩步過程。
- 設備獲取代碼:設備上的應用首先向授權服務器(如 Microsoft Entra ID)的
/devicecode端點發起請求。服務器會返回一組信息,包括一個簡短的user_code(用户代碼)和一個verification_uri(驗證網址)。 - 用户授權:設備將
user_code和verification_uri顯示給用户,並提示用户在其他設備(如個人手機或電腦)上打開瀏覽器,訪問該網址並輸入代碼。用户在授權服務器的正規頁面上完成身份驗證(可能包括多因素認證)並同意授權。在此期間,設備應用會定期輪詢授權服務器的令牌端點,直到用户完成操作後獲取訪問令牌和刷新令牌。
- 設備獲取代碼:設備上的應用首先向授權服務器(如 Microsoft Entra ID)的
-
安全風險與防禦:需要注意的是,此流程可能被用於進行高迷惑性的網絡釣魚攻擊(稱為“設備代碼釣魚”)。攻擊者會誘導用户在真實的微軟登錄頁面輸入由攻擊者生成的設備代碼,從而授權一個惡意應用。防禦措施包括在服務器端嚴格限制應用同意策略、實施條件訪問策略(如要求來自合規設備),以及對用户進行安全教育。
🔄 令牌交換授權 (urn:ietf:params:oauth:grant-type:token-exchange)
令牌交換授權提供了強大的 interoperability(互操作性),允許將一個憑證或令牌交換為另一個不同的令牌,常用於服務之間的安全調用或身份映射。
-
核心概念:它遵循 OAuth Token Exchange 規範,使得客户端能夠使用一個現有的
subject_token(主體令牌)來換取一個新的、針對不同受眾或資源的access_token(訪問令牌)。 -
常見場景:
- 服務間調用:後端服務A可以使用自己持有的令牌,換取一個具有適當權限的、用於調用服務B的訪問令牌。
- 權限降級:一個高權限的應用在需要調用一個低信任度的服務時,可以換一個權限受限的令牌,以提升安全性。
- 外部身份提供商集成:將外部IDP(如Google、Facebook)簽發的令牌交換為內部系統的令牌,從而實現跨域身份聯合。
- 用户模擬:在嚴格管控下,服務可以換取一個代表特定用户身份的令牌(即模擬用户)。
-
實施要點:令牌交換功能通常默認不開啓,需要在服務器端(如Red Hat Single Sign-On)為客户端顯式配置精細的權限策略。
⚙️ JWT持有者授權 (urn:ietf:params:oauth:grant-type:jwt-bearer)
這種授權類型允許客户端直接使用一個預先簽名的JWT(JSON Web Token)作為斷言(assertion)來獲取訪問令牌。
-
基本流程:客户端向授權服務器的令牌端點發起POST請求,在請求體中,
grant_type參數設置為urn:ietf:params:oauth:grant-type:jwt-bearer,並同時提供用作斷言的assertion參數(即JWT本身)。授權服務器會驗證該JWT的簽名、有效期、頒發者等信息,驗證通過後即頒發所請求的訪問令牌。 -
典型應用場景:
- 服務賬户認證:在機器對機器(M2M)的通信中,一個服務可以使用事先配置好的JWT(通常基於私鑰簽名)來獲取訪問令牌,無需用户交互。這在CI/CD流水線或後台服務中非常常見。
- 微服務架構:在微服務網絡中,一個服務在收到訪問令牌後,可以利用此流程向認證服務器換取一個範圍(scope)更窄、專用於訪問另一個特定微服務的令牌。
下面的表格清晰地對比了這三種授權類型的關鍵差異。
| 特性 | 設備代碼授權 (device_code) |
令牌交換授權 (token-exchange) |
JWT持有者授權 (jwt-bearer) |
|---|---|---|---|
| 主要目的 | 方便輸入受限設備上的用户授權 | 實現令牌之間的安全轉換和身份委託 | 客户端使用已有的JWT直接獲取訪問令牌 |
| 令牌流 | 輪詢機制 | 直接交換 | 斷言式請求 |
| 典型應用 | 智能電視、IoT設備、CLI工具 | 服務間調用、權限降級、身份聯合 | 機器對機器通信、服務賬户、微服務 |
處理流程
💎 總結與安全考量
選擇哪種授權類型完全取決於你的具體應用場景。設備代碼授權優化了受限設備的用户體驗,令牌交換授權為複雜的服務間信任鏈提供了靈活性,而JWT持有者授權則是機器對機器通信的簡潔高效方案。
在實施這些授權流程時,務必關注以下安全最佳實踐:
- 嚴格控制權限:遵循最小權限原則,只為應用授予其必需的最少權限。
- 驗證與監控:服務器端必須嚴格驗證所有令牌和斷言(如JWT的簽名和有效期),並建立日誌審計和異常行為監控機制。
- 保護令牌:訪問令牌和刷新令牌是敏感憑證,在傳輸和存儲過程中必須加以保護。
wso2中的實戰
wso2 sp的配置
配置認證grant_type類型
keycloak idp的配置
keycloak中為客户端開啓roles之後,如果有用户有客户端的角色,會在jwt中多出來aud數組字段,也可以為wso2客户端添加自定義的client scope,然後為它添加aud的cliams
IDP名稱必須與IDP中token的Issuer相同
測試
curl -X POST 'https://test-apim.xxx.com/oauth2/token' -H 'Content-Type: application/json' -H 'Content-Type: application/json' -u 'wso2-sp-client-id:wso2-sp-client-secret' --basic -d '{
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": "abc.abc.abc",
"scope": "openid apim:subscribe"
}'
如果keycloak_token過期,就返回這個400錯誤
{
"error_description": "JSON Web Token is expired., Expiration Time(ms) : 1769413736000, TimeStamp Skew : 0, Current Time : 1769413748585. JWT Rejected and validation terminated",
"error": "invalid_grant"
}
如果成功,會返wso2平台的token
{
"access_token": "8b23bf56-f8d2-33fa-9962-f298a797ce94",
"refresh_token": "aad2555-30b0-3591-8c70-b2cdc042cc41",
"scope": "apim:subscribe openid",
"id_token": "",
"token_type": "Bearer",
"expires_in": 3185
}
用户登錄成功後,會初始化用户表,需要注意的是,這種urn:ietf:params:oauth:grant-type:jwt-bearer首次登錄添加的用户,它位於wso2am_db.idn_auth_user表,user_name同樣是三方社區token中的sub字段;而標準oauth的授權碼認證後,除了在wso2am_db.idn_auth_user表初始化外,還在wso2am_share_db.um_user表也會添加一份用户數據。