2. トークン交換リクエストとレスポンス
2.1. リクエスト
クライアントは、[RFC6749] のセクション 4.5 で定義されている拡張グラントタイプメカニズムを使用して、認可サーバーのトークンエンドポイントにトークンリクエストを行うことにより、セキュリティトークンをリクエストします。
認可サーバーへのクライアント認証は、OAuth 2.0 によって提供される通常のメカニズムを使用して行われます。[RFC6749] のセクション 2.3.1 では、クライアントのパスワードベースの認証を定義していますが、クライアント認証は拡張可能であり、他のメカニズムも可能です。たとえば、[RFC7523] は、ベアラー JSON Web Token (JWT) [JWT] を使用したクライアント認証を定義しています。クライアント認証のサポートされている方法、および認証されていないクライアントや識別されていないクライアントを許可するかどうかは、認可サーバーの裁量による展開の決定事項です。クライアント認証を省略すると、侵害されたトークンが STS を介して、侵害されたトークンを所有するすべての人によって他のトークンに活用される可能性があることに注意してください。したがって、クライアント認証により、STS は、どのエンティティが他のエンティティになりすましたり、他のエンティティから委任を受けたりすることを許可されているかについて、追加の認可チェックを行うことができます。
クライアントは、HTTP "POST" メソッドを使用して、拡張グラントタイプでトークンエンドポイントにトークン交換リクエストを行います。[RFC6749] の付録 B で説明されているように、UTF-8 の文字エンコーディングを使用した "application/x-www-form-urlencoded" 形式を使用して、次のパラメータが HTTP リクエストエンティティボディに含まれます。
grant_type
必須。値 urn:ietf:params:oauth:grant-type:token-exchange は、トークン交換が実行されていることを示します。
resource
オプション。クライアントがリクエストされたセキュリティトークンを使用する予定のターゲットサービスまたはリソースを示す URI。これにより、認可サーバーは、発行されるトークンのタイプと内容の決定や、トークンの暗号化の是非と方法など、ターゲットに適切なポリシーを適用できます。多くの場合、クライアントは対話するシステムの論理的な構成についての知識を持っておらず、トークンを使用する予定のサービスの URI しか知りません。resource パラメータを使用すると、クライアントは、認可サーバーに対して、トークン交換リクエストでそのリソースへのアクセスに使用されるのと同じ形式 (通常は https URL) で場所を提供することにより、発行されたトークンを使用する予定の場所を示すことができます。認可サーバーは通常、リソース URI 値から適切なポリシーにマッピングする機能を備えています。resource パラメータの値は、[RFC3986] のセクション 4.3 で指定されている絶対 URI でなければならず (MUST)、クエリコンポーネントを含めることができます (MAY) が、フラグメントコンポーネントを含めてはなりません (MUST NOT)。複数の resource パラメータを使用して、発行されたトークンがリストされている複数のリソースで使用されることを意図していることを示すことができます。resource パラメータの追加の背景と使用法については、[OAUTH-RESOURCE] を参照してください。
audience
オプション。クライアントがリクエストされたセキュリティトークンを使用する予定のターゲットサービスの論理名。これは resource パラメータと同様の目的を果たしますが、クライアントはターゲットサービスの論理名を提供します。名前の解釈には、その値がクライアントと認可サーバーの両方が理解できるものである必要があります。OAuth クライアント識別子、SAML エンティティ識別子 [OASIS.saml-core-2.0-os]、および OpenID Connect 発行者識別子 [OpenID.Core] は、audience パラメータ値として使用される可能性のあるものの例です。ただし、特定の認可サーバーで使用される audience 値は、意図したタイプの値として適切に解釈されるように、そのサーバー内で一意である必要があります。複数の audience パラメータを使用して、発行されたトークンがリストされている複数のオーディエンスで使用されることを意図していることを示すことができます。audience パラメータと resource パラメータを一緒に使用して、論理名とリソース URI が混在する複数のターゲットサービスを示すことができます。
scope
オプション。[RFC6749] のセクション 3.3 で定義されている、スペース区切りの大文字と小文字を区別する文字列のリスト。これにより、クライアントは、トークンが使用されるサービスまたはリソースのコンテキストで、リクエストされたセキュリティトークンの希望するスコープを指定できます。スコープの値と関連するセマンティクスはサービス固有であり、関連するサービスドキュメントで説明されていることが期待されます。
requested_token_type
オプション。リクエストされたセキュリティトークンのタイプを表す、セクション 3 で説明されている識別子。リクエストされたタイプが指定されていない場合、発行されるトークンタイプは認可サーバーの裁量に委ねられ、resource または audience パラメータによって示されるサービスまたはリソースの要件によって決定される場合があります。
subject_token
必須。リクエストを行っている当事者のアイデンティティを表すセキュリティトークン。通常、このトークンのサブジェクトは、リクエストに応じて発行されるセキュリティトークンのサブジェクトになります。
subject_token_type
必須。subject_token パラメータ内のセキュリティトークンのタイプを示す、セクション 3 で説明されている識別子。
actor_token
オプション。行動当事者のアイデンティティを表すセキュリティトークン。通常、これは、リクエストされたセキュリティトークンを使用し、サブジェクトに代わって行動することを許可された当事者になります。
actor_token_type
actor_token パラメータ内のセキュリティトークンのタイプを示す、セクション 3 で説明されている識別子。これは、actor_token パラメータがリクエストに存在する場合に必須 (REQUIRED) ですが、それ以外の場合は含めてはなりません (MUST NOT)。
リクエストを処理する際、認可サーバーは、示されたトークンタイプに対して適切な検証手順を実行しなければならず (MUST)、アクタートークンが存在する場合は、その示されたトークンタイプに対しても適切な検証手順を実行しなければなりません。特定のトークンの有効性基準と詳細は、本書の範囲外であり、それぞれのトークンのタイプとその内容に固有です。
トークンタイプに固有の 1 回限りの使用またはその他のセマンティクスがない場合、トークン交換を実行する行為は、サブジェクトトークンまたはアクタートークンの有効性に影響を与えません。さらに、交換は 1 回限りのイベントであり、入力トークンと出力トークンの間に緊密な連携を作成しません。そのため、(たとえば) 出力トークンの有効期限が入力トークンの有効期限の影響を受ける可能性がある一方で、入力トークンの更新または延長が出力トークンのプロパティに反映されることは期待されていません。トークン失効イベントを伝播することは、依然として適切または望ましい場合があります。ただし、そうすることは STS プロトコルの一般的なプロパティではなく、特定の実装、トークンタイプ、または展開に固有のものです。
2.1.1. リソース、オーディエンス、およびスコープ間の関係
トークンをリクエストするとき、クライアントは、audience および resource パラメータを使用して、そのトークンを使用する予定の希望するターゲットサービスを示すだけでなく、scope パラメータを使用して、リクエストされたトークンの希望するスコープを示すことができます。このようなリクエストのセマンティクスは、クライアントが、リクエストされたすべてのターゲットサービスで使用可能な、リクエストされたスコープを持つトークンを求めているということです。事実上、トークンのリクエストされたアクセス権は、すべてのターゲットサービスにおけるすべてのスコープの直積です。
認可サーバーは、トークンリクエストに応じることを望まないか、応じることができない場合がありますが、非常に広範なアクセス権が求められている場合、リクエストに応じられない可能性は大幅に高くなります。そのため、展開内のシステムの関係に関する特定の知識がない場合、クライアントは、リクエストされるアクセスの広さ、特にターゲットサービスの数について慎重であるべきです。認可サーバーは、セクション 2.2.2 で定義されている invalid_target エラーコードを使用して、同時にあまりにも多くのターゲットサービスへのアクセスをリクエストしたことをクライアントに通知できます。
2.2. レスポンス
認可サーバーは、[RFC6749] のセクション 5 で指定されているトークンエンドポイントからの通常の OAuth 2.0 レスポンスでトークン交換リクエストに応答します。詳細と説明は、以下のサブセクションで提供されます。
2.2.1. 成功したレスポンス
リクエストが有効であり、認可サーバーのすべてのポリシーおよびその他の基準を満たしている場合、[RFC8259] で指定されている "application/json" メディアタイプと HTTP 200 ステータスコードを使用して、HTTP レスポンスのエンティティボディに次のパラメータを追加することにより、成功したトークンレスポンスが構築されます。パラメータは、各パラメータを最上位に追加することにより、JavaScript Object Notation (JSON) 構造にシリアル化されます。パラメータ名と文字列値は JSON 文字列として含まれます。数値は JSON 数値として含まれます。パラメータの順序は重要ではなく、異なる場合があります。
access_token
必須。トークン交換リクエストに応じて認可サーバーによって発行されたセキュリティトークン。[RFC6749] のセクション 5.1 の access_token パラメータは、ここでリクエストされたトークンを運ぶために使用されます。これにより、このトークン交換プロトコルは、トークンエンドポイント用に定義された既存の OAuth 2.0 リクエストおよびレスポンス構造を使用できます。識別子 access_token は歴史的な理由で使用されており、発行されるトークンは OAuth アクセストークンである必要はありません。
issued_token_type
必須。発行されたセキュリティトークンの表現のための、セクション 3 で説明されている識別子。
token_type
必須。[RFC6749] のセクション 7.1 で指定されている、発行されたアクセストークンの使用方法を指定する、大文字と小文字を区別しない値。これは、保護されたリソースにアクセスするためにアクセストークンを利用する方法に関する情報をクライアントに提供します。たとえば、[RFC6750] で指定されている値 "Bearer" は、発行されたセキュリティトークンがベアラートークンであり、クライアントは、トークン自体の内容以外の追加の適格性の証明なしに、そのまま提示できることを示します。このパラメータの意味は、発行されたセキュリティトークンの表現を宣言する issued_token_type パラメータの意味とは異なることに注意してください。「トークンタイプ」という用語は、一般的にセキュリティトークンの構造的または構文的な表現を意味するために使用されます (本仕様のすべての *_token_type パラメータと同様)。発行されたトークンがアクセストークンではないか、アクセストークンとして使用できない場合、token_type 値 "N_A" が使用され、そのコンテキストでは OAuth 2.0 token_type 識別子が適用されないことを示します。
expires_in
推奨。認可サーバーによって発行されたトークンの有効期間 (秒単位)。多くの場合、クライアントはトークンの内容を検査する意向や能力を持っておらず、このパラメータは、トークンが有効であると予想される期間について、一貫したトークンタイプに依存しない指標を提供します。たとえば、値 1800 は、トークンがレスポンスが生成されてから 30 分で期限切れになることを示します。
scope
発行されたセキュリティトークンのスコープがクライアントによってリクエストされたスコープと同じである場合はオプション。それ以外の場合は必須 (REQUIRED)。
refresh_token
オプション。リフレッシュトークンは、通常、交換がある一時的な資格情報 (subject_token) を、他のコンテキストで使用するための別の一時的な資格情報 (発行されたトークン) と交換する場合、発行されません。リフレッシュトークンは、元の資格情報がもはや有効でない場合 (たとえば、ユーザーが存在しない場合や、ユーザーがクライアントとのアクティブなセッションを持たなくなったオフラインシナリオなど) でも、トークン交換のクライアントがリソースにアクセスする機能を必要とする場合に発行できます。本仕様のプロファイルまたは展開では、クライアントが urn:ietf:params:oauth:grant-type:token-exchange グラントタイプリクエストに応答してリフレッシュトークンを期待すべき条件を明確に文書化する必要があります (SHOULD)。
2.2.2. エラーレスポンス
リクエスト自体が無効である場合、あるいは subject_token または actor_token が何らかの理由で無効であるか、ポリシーに基づいて受け入れられない場合、認可サーバーは、[RFC6749] のセクション 5.2 で指定されているエラーレスポンスを構築しなければなりません (MUST)。error パラメータの値は、invalid_request エラーコードでなければなりません (MUST)。
認可サーバーが、resource または audience パラメータによって示される任意のターゲットサービスに対してトークンを発行することを望まない、または発行できない場合、invalid_target エラーコードをエラーレスポンスで使用すべきです (SHOULD)。
認可サーバーは、[RFC6749] のセクション 5.2 で説明されている error_description を使用して、エラーの理由に関する追加情報を含めることができます (MAY)。
他のエラーコードも、必要に応じて使用できます。
2.3. トークン交換の例
次の例は、OAuth リソースサーバーが交換中にクライアントの役割を担う、仮想的なトークン交換を示しています。リソースサーバーは、保護されたリソースリクエストで受け取ったアクセストークンを、バックエンドサービスの呼び出しに使用する新しいトークンと交換します (例の余分な改行とインデントは、表示目的のみです)。
図 1 は、[RFC6750] のセクション 2.1 で指定されている、Authorization ヘッダーに OAuth アクセストークンを含む保護されたリソースリクエストを受信するリソースサーバーを示しています。
GET /resource HTTP/1.1
Host: frontend.example.com
Authorization: Bearer accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
図 1: 保護されたリソースリクエスト
図 2 では、リソースサーバーはトークン交換のクライアントの役割を担い、図 1 のリクエストからのアクセストークンは、セクション 2.1 で指定されたリクエストを使用して認可サーバーに送信されます。subject_token パラメータの値はアクセストークンを運び、subject_token_type パラメータの値はそれが OAuth 2.0 アクセストークンであることを示します。クライアントの役割を果たすリソースサーバーは、その識別子とシークレットを使用して、HTTP Basic 認証スキームを使用して認可サーバーに対して認証を行います。resource パラメータは、発行されたトークンが使用されるバックエンドサービスの場所 <https://backend.example.com/api> を示します。
POST /as/token.oauth2 HTTP/1.1
Host: as.example.com
Authorization: Basic cnMwODpsb25nLXNlY3VyZS1yYW5kb20tc2VjcmV0
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&resource=https%3A%2F%2Fbackend.example.com%2Fapi
&subject_token=accVkjcJyb4BWCxGsndESCJQbdFMogUC5PbRDqceLTC
&subject_token_type=
urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
図 2: トークン交換リクエスト
認可サーバーは、クライアントの資格情報と、トークン交換リクエストで提示された subject_token を検証します。resource パラメータから、認可サーバーはリクエストに適用する適切なポリシーを決定し、<https://backend.example.com> での使用に適したトークンを発行できます。図 3 に示されているレスポンスの access_token パラメータには、新しいトークンが含まれています。これは、それ自体が 1 分間有効なベアラー OAuth アクセストークンです。トークンはたまたま JWT ですが、その構造と形式はクライアントには不透明であるため、issued_token_type はそれがアクセストークンであることのみを示します。
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
{
"access_token":"eyJhbGciOiJFUzI1NiIsImtpZCI6IjllciJ9.eyJhdWQiOiJo
dHRwczovL2JhY2tlbmQuZXhhbXBsZS5jb20iLCJpc3MiOiJodHRwczovL2FzLmV
4YW1wbGUuY29tIiwiZXhwIjoxNDQxOTE3NTkzLCJpYXQiOjE0NDE5MTc1MzMsIn
N1YiI6ImJkY0BleGFtcGxlLmNvbSIsInNjb3BlIjoiYXBpIn0.40y3ZgQedw6rx
f59WlwHDD9jryFOr0_Wh3CGozQBihNBhnXEQgU85AI9x3KmsPottVMLPIWvmDCM
y5-kdXjwhw",
"issued_token_type":
"urn:ietf:params:oauth:token-type:access_token",
"token_type":"Bearer",
"expires_in":60
}
図 3: トークン交換レスポンス
その後、リソースサーバーは、図 4 に示すように、新しく取得したアクセストークンを使用してバックエンドサーバーにリクエストを行うことができます。
GET /api HTTP/1.1
Host: backend.example.com
Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6IjllciJ9.eyJhdWQ
iOiJodHRwczovL2JhY2tlbmQuZXhhbXBsZS5jb20iLCJpc3MiOiJodHRwczovL2
FzLmV4YW1wbGUuY29tIiwiZXhwIjoxNDQxOTE3NTkzLCJpYXQiOjE0NDE5MTc1M
zMsInN1YiI6ImJkY0BleGFtcGxlLmNvbSIsInNjb3BlIjoiYXBpIn0.40y3ZgQe
dw6rxf59WlwHDD9jryFOr0_Wh3CGozQBihNBhnXEQgU85AI9x3KmsPottVMLPIW
vmDCMy5-kdXjwhw
図 4: バックエンドの保護されたリソースリクエスト
その他の例は、付録 A に記載されています。