Skip to content
ADP
API Design PrincipleBETA

[ADP-54] OAuth2.0/OIDC for API

OAuth2.0 概述

OAuth2.0 是一種授權框架,允許第三方應用程序在不暴露用戶憑證的情況下訪問用戶的資源。它支持多種授權流程,適用於不同的應用場景。

授權類型

  1. 授權碼授權:適用於具有後端伺服器的應用程序,提供更高的安全性。
    • 流程:用戶重定向到授權伺服器,授權後返回授權碼,然後用該碼請求訪問令牌。
  2. 隱式授權:適用於單頁應用程序,安全性較低,建議使用帶 PKCE 的授權碼替代。
    • 注意:不應在 URL 中暴露敏感資訊。
  3. 客戶端憑證授權:用於機器對機器的認證。
    • 示例:用於服務之間的 API 認證。
  4. 資源擁有者密碼憑證:用於受信任的第一方客戶端,謹慎使用。
    • 建議:僅在內部應用中使用。

指導原則

  • 應該(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."
}

參考資料