LoginSignup
11
8

More than 1 year has passed since last update.

RFC 8693 OAuth 2.0 Token Exchange

Posted at

はじめに

RFC 8693 OAuth 2.0 Token Exchange は、トークンエンドポイントに既存のトークンを提示して新しいトークンを取得する方法を定義している技術仕様です。入力として提示するトークンはサブジェクトトークン (Subject Token) と呼ばれます。任意ですが、もう一つトークンを入力として与えることができ、そちらはアクタートークン (Actor Token) と呼ばれます。

次の図はトークン交換フローを示しています。

token_exchange.ja.png

当仕様はとても柔軟です。逆に言うと、安全なトークン交換に必要となる詳細事項について当仕様は定義していません。そのため、認可サーバーの実装はそれぞれ独自規則を定め、仕様を補完しなければなりません。

本記事は Authlete 社ウェブサイト上の記事『RFC 8693 OAuth 2.0 Token Exchange』の一部転載です。

仕様

トークンタイプ

トークン交換フローには 3 つのトークンが登場します。サブジェクトトークン、アクタートークン、そして新しく発行されるトークンです。それらのトークンが取りうる型として、仕様は次のトークンタイプを列挙し、それぞれにトークンタイプ識別子を割り当てています。これらのトークンタイプ識別子は IANA (Internet Assigned Numbers Authority) の OAuth Parameters / OAuth URI に登録されています。

トークンタイプ トークンタイプ識別子
JWT urn:ietf:params:oauth:token-type:jwt
アクセストークン urn:ietf:params:oauth:token-type:access_token
リフレッシュトークン urn:ietf:params:oauth:token-type:refresh_token
ID トークン urn:ietf:params:oauth:token-type:id_token
SAML 1.1 アサーション urn:ietf:params:oauth:token-type:saml1
SAML 2.0 アサーション urn:ietf:params:oauth:token-type:saml2

JWT 用のトークンタイプ識別子は RFC 7519 JSON Web Token (JWT) で定義されています。他の識別子は RFC 8693 OAuth 2.0 Token Exchange で定義されています。

サブジェクトトークン

( RFC 8693 Section 2.1. Request より抜粋 )

A subject token represents the identity of the party on behalf of whom the request is being made.

サブジェクトトークンは、リクエストの当事者のアイデンティティを表すものである。

サブジェクトトークンにより特定されるサブジェクトが新しく発行されるトークンのサブジェクトとして用いられることを仕様は想定しています。

アクタートークン

( RFC 8693 Section 2.1. Request より抜粋 )

An actor token represents the identity of the acting party.

アクタートークンは、代行者のアイデンティティを表すものである。

新しく発行されたトークンのサブジェクトと、そのトークンを利用する代行者とを区別する必要がある場合、認可サーバーの実装はアクタートークンを活用し、発行するトークンに代行者に関する情報を埋め込んでもよいでしょう。RFC 86934.1 節4.4 節は、代行者に関連する JWT クレームを定義しています。

トークン交換リクエスト

トークン交換リクエストはトークンリクエストの一種です。

グラントタイプ

他のトークンリクエストとトークン交換リクエストを区別するため、新しいグラントタイプ urn:ietf:params:oauth:grant-type:token-exchange が仕様で定義されています。この値はトークンリクエストの grant_type リクエストパラメーターの値として使用されます。

クライアントの特定と認証

仕様は、トークンエンドポイントにおける クライアント認証 を要求しておらず、さらにはクライアントの特定すら要求していません。これについて RFC 8693Section 2.1. Request は次のように述べています。

The supported methods of client authentication and whether or not to allow unauthenticated or unidentified clients are deployment decisions that are at the discretion of the authorization server.

サポートするクライアント認証方式や、未認証または未特定のクライアントを許容するかどうかは、認可サーバーの自由裁量の範疇で運用方針に応じて決定する事項である。

技術的には、『未認証のクライアント』はパブリッククライアントを意味し (参照: RFC 6749 Section 2.1. Client Types)、『未特定のクライアント』はトークンリクエストがクライアントを特定するための情報を含んでいないことを意味します。

RFC 8693付録 1.1 には特定不能なクライアントからのトークン交換リクエストの例が示されていますが、任意の特定不能クライアント (API 呼出者) にトークン交換リクエストを無条件で許可することにはリスクがあります。これが、安全なトークン交換のために認可サーバーの実装が独自規則を定めて RFC 8693 を補完しなければならない理由です。

リクエストパラメーター

リクエストパラメーター 要否 説明
grant_type 必須 urn:ietf:params:oauth:grant-type:token-exchange という値によりトークンリクエストがトークン交換リクエストであることが示されます。
resource 任意 新しく発行されるトークンに結び付けられるリソース。このリクエストパラメーターは複数回指定してもよいとされています。詳細は RFC 8707 Resource Indicators for OAuth 2.0 を参照してください。
audience 任意 新しく発行されるトークンの対象。このリクエストパラメーターも複数回指定してもよいとされています。
scope 任意 新しく発行されるトークンに結び付けられるスコープ群の名前をスペース区切りで並べたもの。
requested_token_type 任意 クライアントが希望する、新しく発行されるトークンのトークンタイプ。登録されているトークンタイプ識別子のいずれか。
subject_token 必須 サブジェクトトークンの値。
subject_token_type 必須 サブジェクトトークンのトークンタイプ。登録されているトークンタイプ識別子のいずれか。
actor_token 任意 アクタートークンの値。
actor_token_type 任意 アクタートークンのトークンタイプ。登録されているトークンタイプ識別子のいずれか。actor_token リクエストパラメーターが与えられている場合、このリクエストパラメーターは必須。逆に、actor_token リクエストパラメーターが与えられていない場合、このリクエストパラメーターが存在していてはいけません。

RFC 6749 The OAuth 2.0 Authorization Framework は "Request and response parameters MUST NOT be included more than once." (リクエストパラメーターとレスポンスパラメーターは複数回含まれていてはならない) と述べています。resource リクエストパラメーターと audience リクエストパラメーターは例外です。

トークン交換レスポンス

トークン交換レスポンスはトークンレスポンスの一種です。

レスポンスパラメーター

レスポンスパラメーター 要否 説明
access_token 必須 トークンタイプに関わらず、新しく発行されたトークンの値はこのレスポンスパラメーターにセットされます。
issued_token_type 必須 新しく発行されたトークンのトークンタイプ。登録されているトークンタイプ識別子のいずれか。
token_type 必須 新しく発行されたトークンのトークンタイプが urn:ietf:params:oauth:token-type:access_token のとき、このレスポンスパラメーターは RFC 6749 The OAuth 2.0 Authorization Framework で定義されているものと同じ意味を持ちます。それ以外の場合は "N_A" がセットされます。
expires_in 任意 新しく発行されたトークンの有効時間 (秒単位)。
scope 任意 新しく発行されたトークンに結び付けられたスコープ群。新しく発行されたトークンに結び付けられたスコープ群の実際の組がトークン交換リクエストで要求された組と異なる場合、このレスポンスパラメーターは必須。
refresh_token 任意 リフレッシュトークン (参照: RFC 6749 Section 6. Refreshing an Access Token)。

実装

RFC 8693 は Authlete 2.3 以降でサポートされます。

実装に関する情報については Authlete 社ウェブサイト上の記事『RFC 8693 OAuth 2.0 Token Exchange』の『実装』をご参照ください。

認可サーバー実装の例

Java で書かれたオープンソースの認可サーバー実装サンプルである java-oauth-serverTokenExchanger.java が、トークン交換リクエスト処理の実装サンプルとなっています。

当実装は一例に過ぎず、商用利用可能な完璧さは意図していないのでご注意ください。

リクエストとレスポンスの例

1. 何らかの方法で ID トークンを用意する。

$ ID_TOKEN=eyJraWQiOiJhdXRobGV0ZS1mYXBpZGV2LWFwaS0yMDE4MDUyNCIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJodHRwczovL2ZhcGlkZXYtYXMuYXV0aGxldGUubmV0LyIsInN1YiI6IjEwMDQiLCJhdWQiOlsiNTg5OTQ2MzYxNDQ0ODA2MyJdLCJleHAiOjE2NTg2NzExMzAsImlhdCI6MTY1ODY3MDgzMCwiYXV0aF90aW1lIjoxNjU4NjcwODMwLCJub25jZSI6IjEyMzQ1Njc4OSIsInZlcmlmaWVkX2NsYWltcyI6eyJ2ZXJpZmljYXRpb24iOnsidHJ1c3RfZnJhbWV3b3JrIjoibmlzdF84MDBfNjNBIn0sImNsYWltcyI6eyJnaXZlbl9uYW1lIjoiSW5nYSIsImZhbWlseV9uYW1lIjoiU2lsdmVyc3RvbmUiLCJiaXJ0aGRhdGUiOiIxOTkxLTExLTA2IiwiOmFnZV8xOF9vcl9vdmVyIjpudWxsfX19.mxE8FQaDb0edY_rWasSQ7pEMXbFon7oWr-Ccv1dB15q8eh2MaKRGrgvwPw_XjAdXlMNzkcV6iEUjRUvLGTvzm7_45cdoOxRX1xWzQw-vwvRbM46xd3Yht3EVjyRUUBJ_92J1yBmu7Nn93rygcnCE-fC_bSTSIJWgEnoC7dpxHYnoJ2QHrIOYFMBAA_3ZYCLGpgiWbIZnB2D1ib2eqwJ9zoJqeFNEBhXo9ThYkASHYaG-ZWofy7364lgeV4Rqy1r4XqzchFRW4yzWs_IM72bTtXTUkstlNOxZU12KEz50uVhtcOXv06iI71I9vceRP-ZVICpq7Knt0vEKWTM41E3ziw

2. トークン交換リクエストを行う。

$ curl http://localhost:8080/api/token -d grant_type=urn:ietf:params:oauth:grant-type:token-exchange -d subject_token=$ID_TOKEN -d subject_token_type=urn:ietf:params:oauth:token-type:id_token -d client_id=5908895171 -d scope=email

3. トークン交換レスポンスを受け取る。

{
  "access_token":"NEdL-q9EfOI4S5XzaMeimXAXVqS139Jm9DTYeLUAd5o",
  "issued_token_type":"urn:ietf:params:oauth:token-type:access_token",
  "token_type":"Bearer",
  "expires_in":86400,
  "scope":"email",
  "refresh_token":"pK9f5OWIrx58_XWrE_SpCLLN-BM673ljliTSffjqwao"
}
11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8