RFC 9396 OAuth 2.0 Rich Authorization Requests
RFC 9396 - OAuth 2.0 Rich Authorization Requests
概要
OAuth 2.0 [1] では要求する認可を表すのに scope
パラメータを定義していた。これは単なる文字列であり、多くの場合にはこれで十分である一方で、表現力が不足しているケースもあると考えられる。
そこで本仕様では認可エンドポイントとトークンエンドポイントに authorization_details
パラメータを追加し、これで JSON によって要求する認可を記述する。以下は Section 2.2 に記載の authorization_details
の例である。これと同等の内容を scope
で記述するのは難しいであろう。
[
{
"type": "account_information",
"actions": [
"list_accounts",
"read_balances",
"read_transactions"
],
"locations": [
"https://example.com/accounts"
]
},
{
"type": "payment_initiation",
"actions": [
"initiate",
"status",
"cancel"
],
"locations": [
"https://example.com/payments"
],
"instructedAmount": {
"currency": "EUR",
"amount": "123.50"
},
"creditorName": "Merchant A",
"creditorAccount": {
"iban": "DE02100100109307118603"
},
"remittanceInformationUnstructured": "Ref Number Merchant"
}
]
authorization_details
の構造
authorization_details
は JSON オブジェクトの配列である。各オブジェクトは type
というキーを必須で持ち、これによってそのオブジェクトの型を示す。加えて以下のフィールドが提案されている。これらは必須のパラメータではないが、authorization_details
の設計の際に有用である。
value | type | description |
---|---|---|
locations | array<string> |
リソースやリソースサーバーの場所を示す文字列のリストで、典型的には URI のリストである |
actions | array<string> |
リスースに対して取れるアクションを示す |
datatypes | array<string> |
リソースのうちどのデータへの権限を要求するかを示す |
identifier | string |
リソースサーバーの API で用いるリソースの識別子 |
privileges | array<string> |
リソースに対する権限の種類やレベルを表す |
以下は Section 2.2 で示される authorization_details の例である
[
{
"type":"photo-api",
"actions":[
"read",
"write"
],
"locations":[
"https://server.example.net/",
"https://resource.local/other"
],
"datatypes":[
"metadata",
"images"
],
"geolocation":[
{
"lat":-32.364,
"lng":153.207
},
{
"lat":-35.364,
"lng":158.207
}
]
},
{
"type":"financial-transaction",
"actions":[
"withdraw"
],
"identifier":"account-14-32-32-3",
"currency":"USD"
}
]
認可エンドポイント
認可エンドポイントまたはそれに相当するエンドポイント (デバイス認可エンドポイント[1]やバックチャンネル認証エンドポイント[2])で、リクエストパラメータとして authorization_details
を指定する。RFC 6749 の認可エンドポイントの利用にあたっては、PAR [3] や JAR [4] を利用することもできる。
認可サーバーはここで指定された authorization_details
に基づいてリソースオーナーに対して許諾を得ることになるが、ここでリソースオーナーは authorization_details
のサブセットに対して許諾を出す事もできる [5]。
以下は RFC 6749 の認可エンドポイントのリクエストの例である。このように authorization_details
を丸ごと application/x-www-form-urlencoded
でエンコードする。
GET /authorize?response_type=code
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&code_challenge_method=S256
&code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bwc-uCHaoeK1t8U
&authorization_details=%5B%7B%22type%22%3A%22account%5Finfo
rmation%22%2C%22actions%22%3A%5B%22list%5Faccounts%22%2C%22
read%5Fbalances%22%2C%22read%5Ftransactions%22%5D%2C%22loca
tions%22%3A%5B%22https%3A%2F%2Fexample%2Ecom%2Faccounts%22%
5D%7D%2C%7B%22type%22%3A%22payment%5Finitiation%22%2C%22act
ions%22%3A%5B%22initiate%22%2C%22status%22%2C%22cancel%22%5
D%2C%22locations%22%3A%5B%22https%3A%2F%2Fexample%2Ecom%2Fp
ayments%22%5D%2C%22instructedAmount%22%3A%7B%22currency%22%
3A%22EUR%22%2C%22amount%22%3A%22123%2E50%22%7D%2C%22credito
rName%22%3A%22Merchant%20A%22%2C%22creditorAccount%22%3A%7B
%22iban%22%3A%22DE02100100109307118603%22%7D%2C%22remittanc
eInformationUnstructured%22%3A%22Ref%20Number%20Merchant%22
%7D%5D HTTP/1.1
Host: server.example.com
認可サーバーは受け取った authorization_details
の各オブジェクトを検証し、以下のいずれかに当たるものが含まれる場合にはエラーコード invalid_authorization_details
でエラーを通知する。
-
type
の値が認可サーバーがサポートしない値、またはそのクライアントにはサポートしない値の場合 -
type
で定められた型に含まれないフィールドが含まれる場合 -
type
で定められた型で必要なフィールドの値が不正、または存在しない場合
なお、scope
と authorization_details
を同時に指定することも可能である。ただしこれは scope
から authorization_details
への (もしくは逆の) 段階的な移行のための仕様であり、どちらか一方のみを用いることが推奨される。両方指定された場合は、両方で示される権限の和が要求されているものとして処理をしなければならない。同様に resource
[6] パラメータを指定することも可能である。
-
OpenID Connect Client-Initiated Backchannel Authentication Flow ↩︎
-
RFC 9101 The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR) ↩︎
-
これは
scope
パラメータの場合も同様である ↩︎
トークンエンドポイント
トークンエンドポイントでも authorization_details
を指定することでアクセストークンの持つ権限を指定することができる [1]。
ここで、トークンエンドポイントで指定する authorization_details
はリソースオーナーが許諾を出した範囲内で指定されなければならないが、新しい authorization_details
が既存の authorization_details
に含まれるかの判定は、双方の各 JSON Object の完全一致による比較のみで行えるとは限らないことに注意する必要がある。
例えば認可エンドポイントで以下の authorization_details
が指定されたとし、
[
{
"type": "example_api",
"actions": [
"write"
]
}
]
その後トークンエンドポイントでは以下が指定されたとする。
[
{
"type": "example_api",
"actions": [
"read"
]
}
]
一般に書き込み権限は読み取り権限を含むと考えられるから後者は前者の範囲内である。この結論は各オブジェクトの単純な比較によっては得られない。このように認可サーバーは自らが導入する authorization_details
の type
に応じた適切な比較の仕様を定義する必要がある。
レスポンス
アクセストークンの持つ権限が authorization_details
によって記述されるとき、トークンエンドポイントのレスポンスでは下記のように authorization_details
パラメータを持たなければならない。以下は Section 7 に記載のレスポンスの例である。
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"authorization_details": [
{
"type": "payment_initiation",
"actions": [
"initiate",
"status",
"cancel"
],
"locations": [
"https://example.com/payments"
],
"instructedAmount": {
"currency": "EUR",
"amount": "123.50"
},
"creditorName": "Merchant A",
"creditorAccount": {
"iban": "DE02100100109307118603"
},
"remittanceInformationUnstructured": "Ref Number Merchant"
}
]
}
認可サーバーが決めるポリシーによっては、ここで返却される authorization_details
はクライアントがはじめ認可エンドポイントで指定した authorization_details
とは異なる場合がある。これはリソースオーナーがクライアントが指定した authorization_details
の一部に対して許諾を出した場合に加え、リソースオーナーと認可サーバーのやり取りの中で得られる権限の詳細が決定する場合もありえる。
Section 7.1 に記載の例を示す。まず以下がクライアントのリクエストに含まれる authorization_details
である。ここで accounts
, balances
, transactions
には具体的な account_information
の対象が含まれるが、クライアントが認可リクエストする時点ではここの詳細は決まっておらず、プレースホルダとして記載されているものとする。
[
{
"type": "account_information",
"access": {
"accounts": [],
"balances": [],
"transactions": []
},
"recurringIndicator":true
}
]
その後リソースオーナーと認可サーバーのやり取りの中で詳細が決まり、トークンエンドポイントでは下記の authorization_details
が返される
{
"type":"account_information",
"access":{
"accounts":[
{
"iban":"DE2310010010123456789"
},
{
"maskedPan":"123456xxxxxx1234"
}
],
"balances":[
{
"iban":"DE2310010010123456789"
}
],
"transactions":[
{
"iban":"DE2310010010123456789"
},
{
"maskedPan":"123456xxxxxx1234"
}
]
},
"recurringIndicator":true
}
]
-
トークンエンドポイントはリクエストパラメータとして
scope
を受け付けない場合もある (認可コードフローなど)。authorization_details
はどの場合に指定できるのかについては仕様に記述は見当たらなかった ↩︎