メインコンテンツまでスキップ

OpenID Connect Discovery 1.0

OpenID Connect Discovery は、OpenID Provider(OP)の設定情報を自動的に発見するための仕様です。


第1部: 概要編

Discovery とは?

Discovery は、クライアントが OpenID Provider の設定情報を自動的に取得するための仕組みです。

手動設定(従来):
クライアント設定ファイル:
authorization_endpoint: https://auth.example.com/authorize
token_endpoint: https://auth.example.com/token
jwks_uri: https://auth.example.com/.well-known/jwks.json
...

自動発見(Discovery):
GET https://auth.example.com/.well-known/openid-configuration

すべての設定情報を JSON で取得

なぜ Discovery が必要なのか?

課題Discovery による解決
設定の手動管理自動取得
エンドポイントの変更メタデータを更新するだけ
サポート機能の確認メタデータで宣言
マルチ OP 対応issuer から自動発見

Well-Known URI

OpenID Provider のメタデータ:
https://{issuer}/.well-known/openid-configuration

例:
https://accounts.google.com/.well-known/openid-configuration
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration
https://auth.example.com/.well-known/openid-configuration

第2部: 詳細編

メタデータの取得

GET /.well-known/openid-configuration HTTP/1.1
Host: auth.example.com
HTTP/1.1 200 OK
Content-Type: application/json

{
"issuer": "https://auth.example.com",
"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/token",
"userinfo_endpoint": "https://auth.example.com/userinfo",
"jwks_uri": "https://auth.example.com/.well-known/jwks.json",
...
}

必須メタデータ

フィールド説明
issuerOP の識別子(URL)
authorization_endpoint認可エンドポイント
token_endpointトークンエンドポイント(暗黙的フローのみの場合は不要)
jwks_uriJWK Set の URL
response_types_supportedサポートする response_type
subject_types_supportedサポートする subject タイプ
id_token_signing_alg_values_supportedID トークンの署名アルゴリズム

推奨メタデータ

フィールド説明
userinfo_endpointUserInfo エンドポイント
registration_endpoint動的登録エンドポイント
scopes_supportedサポートするスコープ
claims_supportedサポートするクレーム
grant_types_supportedサポートするグラントタイプ
acr_values_supportedサポートする認証コンテキストクラス

完全なメタデータ例

{
"issuer": "https://auth.example.com",

"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/token",
"userinfo_endpoint": "https://auth.example.com/userinfo",
"jwks_uri": "https://auth.example.com/.well-known/jwks.json",
"registration_endpoint": "https://auth.example.com/register",
"revocation_endpoint": "https://auth.example.com/revoke",
"introspection_endpoint": "https://auth.example.com/introspect",
"end_session_endpoint": "https://auth.example.com/logout",
"pushed_authorization_request_endpoint": "https://auth.example.com/par",

"scopes_supported": [
"openid", "profile", "email", "address", "phone", "offline_access"
],

"response_types_supported": [
"code",
"token",
"id_token",
"code token",
"code id_token",
"token id_token",
"code token id_token"
],

"response_modes_supported": [
"query", "fragment", "form_post", "jwt", "query.jwt", "fragment.jwt", "form_post.jwt"
],

"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"client_credentials",
"urn:ietf:params:oauth:grant-type:jwt-bearer",
"urn:ietf:params:oauth:grant-type:token-exchange",
"urn:openid:params:grant-type:ciba"
],

"subject_types_supported": [
"public", "pairwise"
],

"id_token_signing_alg_values_supported": [
"RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512"
],

"id_token_encryption_alg_values_supported": [
"RSA-OAEP", "RSA-OAEP-256", "A256KW"
],

"id_token_encryption_enc_values_supported": [
"A128CBC-HS256", "A256CBC-HS512", "A128GCM", "A256GCM"
],

"userinfo_signing_alg_values_supported": [
"RS256", "ES256"
],

"request_object_signing_alg_values_supported": [
"none", "RS256", "ES256"
],

"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"client_secret_jwt",
"private_key_jwt",
"tls_client_auth",
"self_signed_tls_client_auth"
],

"token_endpoint_auth_signing_alg_values_supported": [
"RS256", "ES256", "PS256"
],

"claims_supported": [
"sub", "iss", "aud", "exp", "iat", "auth_time", "nonce", "acr", "amr",
"name", "given_name", "family_name", "nickname", "preferred_username",
"profile", "picture", "website", "email", "email_verified",
"gender", "birthdate", "zoneinfo", "locale", "phone_number",
"phone_number_verified", "address", "updated_at"
],

"acr_values_supported": [
"urn:mace:incommon:iap:silver",
"urn:mace:incommon:iap:bronze"
],

"claims_parameter_supported": true,
"request_parameter_supported": true,
"request_uri_parameter_supported": true,
"require_request_uri_registration": true,

"code_challenge_methods_supported": [
"plain", "S256"
],

"tls_client_certificate_bound_access_tokens": true,
"dpop_signing_alg_values_supported": ["RS256", "ES256"],

"authorization_response_iss_parameter_supported": true,

"backchannel_logout_supported": true,
"backchannel_logout_session_supported": true,
"frontchannel_logout_supported": true,
"frontchannel_logout_session_supported": true,

"service_documentation": "https://auth.example.com/docs",
"ui_locales_supported": ["en", "ja", "de", "fr"]
}

OAuth 2.0 拡張メタデータ(RFC 8414)

フィールド説明
revocation_endpointトークン取消エンドポイント
introspection_endpointトークンイントロスペクションエンドポイント
code_challenge_methods_supportedPKCE のサポート
pushed_authorization_request_endpointPAR エンドポイント
require_pushed_authorization_requestsPAR が必須か

セキュリティ拡張メタデータ

フィールド説明
tls_client_certificate_bound_access_tokensmTLS トークンバインディング
dpop_signing_alg_values_supportedDPoP サポート
authorization_response_iss_parameter_supportedRFC 9207 サポート

ログアウト関連メタデータ

フィールド説明
end_session_endpointRP 起点ログアウト
frontchannel_logout_supportedフロントチャネルログアウト
frontchannel_logout_session_supportedセッション付きフロントチャネルログアウト
backchannel_logout_supportedバックチャネルログアウト
backchannel_logout_session_supportedセッション付きバックチャネルログアウト

WebFinger による Issuer 発見

ユーザーのメールアドレスなどから Issuer を発見する場合。

GET /.well-known/webfinger?
resource=acct:user@example.com
&rel=http://openid.net/specs/connect/1.0/issuer
Host: example.com
{
"subject": "acct:user@example.com",
"links": [
{
"rel": "http://openid.net/specs/connect/1.0/issuer",
"href": "https://auth.example.com"
}
]
}

キャッシュ戦略

メタデータのキャッシュ:

1. HTTP キャッシュヘッダーに従う
Cache-Control: max-age=3600

2. 適度な間隔で更新
- 一般的には 1-24 時間ごと
- エラー発生時に再取得

3. JWKS のキャッシュ
- 鍵ローテーションを考慮
- kid が見つからない場合は再取得

注意:
- 本番環境では必ずキャッシュを使用
- 起動時に 1 回取得し、定期的に更新

セキュリティ考慮事項

項目推奨事項
HTTPSDiscovery エンドポイントは HTTPS 必須
issuer 検証レスポンスの issuer と期待値を比較
キャッシュ適切な TTL でキャッシュ
TLS 証明書有効な証明書を検証
エンドポイント検証取得したエンドポイントが issuer と同一オリジンか確認

参考リンク