OpenID Federation 1.0

はじめに

このドキュメントでは OpenID Federation 1.0 について説明します。

変更履歴
日付 変更内容
2023-01-01
  • 初版を公開
2024-08-03
  • 仕様の名称が "OpenID Connect Federation 1.0" から "OpenID Federation 1.0" に変更されたため、テキストおよび図を更新
  • "はじめに" セクションを追加し、"変更履歴" を掲載

概要

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 の概要を示しています。

トラストチェーン

技術的には、トラストチェーンは JWTRFC 7519 JSON Web Token)のシーケンスであり、リーフエンティティ、中間認証機関(ゼロ個以上)、およびトラストアンカーによって発行されます。

リーフエンティティによる JWT の発行

リーフエンティティは、自身の秘密鍵で署名した 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 は、中間認証機関の秘密鍵で署名されます。

JWT の目的は、中間認証機関がリーフエンティティを認可していることを示すことです。そのため、sub クレームにはリーフエンティティの識別子が格納され、iss クレームには中間認証機関の識別子が格納されます。

さらに、jwks クレームにはリーフエンティティの公開鍵が格納されます。

トラストアンカーによる JWT の発行

トラストチェーンは、トラストアンカーの秘密鍵で署名された 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.0RFC 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.comhttps://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.0RFC 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.0RFC 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 仕様では、リクエスト送信者がリクエスト内の公開鍵とペアになっている秘密鍵を所有していることを証明することを要求します。仕様では、使用可能な リクエスト認証方法 として以下の方法を挙げています。

  1. request_object - 非対称アルゴリズムで署名されたリクエストオブジェクト
  2. private_key_jwt - クライアントアサーションを使用したクライアント認証
  3. tls_client_auth - X.509 証明書を使用したクライアント認証
  4. 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.0RFC 7591 OAuth 2.0 Dynamic Client Registration Protocol で定義される 動的クライアント登録 に似ています。

明示的クライアント登録をサポートするアイデンティティプロバイダーは、フェデレーション登録エンドポイント(Federation Registration Endpoint)を提供します。このエンドポイントに対してクライアント登録リクエストを送信することで、明示的にクライアントを登録できます。

フェデレーション登録エンドポイントに送信できるデータは次のいずれかです。

  1. エンティティ構成(Entity Configuration): Content-Type は application/entity-statement+jwt
  2. トラストチェーン(Trust Chain): エンティティステートメントの JSON 配列。Content-Type は 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 リクエストパラメータを含めることができます。アイデンティティプロバイダーは、このリクエストパラメータで指定されたトラストチェーンを使用して、クライアントのメタデータを更新したり、クライアントを新規登録したりする場合があります。

Authlete による実装

バージョン

OpenID Federation 1.0 は Authlete 2.3 以降のバージョンでサポートされています。

仕様は現在も進化を続けており、新機能の追加や破壊的変更が発生する可能性があります。Authlete は、今後のアップデートに合わせて機能を継続的に調整していきます。

機能の有効化

OpenID Federation 1.0 の機能を有効にするには、以下の条件を満たす必要があります。これらの条件を満たさない場合、Authlete サーバーは OpenID Federation の仕様を認識しません。

  1. Authlete サーバーfeature.oidc_federation.enabled=true が設定されていること。
  2. サービスの federationEnabled フラグtrue になっていること。(Service.setFederationEnabled(boolean)

また、IDP を適切に動作させるために、以下の設定が必要です。

  1. 少なくとも 1 つの認証機関(中間認証機関またはトラストアンカー)を登録 する必要があります。登録がないと、エンティティ構成を生成できません。(Service.setAuthorityHints(URI[])
  2. 少なくとも 1 つのトラストアンカーとその JWK セットを登録 する必要があります。登録がないと、どのトラストチェーンも信頼できません。(Service.setTrustAnchors(TrustAnchor[])
  3. OpenID Federation 専用の秘密鍵を 1 つ以上登録 する必要があります。登録がないと、エンティティステートメントに署名できません。(Service.setFederationJwks(String)
  4. 自動クライアント登録または明示的クライアント登録のいずれかをサポート する必要があります。サポートがないと、フェデレーションクライアントを登録できません。(Service.setSupportedClientRegistrationTypes(ClientRegistrationType[])

フェデレーションの設定

フェデレーション機能を設定するには、以下の手順を実行します。

  1. Authlete Management Console にログイン する。
  2. [Service Settings] > [Endpoints] > [Federation] に移動する。
  3. Federation Support セクションでトグルを有効にし、OpenID Federation 1.0 を有効化する。
  4. Client Registration Types で、以下のいずれか、または両方を選択する:
    • Automatic: 自動クライアント登録を有効化
    • Explicit: 明示的クライアント登録を有効化
  5. Registration Endpoint フィールドに、フェデレーション登録エンドポイントの URI(例: https://idp.example.com/fedreg)を入力する。
  6. Save Changes をクリックし、設定を適用する。

Authlete API

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 ライブラリには、エンティティ構成エンドポイントの実装を支援するユーティリティクラス(FederationConfigurationRequestHandlerBaseFederationConfigurationEndpoint)が含まれています。以下は java-oauth-serverFederationConfigurationEndpoint からの抜粋です。

@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 ライブラリには、フェデレーション登録エンドポイントの実装を支援するユーティリティクラス(FederationRegistrationRequestHandlerBaseFederationRegistrationEndpoint)が含まれています。以下は java-oauth-serverFederationRegistrationEndpoint からの抜粋です。

@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 までお問い合わせください