跳到內容

Ory Hydra: Dynamic Client Registration

本文基於 Ory Hydra v25.4.0 分析其 Dynamic Client Registration(DCR)實作,包含 API 端點、支援欄位、安全機制與實際測試結果。

Hydra 的 DCR 預設停用,需要在設定檔中明確啟用:

oidc:
dynamic_client_registration:
enabled: true
default_scope:
- openid
- offline
- offline_access

啟用後,DCR 端點會在 Public API port 上生效。

Hydra 提供兩套 Client 管理 API,DCR 屬於 Public API:

方法路徑說明
POST/oauth2/register註冊新的 Client
GET/oauth2/register/{id}取得 Client 資訊
PUT/oauth2/register/{id}更新 Client(完整替換)
DELETE/oauth2/register/{id}刪除 Client
方法路徑說明
POST/admin/clients建立 Client(可自訂 client_id
GET/admin/clients列出所有 Client
GET/admin/clients/{id}取得 Client
PUT/admin/clients/{id}更新 Client
PATCH/admin/clients/{id}部分更新 Client
DELETE/admin/clients/{id}刪除 Client

DCR 端點是 Admin API 的子集,主要差異:

  • 不能自訂 client_id(強制使用 UUID4)
  • 不能自訂 client_secret(由伺服器產生)
  • 不能設定 metadataaccess_token_strategyskip_consent 等管理欄位
  • 沒有 PATCH 方法和 Token lifespan 設定

以下使用 Docker 啟動 Hydra v25.4.0 進行測試。

POST /oauth2/register HTTP/1.1
Host: localhost:4444
Content-Type: application/json
{
"client_name": "Test Application",
"redirect_uris": ["http://localhost:3000/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"scope": "openid offline",
"token_endpoint_auth_method": "client_secret_basic"
}

回應:

{
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"client_name": "Test Application",
"client_secret": "generated-secret-value",
"client_secret_expires_at": 0,
"redirect_uris": ["http://localhost:3000/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"scope": "openid offline",
"token_endpoint_auth_method": "client_secret_basic",
"registration_access_token": "ory_at_...",
"registration_client_uri": "http://localhost:4444/oauth2/register/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-03-18T00:00:00Z",
"updated_at": "2026-03-18T00:00:00Z"
}

重點觀察:

  • client_id 為伺服器產生的 UUID4,無法自訂
  • client_secret_expires_at 永遠為 0(不支援 secret 過期)
  • 回應包含 registration_access_tokenregistration_client_uri,用於後續管理操作

使用 Registration Access Token 查詢 Client

Section titled “使用 Registration Access Token 查詢 Client”
GET /oauth2/register/a1b2c3d4-e5f6-7890-abcd-ef1234567890 HTTP/1.1
Host: localhost:4444
Authorization: Bearer ory_at_...

registration_access_token 是存取 GETPUTDELETE 端點的唯一憑證。

PUT /oauth2/register/a1b2c3d4-e5f6-7890-abcd-ef1234567890 HTTP/1.1
Host: localhost:4444
Authorization: Bearer ory_at_...
Content-Type: application/json
{
"client_name": "Updated Application",
"redirect_uris": ["http://localhost:3000/callback", "http://localhost:3000/callback2"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"scope": "openid offline",
"token_endpoint_auth_method": "client_secret_basic"
}

重點觀察:

  • PUT 是完整替換,未帶的欄位會被重設為預設值
  • 更新後會重新產生 registration_access_token(Token Rotation),舊的 Token 立即失效

若未設定 oidc.dynamic_client_registration.enabled: true,所有 DCR 端點會回傳 404

欄位說明
client_nameClient 名稱
redirect_urisRedirect URI 陣列
grant_types授權類型
response_types回應類型
scope授權範圍(空格分隔)
token_endpoint_auth_methodToken Endpoint 認證方式
contacts聯絡人 email 陣列
client_uriClient 資訊頁面 URL
logo_uriLogo URL
policy_uri隱私權政策 URL
tos_uri服務條款 URL
audience允許的 Audience 清單
欄位說明
subject_typepublicpairwise
sector_identifier_uriPairwise 計算用的 sector URI
jwks_uriJWK Set URL
jwksJWK Set(直接傳值)
userinfo_signed_response_alg僅支援 noneRS256
frontchannel_logout_uriFront-Channel Logout URI
backchannel_logout_uriBack-Channel Logout URI
post_logout_redirect_uris登出後重導向 URI

支援的認證方式(token_endpoint_auth_method

Section titled “支援的認證方式(token_endpoint_auth_method)”
說明
client_secret_basicHTTP Basic Authentication
client_secret_postSecret 放在 POST body
private_key_jwt使用私鑰簽署 JWT
none不需認證(Public Client)
說明
authorization_codeAuthorization Code Flow
client_credentialsClient Credentials Flow
implicitImplicit Flow(不建議)
refresh_tokenRefresh Token
urn:ietf:params:oauth:grant-type:jwt-bearerJWT Assertion
urn:ietf:params:oauth:grant-type:device_codeDevice Code Flow

註冊端點不需要認證,任何人都可以註冊 Client。這符合 RFC 7591 的開放註冊模式。

如果需要保護註冊端點,Hydra 不提供內建的 Initial Access Token 機制,官方建議使用外部方案:

  • 反向代理(如 Ory Oathkeeper)攔截請求
  • mTLS 認證
  • 網路層限制

使用 registration_access_token 做 Bearer Token 驗證:

  • Token 在註冊時產生,PUT 更新時會 rotate(舊 Token 失效,產生新 Token)
  • Token 不會過期
  • Token 以 HMAC 簽章方式驗證,簽章儲存在資料庫中

RFC 7591(Dynamic Client Registration Protocol)

Section titled “RFC 7591(Dynamic Client Registration Protocol)”
要求Hydra 狀態
POST 註冊端點/oauth2/register
回傳 client_id✅ 伺服器產生 UUID4
回傳 client_secret(Confidential Client)
software_statement 支援❌ 不支援
client_secret_expires_at⚠️ 永遠為 0(不支援過期)

RFC 7592(Dynamic Client Registration Management Protocol)

Section titled “RFC 7592(Dynamic Client Registration Management Protocol)”
要求Hydra 狀態
回傳 registration_access_token
回傳 registration_client_uri
GET 讀取 Client 配置
PUT 更新 Client 配置
DELETE 刪除 Client
Bearer Token 驗證registration_access_token
Token RotationPUT 時重新產生 Token(RFC 規範為 MAY)