Table of Contents
このドキュメントでは OpenID Federation 1.0 について説明します。
変更履歴 | |
---|---|
日付 | 変更内容 |
2023-01-01 |
|
2024-08-03 |
|
OpenID Federation 1.0 は、アイデンティティプロバイダー(IDP) / 認可サーバー と リライングパーティー(クライアント)が、直接的な関係を持たなくても トラストチェーン を介して互いに信頼し、IDP が事前登録なしでリライングパーティーから OAuth/OIDC リクエストを受け入れる仕組みを定義しています。
トラストチェーンは一方向であるため、IDP とリライングパーティーが互いを信頼するには、2 つのトラストチェーンを構築する必要があります。一方はリライングパーティーが IDP を信頼するためのチェーンです。
もう一方は IDP がリライングパーティーを信頼するためのチェーンです。
トラストチェーンは第三者の 認証機関 によって構築されます。トラストチェーンの起点となる認証機関を “トラストアンカー” と呼び、トラストアンカーと対象の リーフエンティティ(IDP またはリライングパーティー)の間にある認証機関を “中間認証機関” と呼びます。トラストアンカーと中間認証機関は、公開鍵基盤(PKI) における ルート証明機関(Root CA) および 中間証明機関(Intermediate CA) と概念的に同等です。
リライングパーティーは 1 つ以上のトラストアンカーを信頼します。信頼するトラストアンカーのいずれかが対象の IDP へのパスを持つ場合、リライングパーティーはその IDP を信頼できます。
同様に、IDP も 1 つ以上のトラストアンカーを信頼します。信頼するトラストアンカーのいずれかが対象のリライングパーティーへのパスを持つ場合、IDP はそのリライングパーティーを信頼できます。
以下の図は、本セクションで説明した OpenID Federation 1.0 の概要を示しています。
技術的には、トラストチェーンは JWT(RFC 7519 JSON Web Token)のシーケンスであり、リーフエンティティ、中間認証機関(ゼロ個以上)、およびトラストアンカーによって発行されます。
リーフエンティティは、自身の秘密鍵で署名した JWT を発行します。
OpenID Federation 仕様では、リーフエンティティが発行する JWT のペイロード部分に、署名に使用した秘密鍵に対応する公開鍵を含めることが求められています。公開鍵は jwks
クレームに格納されます。
その結果、JWT は 自己署名 JWT となります。したがって、JWT のペイロード部分に含まれる iss
クレーム(Issuer; RFC 7519 セクション 4.1.1)と sub
クレーム(Subject; RFC 7519 セクション 4.1.2)の両方に、リーフエンティティの識別子が格納されます。
リーフエンティティを認可する中間認証機関(または、トラストチェーンに中間認証機関が存在しない場合はトラストアンカー)が、リーフエンティティを認可することを示す JWT を発行します。この JWT は、中間認証機関の秘密鍵で署名されます。
JWT の目的は、中間認証機関がリーフエンティティを認可していることを示すことです。そのため、sub
クレームにはリーフエンティティの識別子が格納され、iss
クレームには中間認証機関の識別子が格納されます。
さらに、jwks
クレームにはリーフエンティティの公開鍵が格納されます。
トラストチェーンは、トラストアンカーの秘密鍵で署名された JWT によって終端されます。
この JWT は、トラストアンカーが最後の中間認証機関を認可していることを示します。sub
クレームには最後の中間認証機関の識別子が格納され、iss
クレームにはトラストアンカーの識別子が格納されます。中間認証機関が存在しない場合は、トラストアンカーが直接リーフエンティティを認可する JWT を発行します。この場合、sub
クレームにはリーフエンティティの識別子が格納されます。
トラストアンカーが発行する JWT には、最後の中間認証機関の公開鍵が含まれます。
トラストチェーンには、オプションとして、トラストアンカー自身が自己署名した JWT を末尾に含めることができます。
この JWT は自己署名であるため、iss
クレームと sub
クレームの両方にトラストアンカーの識別子が格納されます。
以下の図は、トラストチェーン全体の構成を示しています。
トラストチェーンの解決プロセスは、リーフエンティティの自己署名 JWT を取得することから始まります。
OpenID Federation 仕様では、自己署名 JWT の取得場所が定義されています。それは、リーフエンティティの識別子に固定文字列 "/.well-known/openid-federation"
を追加した URL です。
リーフエンティティの識別子 + /.well-known/openid-federation
OpenID Connect Discovery 1.0 や RFC 8414 OAuth 2.0 Authorization Server Metadata の仕様に詳しい場合、リーフエンティティの識別子が http://
または https://
で始まる URL であることを想像するでしょう。その想像は正しいです。
フェデレーションの参加者(IDP、リライングパーティー、中間認証機関、トラストアンカー)は “フェデレーションエンティティ” と呼ばれます。各フェデレーションエンティティは、一意の識別子 “エンティティ ID” を持ちます。そして、エンティティ ID は http
または https
をスキームとする URL である必要があります。この URL により、Web サーバーがエンティティを識別し、必要な JWT を発行できます。
例えば、リライングパーティーのエンティティ ID が https://rp.example.com/123
の場合、リライングパーティーの自己署名 JWT は以下の URL で公開されることが期待されます。
https://rp.example.com/123/.well-known/openid-federation
一般に、フェデレーションエンティティの /.well-known/openid-federation
に公開される自己署名 JWT は “エンティティ構成"(Entity Configuration)と呼ばれます。
エンティティ構成のペイロードには authority_hints
クレームが含まれます。このクレームは JSON 配列であり、エンティティ構成のフェデレーションエンティティを認可できる中間認証機関またはトラストアンカーのエンティティ ID をリストします。
例えば、リライングパーティー https://rp.example.com/123
が直接の中間認証機関 https://ia.example.com
を持つ場合、リライングパーティーのエンティティ構成の authority_hints
クレームには https://ia.example.com
が含まれます。
同様に、中間認証機関がトラストアンカー https://ta.example.com
を直接の認証機関として持つ場合、中間認証機関のエンティティ構成の authority_hints
クレームには https://ta.example.com
が含まれます。
一方で、トラストアンカーは定義上、それ以上の上位認証機関を持たないため、トラストアンカーのエンティティ構成には authority_hints
クレームが含まれません。
リーフエンティティのエンティティ構成を取得した後の次のステップは、リーフエンティティを認可する認証機関(中間認証機関またはトラストアンカー)から JWT を取得することです。
認証機関はこのために フェデレーションフェッチエンドポイント(Federation Fetch Endpoint)を提供することが求められます。このエンドポイントの仕様は次の表にまとめられています。
リクエスト | |||
---|---|---|---|
HTTP メソッド | GET | ||
パラメータ | iss |
任意 | 発行者のエンティティ ID |
sub |
任意 | 対象(サブジェクト)のエンティティ ID | |
レスポンス | |||
HTTP ステータスコード | 200 | ||
Content-Type | application/entity-statement+jwt |
例えば、中間認証機関 https://ia.example.com
が https://ia.example.com/fetch
にフェデレーションフェッチエンドポイントを提供している場合、次の HTTP リクエストを送信することで、リライングパーティー https://rp.example.com/123
を認可する JWT を取得できます。
https://ia.example.com/fetch?sub=https://rp.example.com/123
認証機関のフェデレーションフェッチエンドポイントの URL は、その認証機関のエンティティ構成に記載されています。この URL は federation_fetch_endpoint
クレームに格納されますが、このクレームは metadata
JSON オブジェクト内の federation_entity
オブジェクト内に配置されています。
フェデレーションフェッチエンドポイントから JWT を取得するプロセスは、トラストアンカーの JWT を取得するまで繰り返されます。取得したトラストアンカーが信頼できるトラストアンカーの 1 つであれば、リーフエンティティを信頼するためのトラストチェーンが構築できたことになります。
トラストチェーン解決の流れを振り返ります。
(1) 最初のステップは、リーフエンティティのエンティティ構成を取得することです。
(2) エンティティ構成には authority_hints
クレームが含まれています。これは、リーフエンティティを認可する中間認証機関またはトラストアンカーのエンティティ ID を示す JSON 配列です。この例では、中間認証機関 https://ia.example.com
が含まれています。
(3) 中間認証機関のエンティティ構成を取得し、フェデレーションフェッチエンドポイントの URL を確認します。
(4) フェデレーションフェッチエンドポイントに sub
クエリパラメータを含む HTTP リクエストを送信します。この例では、リーフエンティティのエンティティ ID (https://rp.example.com/123
) を sub
に指定しています。
(5) フェデレーションフェッチエンドポイントから、中間認証機関がリーフエンティティを認可することを示す JWT を取得します。
(6) 中間認証機関の authority_hints
クレームには、上位の認証機関のエンティティ ID が含まれています。この例では、トラストアンカー https://ta.example.com
が含まれています。
(7) トラストアンカーのエンティティ構成を取得し、フェデレーションフェッチエンドポイントの URL を確認します。
(8) トラストアンカーのフェデレーションフェッチエンドポイントに sub
クエリパラメータを含む HTTP リクエストを送信します。この例では、中間認証機関のエンティティ ID (https://ia.example.com
) を sub
に指定しています。
(9) フェデレーションフェッチエンドポイントから、トラストアンカーが中間認証機関を認可することを示す JWT を取得します。
(10) リーフエンティティのエンティティ構成と、フェデレーションフェッチエンドポイントから取得した JWT 群によってトラストチェーンが形成されます。
以下の図は、トラストチェーン解決の全体の流れを示しています。
トラストチェーン解決の過程で現れるすべての JWT は “エンティティステートメント"(Entity Statement)と呼ばれます。エンティティ構成もエンティティステートメントの一種です。
エンティティ構成には、フェデレーションエンティティの メタデータ が含まれます。
アイデンティティプロバイダー(IDP)のメタデータは、metadata
JSON オブジェクト内の openid_provider
JSON オブジェクトに格納されます。
OpenID Connect Discovery 1.0、RFC 8414 OAuth 2.0 Authorization Server Metadata、その他の標準仕様で定義されるメタデータが openid_provider
JSON オブジェクトに含まれることがあります。
さらに、OpenID Federation 仕様では以下のサーバーメタデータを定義しています。
client_registration_types_supported
organization_name
federation_registration_endpoint
request_authentication_methods_supported
request_authentication_signing_alg_values_supported
signed_jwks_uri
jwks
リライングパーティーのメタデータは、metadata
JSON オブジェクト内の openid_relying_party
JSON オブジェクトに格納されます。
OpenID Connect Dynamic Client Registration 1.0、RFC 7591 OAuth 2.0 Dynamic Client Registration Protocol、その他の標準仕様で定義されるメタデータが openid_relying_party
JSON オブジェクトに含まれることがあります。
さらに、OpenID Federation 仕様では以下のクライアントメタデータを定義しています。
client_registration_types
organization_name
signed_jwks_uri
中間認証機関およびトラストアンカーのメタデータは、metadata
JSON オブジェクト内の federation_entity
JSON オブジェクトに格納されます。
OpenID Federation 仕様では、認証機関向けの以下のメタデータを定義しています。
federation_fetch_endpoint
federation_list_endpoint
federation_resolve_endpoint
federation_trust_mark_status_endpoint
organization_name
contacts
logo_uri
policy_uri
homepage_uri
トラストチェーン内のリーフエンティティのエンティティ構成には、そのエンティティのメタデータが含まれています。これらのメタデータは metadata
クレームに格納されます。
一方で、トラストチェーン内の他の JWT(中間認証機関やトラストアンカーが発行するもの)には、リーフエンティティのメタデータを調整するための メタデータポリシー が含まれる場合があります。これらのポリシーは metadata_policy
クレームに格納されます。
メタデータポリシーは組み合わせられて適用されます。
次に、統合されたメタデータポリシーがリーフエンティティのメタデータに適用され、フェデレーション内で使用される最終的なメタデータが決定されます。
以下の図は、メタデータポリシーの適用フローを示しています。
メタデータポリシーの詳細については、OpenID Federation 仕様を参照してください。
一般的なアイデンティティプロバイダーの実装では、リライングパーティー(クライアント)の識別子はアイデンティティプロバイダーによって管理されており、その識別子はアイデンティティプロバイダーの範囲内でのみ一意です。一方、OpenID Federation では、すべてのフェデレーションエンティティが グローバルに一意のエンティティ ID を持ちます。
OpenID Federation の興味深い特性の一つは、このグローバルなエンティティ ID を OAuth/OIDC リクエストのクライアント ID として使用できる ことです。例えば、以下のような認可リクエストを送信できます。この例では、client_id
パラメータの値としてリライングパーティーのエンティティ ID が使用されている点に注目してください。
https://idp.example.com/authorize?request_uri=...&client_id=https://rp.example.com/123
OAuth/OIDC リクエストに含まれるクライアント ID が未知であるが、エンティティ ID のように見える場合、OpenID Federation をサポートするアイデンティティプロバイダーは、そのエンティティ ID から開始し、信頼できるトラストアンカーまで続くトラストチェーンを探します。
そのようなトラストチェーンが見つかると、アイデンティティプロバイダーは、エンティティ ID とメタデータを使用して自動的に新しいクライアントを登録し、OAuth/OIDC リクエストの処理を続行します。
自動クライアント登録 をサポートするアイデンティティプロバイダーのディスカバリドキュメント(OpenID Connect Discovery 1.0)には、client_registration_types_supported
サーバーメタデータに automatic
が含まれます。OpenID Federation 仕様では client_registration_types_supported
サーバーメタデータを必須としています。
また、自動登録されるクライアントの client_registration_types
クライアントメタデータには automatic
を含める必要があります。OpenID Federation 仕様では client_registration_types
クライアントメタデータも必須としています。
OAuth/OIDC リクエストが自動クライアント登録をトリガーするとき、そのリクエストは何らかの方法で認証される必要があります。OpenID Federation 仕様では、リクエスト送信者がリクエスト内の公開鍵とペアになっている秘密鍵を所有していることを証明することを要求します。仕様では、使用可能な リクエスト認証方法 として以下の方法を挙げています。
request_object
- 非対称アルゴリズムで署名されたリクエストオブジェクトprivate_key_jwt
- クライアントアサーションを使用したクライアント認証tls_client_auth
- X.509 証明書を使用したクライアント認証self_signed_tls_client_auth
- 自己署名 X.509 証明書を使用したクライアント認証自動クライアント登録はさまざまなエンドポイントで発生する可能性がありますが、利用可能なリクエスト認証方法は、それぞれのエンドポイントの特性によって異なります。
例えば、クライアント認証に基づくリクエスト認証方法は、認可エンドポイントでは使用できません。なぜなら、認可エンドポイントではクライアント認証が実施されないためです。同様に、request_object
を用いたリクエスト認証は、トークンエンドポイントでは使用できません。なぜなら、トークンエンドポイントでは request
または request_uri
のリクエストパラメータを認識しないためです。
以下の表は、エンドポイントごとのリクエスト認証方法の利用可否を示しています。
エンドポイント | リクエスト認証方法 | |||
---|---|---|---|---|
request_object |
private_key_jwt |
tls_client_auth |
self_signed_tls_client_auth |
|
認可エンドポイント | ✓ | N/A | N/A | N/A |
トークンエンドポイント | N/A | ✓ | ✓ | ✓ |
PAR エンドポイント | ✓ | ✓ | ✓ | ✓ |
アイデンティティプロバイダーのディスカバリドキュメントには、サポートするリクエスト認証方法を示す request_authentication_methods_supported
サーバーメタデータが含まれます。
自動クライアント登録に加えて、OpenID Federation 仕様ではクライアントを明示的に登録する方法も定義しています。この仕組みは 明示的クライアント登録(Explicit Client Registration)と呼ばれ、OpenID Connect Dynamic Client Registration 1.0 や RFC 7591 OAuth 2.0 Dynamic Client Registration Protocol で定義される 動的クライアント登録 に似ています。
明示的クライアント登録をサポートするアイデンティティプロバイダーは、フェデレーション登録エンドポイント(Federation Registration Endpoint)を提供します。このエンドポイントに対してクライアント登録リクエストを送信することで、明示的にクライアントを登録できます。
フェデレーション登録エンドポイントに送信できるデータは次のいずれかです。
application/entity-statement+jwt
application/trust-chain+json
クライアント登録が成功すると、フェデレーション登録エンドポイントは エンティティステートメント をレスポンスとして返します。特徴的なのは trust_anchor_id
クレームが含まれている点です。このクレームの値は、登録時に選択されたトラストアンカーのエンティティ ID を示します。
レスポンスの client_id
クライアントメタデータの値は、アイデンティティプロバイダーによって割り当てられたクライアント ID です。この値はエンティティ ID と異なる可能性があります。
明示的クライアント登録をサポートするアイデンティティプロバイダーのディスカバリドキュメントには、client_registration_types_supported
サーバーメタデータに explicit
が含まれ、フェデレーション登録エンドポイントの URL が federation_registration_endpoint
サーバーメタデータで公開されます。
また、明示的に登録されるクライアントの client_registration_types
クライアントメタデータには explicit
を含める必要があります。
トラストチェーン内のすべてのエンティティステートメントには exp
クレーム(有効期限; RFC 7519 セクション 4.1.4)が含まれています。OpenID Federation 仕様ではこのクレームを必須としています。exp
クレームの最小値がトラストチェーン全体の有効期限として扱われます。
OpenID Federation 仕様では、アイデンティティプロバイダーは トラストチェーンの有効期限をクライアントの有効期限として扱う ことを推奨しています。
アイデンティティプロバイダーは、クライアントのトラストチェーンが期限切れになったことを検出すると、新しいトラストチェーンを取得し、クライアントのメタデータを更新しようとします。
trust_chain
リクエストパラメータOAuth/OIDC リクエストには trust_chain
リクエストパラメータを含めることができます。アイデンティティプロバイダーは、このリクエストパラメータで指定されたトラストチェーンを使用して、クライアントのメタデータを更新したり、クライアントを新規登録したりする場合があります。
OpenID Federation 1.0 は Authlete 2.3 以降のバージョンでサポートされています。
仕様は現在も進化を続けており、新機能の追加や破壊的変更が発生する可能性があります。Authlete は、今後のアップデートに合わせて機能を継続的に調整していきます。
OpenID Federation 1.0 の機能を有効にするには、以下の条件を満たす必要があります。これらの条件を満たさない場合、Authlete サーバーは OpenID Federation の仕様を認識しません。
feature.oidc_federation.enabled=true
が設定されていること。federationEnabled
フラグ が true
になっていること。(Service.setFederationEnabled(boolean))また、IDP を適切に動作させるために、以下の設定が必要です。
フェデレーション機能を設定するには、以下の手順を実行します。
https://idp.example.com/fedreg
)を入力する。Authlete サーバーは OpenID Federation のために以下の API を提供します。
/api/federation/configuration
APIこの API は エンティティ構成エンドポイント(/.well-known/openid-federation
)の実装に使用されます。
項目 | 内容 |
---|---|
HTTP メソッド | GET |
項目 | 内容 |
---|---|
HTTP ステータスコード | 200 |
Content-Type | application/json |
action |
"OK" の場合、エンティティ構成エンドポイントは 200 OK を返す |
responseContent |
エンティティ構成の JWT |
authlete-java-common ライブラリには FederationConfigurationRequest クラスと FederationConfigurationResponse クラスが含まれており、Authlete API のリクエストとレスポンスにマッピングできます。
authlete-java-jaxrs ライブラリには、エンティティ構成エンドポイントの実装を支援するユーティリティクラス(FederationConfigurationRequestHandler、BaseFederationConfigurationEndpoint)が含まれています。以下は java-oauth-server の FederationConfigurationEndpoint からの抜粋です。
@Path("/.well-known/openid-federation")
public class FederationConfigurationEndpoint extends BaseFederationConfigurationEndpoint
{
@GET
public Response get()
{
return handle(AuthleteApiFactory.getDefaultApi());
}
}
/api/federation/registration
APIこの API は フェデレーション登録エンドポイント の実装に使用されます。
項目 | 内容 |
---|---|
HTTP メソッド | POST |
Content-Type | application/x-www-form-urlencoded または application/json |
entityConfiguration |
フェデレーション登録リクエストのエンティティ構成 |
trustChain |
フェデレーション登録リクエストのトラストチェーン |
項目 | 内容 |
---|---|
HTTP ステータスコード | 200 |
Content-Type | application/json |
action |
"OK" の場合、フェデレーション登録エンドポイントは 200 OK を返す |
responseContent |
新しく登録されたクライアントのエンティティステートメント |
client |
登録されたクライアントの情報 |
authlete-java-common ライブラリには FederationRegistrationRequest クラスと FederationRegistrationResponse クラスが含まれています。
authlete-java-jaxrs ライブラリには、フェデレーション登録エンドポイントの実装を支援するユーティリティクラス(FederationRegistrationRequestHandler、BaseFederationRegistrationEndpoint)が含まれています。以下は java-oauth-server の FederationRegistrationEndpoint からの抜粋です。
@Path("/api/federation/register")
public class FederationRegistrationEndpoint extends BaseFederationRegistrationEndpoint
{
@POST
@Consumes("application/entity-statement+jwt")
public Response entityConfiguration(String jwt)
{
return handle(AuthleteApiFactory.getDefaultApi(), request().setEntityConfiguration(jwt));
}
@POST
@Consumes("application/trust-chain+json")
public Response trustChain(String json)
{
return handle(AuthleteApiFactory.getDefaultApi(), request().setTrustChain(json));
}
private static FederationRegistrationRequest request()
{
return new FederationRegistrationRequest();
}
}
OpenID Federation 1.0 は、OAuth および OpenID Connect に関連する標準仕様の中でも特に複雑な仕様であり、商用レベルの実装を見つけることは困難です。Authlete はその数少ない例の一つです。
OpenID Federation 1.0 を試してみたい方は、Authlete までお問い合わせください。