跳到內容

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)
回傳 registration_access_token
回傳 registration_client_uri
software_statement 支援❌ 不支援
client_secret_expires_at⚠️ 永遠為 0(不支援過期)

RFC 7592(Dynamic Client Registration Management Protocol)

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