[ADP-54] OAuth2.0/OIDC for API
OAuth2.0 概述
OAuth2.0 是一種授權框架,允許第三方應用程序在不暴露用戶憑證的情況下訪問用戶的資源。它支持多種授權流程,適用於不同的應用場景。
授權類型
- 授權碼授權:適用於具有後端伺服器的應用程序,提供更高的安全性。
- 流程:用戶重定向到授權伺服器,授權後返回授權碼,然後用該碼請求訪問令牌。
- 隱式授權:適用於單頁應用程序,安全性較低,建議使用帶 PKCE 的授權碼替代。
- 注意:不應在 URL 中暴露敏感資訊。
- 客戶端憑證授權:用於機器對機器的認證。
- 示例:用於服務之間的 API 認證。
- 資源擁有者密碼憑證:用於受信任的第一方客戶端,謹慎使用。
- 建議:僅在內部應用中使用。
指導原則
- 應該(SHOULD)優先考慮支持 OIDC(OAuth2.0 的超集)。
- 所有 API 端點必須(MUST)考慮使用 OAuth2.0 進行安全保護。
- 不應(SHOULD NOT)使用基本認證,因其安全性較低。
- 所有外部 API 必須(MUST)建立在 HTTPS 之上,以保護傳輸中的數據。
- 應(SHOULD)定義用於 OAuth2.0 的 scope,命名慣例為
resource.permission
。 - 針對 M2M(機器對機器)認證應(SHOULD)使用 Client Credential 模式。
- 針對可信任客戶端應(SHOULD)使用 Authorization Grant Code 模式。
- 應(SHOULD)考慮實作端點發現,根據 RFC 8414。
服務發現的工作流程
客戶端請求元數據
客戶端應用程序請求授權伺服器的元數據端點,以獲取相關配置。這個請求通常是對一個固定的 URL 進行 HTTP GET 請求。例如:
http
GET https://authorization-server.com/.well-known/openid-configuration
授權伺服器返回元數據
授權伺服器返回一個 JSON 文件,其中包含了各種與 OAuth 2.0 流程相關的 URL 和配置資訊。示例元數據回應:
json
{
"issuer": "https://authorization-server.com",
"authorization_endpoint": "https://authorization-server.com/auth",
"token_endpoint": "https://authorization-server.com/token",
"jwks_uri": "https://authorization-server.com/.well-known/jwks.json",
"response_types_supported": ["code", "token"],
"grant_types_supported": ["authorization_code", "client_credentials"],
"id_token_signing_alg_values_supported": ["RS256"]
}
錯誤規範
根據 RFC6749 定義,授權失敗應回應以下物件(注意此處既然規範本身已經定義物件內容,本回應不適用 RFC9457 HTTP Problem)。
1. HTTP 狀態碼
根據錯誤的類型,應返回不同的 HTTP 狀態碼給客戶端:
- 400 Bad Request:請求有誤,例如缺少必要的參數或參數格式不正確。
- 401 Unauthorized:客戶端未通過身份驗證,通常在客戶端憑證錯誤或 access_token 無效時使用。
- 403 Forbidden:客戶端已通過身份驗證,但沒有權限訪問請求的資源或執行請求的操作。
- 500 Internal Server Error:伺服器內部錯誤,導致授權失敗。
2. 錯誤回應體
OAuth 2.0 規範要求錯誤回應體使用 JSON 格式,並且必須包含以下屬性(property):
- error:描述錯誤類型的字符串。規範中定義的錯誤類型包括:
invalid_request
:請求參數缺失或無效。invalid_client
:客戶端身份驗證失敗(如 client_id 或 client_secret 無效)。invalid_grant
:授權碼或刷新令牌無效、過期或已撤銷。unauthorized_client
:客戶端無權使用此授權類型。unsupported_grant_type
:授權類型不受支持。invalid_scope
:請求的 scope 超出了授權範圍或無效。
- error_description:(可選)對錯誤的詳細描述,便於調試。
- error_uri:(可選)指向一個網頁,包含關於錯誤的更多資訊。
示例
以下是使用 OAuth2.0 的 API 請求示例:
http
POST /token HTTP/1.1
Host: api.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=AUTH_CODE&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
錯誤處理示例
當請求失敗時,應返回適當的錯誤代碼和資訊:
json
{
"error": "invalid_grant",
"error_description": "The provided authorization grant is invalid, expired, or revoked."
}