インターネットドラフト OAuth 2.1 認可フレームワーク 2026年3月
Hardt ほか 2026年9月3日に失効 [ページ]
ワーキンググループ:
OAuth ワーキンググループ
インターネットドラフト:
draft-ietf-oauth-v2-1-15
公開日:
予定されるステータス:
標準化トラック
失効日:
著者:
D. Hardt
Hellō
A. Parecki
Okta
T. Lodderstedt
SPRIND

OAuth 2.1 認可フレームワーク

概要

OAuth 2.1 認可フレームワークは、 アプリケーションが、リソース所有者と認可サービスとの間の 承認操作を調整することによりリソース所有者に代わって、または アプリケーションが自らのためにアクセスを取得できるようにすることにより、 保護されたリソースへの限定的なアクセスを取得できるようにします。この 仕様は、RFC 6749 で説明されている OAuth 2.0 認可 フレームワーク、および RFC 6750 の Bearer Token Usage を置き換え、 廃止します。

議論の場

この注記は、RFC として公開される前に削除されます。

この文書に関する議論は、 OAuth ワーキンググループのメーリングリスト (oauth@ietf.org) で行われ、 そのアーカイブは https://mailarchive.ietf.org/arch/browse/oauth/ にあります。

このドラフトのソースおよび課題トラッカーは、 https://github.com/oauth-wg/oauth-v2-1 にあります。

このメモの位置付け

このインターネットドラフトは、BCP 78 および BCP 79 の規定に 完全に準拠して提出されています。

インターネットドラフトは、Internet Engineering Task Force (IETF) の作業文書です。他のグループも作業 文書をインターネットドラフトとして配布する場合があることに注意してください。 現在のインターネットドラフトの一覧は https://datatracker.ietf.org/drafts/current/ にあります。

インターネットドラフトは、最大 6 か月間有効なドラフト文書であり、 いつでも他の文書によって更新、置換、または廃止される可能性があります。 インターネットドラフトを参考資料として使用したり、「作業中」 以外のものとして引用したりすることは不適切です。

このインターネットドラフトは 2026年9月3日に失効します。

目次

1. はじめに

OAuth は、クライアントの役割をリソース所有者の役割から 分離することにより、クライアントサーバー認証モデルに認可レイヤーを 導入します。OAuth では、クライアントはリソース所有者によって制御され、 リソースサーバーによってホストされるリソースへのアクセスを要求します。 保護されたリソースにアクセスするためにリソース所有者のクレデンシャルを 使用する代わりに、クライアントはアクセストークンを取得します。これは、 スコープや有効期間など、特定のアクセス属性の集合を表すクレデンシャルです。 アクセストークンは、リソース所有者の承認を得て、認可サーバーによって クライアントに発行されます。クライアントはアクセストークンを使用して、 リソースサーバーでホストされる保護されたリソースにアクセスします。

従来の、より限定的なクライアントサーバー認証モデルでは、クライアントは リソース所有者のクレデンシャルを使用してサーバーに認証することにより、 サーバー上のアクセス制限付きリソース(保護されたリソース)を要求します。 アプリケーションに制限付きリソースへのアクセスを提供するために、 リソース所有者はそのクレデンシャルをアプリケーションと共有します。 これにより、いくつかの問題と制限が生じます:

OAuth が使用される例として、エンドユーザー(リソース所有者)が金融 管理 サービス(クライアント)に、銀行サービス(リソースサーバー)に保存された 機密性の高い取引履歴へのアクセスを許可する一方で、金融管理サービスに ユーザー名とパスワードを共有しない場合があります。代わりに、ユーザーは 自分の金融機関のサーバー(認可サーバー)で直接認証し、 そのサーバーが金融管理サービスに委任固有のクレデンシャル (アクセストークン)を発行します。

この関心事の分離により、多要素認証やパスワードレス認証など、 より高度なユーザー認証方式を、アプリケーションに変更を加えることなく 使用できるようにもなります。すべてのユーザー認証ロジックが認可サーバーで 処理されるため、アプリケーションは特定の認証メカニズムの実装詳細を 気にする必要がありません。これにより、認可サーバーはユーザー認証ポリシーを 管理し、将来それらを変更する場合でもアプリケーションと変更を調整せずに 済ませることができます。

認可レイヤーは、リソースサーバーがリクエストが認可されているかを 判断する方法も簡略化できます。従来は、クライアントを認証した後、 各リソースサーバーが各 API 呼び出しでクライアントが認可されているかを 計算するためにポリシーを評価していました。分散システムでは、ポリシーを すべてのリソースサーバーに同期する必要があるか、またはリソースサーバーが 各リクエストを処理するために中央のポリシーサーバーを呼び出す必要があります。 OAuth では、ポリシーの評価は認可サーバーによって新しいアクセストークンが 作成されるときにのみ行われます。認可されたアクセスがアクセストークン内に 表現されている場合、リソースサーバーはポリシーを評価する必要がなくなり、 アクセストークンを検証するだけで済みます。この簡略化は、アプリケーションが リソース所有者の代理として動作している場合にも、自身の代理として動作している場合にも 適用されます。

OAuth は認可プロトコルであり、認証プロトコルではありません。OAuth は ユーザー認証を達成するために必要な構成要素を定義していないためです。 目的がユーザーを認証することである場合、認証プロトコルが必要です。例として OpenID Connect [OpenID.Connect] があります。これは OAuth を基盤として、認証プロトコルに必要なセキュリティ特性と 構成要素を提供します。

アクセストークンは、クライアントに付与された認可を表します。クライアントが アクセストークンを独自 API に提示し、その API がリソース所有者の ユーザー識別子を返し、その API の結果をユーザー認証の代替として 使用することは一般的な慣行です。この慣行は OAuth 標準または セキュリティ上の考慮事項の一部ではなく、リソース所有者によって 考慮されていない可能性があります。実装者は、この慣行を採用する前に、 リソースサーバーの文書を慎重に参照するべきです。

この仕様は HTTP [RFC9110] とともに使用するように設計されています。HTTP 以外の プロトコル上で OAuth を使用することは、この仕様の範囲外です。

OAuth 2.0 Authorization Framework [RFC6749] が 2012年10月に公開されて以来、OAuth 2.0 for Native Apps [RFC8252]、 OAuth Security Best Current Practice [RFC9700]、 および OAuth 2.0 for Browser-Based Apps [I-D.ietf-oauth-browser-based-apps] によって更新されてきました。 The OAuth 2.0 Authorization Framework: Bearer Token Usage [RFC6750][RFC9700] によって更新されています。この 標準化トラック仕様は、これらすべての文書の情報を統合し、 [RFC9700] において安全でないことが判明した 機能を削除します。

1.1. 役割

OAuth は 4 つの役割を定義します:

"resource owner":

保護されたリソースへのアクセスを付与できる主体です。 リソース所有者が人である場合、エンドユーザーと呼ばれます。 これは "RO" と略されることがあります。

"resource server":

保護されたリソースをホストするサーバーであり、アクセストークンを使用した 保護されたリソースリクエストを受け入れ、それに応答できます。 リソースサーバーは、多くの場合 API 経由でアクセスできます。 これは "RS" と略されることがあります。

"client":

リソース所有者の代理として、その認可に基づいて保護された リソースリクエストを行うアプリケーションです。"client" という用語は、 特定の実装特性(たとえば、アプリケーションがサーバー、デスクトップ、 またはその他のデバイス上で実行されるかどうか)を意味しません。

"authorization server":

リソース所有者を正常に認証し、認可を取得した後、 クライアントにアクセストークンを発行するサーバーです。 これは "AS" と略されることがあります。

この仕様の大部分は、クライアントと認可サーバーとの間の相互作用、 およびクライアントとリソースサーバーとの間の相互作用を定義します。

認可サーバーとリソースサーバーとの間の相互作用は この仕様の範囲外ですが、リソースサーバーと認可サーバーの間の 相互運用性のための選択肢を提供するため、いくつかの拡張が 定義されています。認可サーバーは、リソースサーバーと同じサーバーでも、 別個の主体でもかまいません。単一の認可サーバーは、 複数のリソースサーバーによって受け入れられるアクセストークンを 発行できます。

リソース所有者と認可サーバーとの間の相互作用 (たとえば、エンドユーザーが認可サーバーでどのように自身を認証するか) もこの仕様の範囲外ですが、エンドユーザーに同意を求める際の セキュリティ上の考慮事項など、一部の例外があります。

リソース所有者がエンドユーザーである場合、ユーザーはクライアントと 相互作用します。クライアントが Web ベースのアプリケーションである場合、 ユーザーは、リソース所有者が使用するデバイス上のユーザーエージェント ([RFC9110] の Section 3.5 で説明) を通じてクライアントと相互作用します。 クライアントがネイティブアプリケーションである場合、ユーザーは オペレーティングシステムを通じてクライアントと直接相互作用します。 詳細については Section 2.1 を参照してください。

1.2. プロトコルフロー

     +--------+                               +---------------+
     |        |--(1)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(2)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(3)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(4)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(5)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(6)--- Protected Resource ---|               |
     +--------+                               +---------------+
図 1: 抽象プロトコルフロー

Figure 1 に示される抽象 OAuth 2.1 フローは、 4 つの役割の間の相互作用を説明し、次の手順を含みます:

  1. クライアントはリソース所有者に認可を要求します。 認可リクエストは、(図のように)リソース所有者に直接行うことも、 望ましくは認可サーバーを仲介者として間接的に行うこともできます。

  2. クライアントは認可グラントを受け取ります。これは リソース所有者の認可を表すクレデンシャルであり、この 仕様で定義されている認可グラント種別のいずれか、 または拡張グラント種別を使用して表現されます。 認可グラント種別は、クライアントが認可を要求するために使用した 方法と、認可サーバーがサポートする種別に依存します。

  3. クライアントは認可サーバーで認証し、認可グラントを提示することにより、 アクセストークンを要求します。

  4. 認可サーバーはクライアントを認証し、認可グラントを検証し、 有効であればアクセストークンを発行します。

  5. クライアントはリソースサーバーから保護されたリソースを要求し、 アクセストークンを提示することによって認証します。

  6. リソースサーバーはアクセストークンを検証し、有効であれば リクエストに応答します。

クライアントがリソース所有者から認可グラントを取得するための 推奨される方法(手順 (1) および (2) に示される)は、 認可サーバーを仲介者として使用することです。これは Section 4.1Figure 3 に示されています。

1.3. 認可グラント

認可グラントは、クライアントがアクセストークンを取得するために使用する、 リソース所有者の認可(その保護されたリソースにアクセスするためのもの)を 表します。この仕様は、認可コード、リフレッシュトークン、 およびクライアントクレデンシャルという 3 つのグラント種別と、 追加の種別を定義するための拡張メカニズムを定義します。

1.3.1. 認可コード

認可コードは、アクセストークンを取得するために使用される 一時的なクレデンシャルです。 クライアントがリソース所有者から直接認可を要求する代わりに、 クライアントはリソース所有者を(そのユーザーエージェントを介して) 認可サーバーへ誘導し、認可サーバーは認可コードとともに リソース所有者をクライアントへ戻します。 その後、クライアントは認可コードをアクセストークンと交換できます。

認可コードとともにリソース所有者をクライアントへ戻す前に、 認可サーバーはリソース所有者を認証し、リソース所有者の同意を 求めたり、その他の方法でクライアントのリクエストについて通知したりできます。 リソース所有者は認可サーバーでのみ認証するため、 リソース所有者のクレデンシャルはクライアントと共有されることがなく、 クライアントは多要素認証や委任アカウントなどの追加の認証手順を 知る必要がありません。

認可コードは、クライアントを認証できることや、 アクセストークンをリソース所有者のユーザーエージェントを経由させずに クライアントへ直接送信し、リソース所有者を含む他者へ 露出する可能性を避けられることなど、いくつかの重要な セキュリティ上の利点を提供します。

1.3.2. リフレッシュトークン

リフレッシュトークンは、アクセストークンを取得するために使用される クレデンシャルです。リフレッシュトークンは、認可サーバーによって クライアントに発行される場合があり、現在のアクセストークンが 無効になったり失効したりしたときに新しいアクセストークンを取得するため、 または同一もしくはより狭いスコープを持つ追加のアクセストークンを 取得するために使用されます(アクセストークンは、リソース所有者によって 認可されたものよりも短い有効期間や少ない権限を持つ場合があります)。 リフレッシュトークンの発行は認可サーバーの裁量による任意のものであり、 クライアントの特性、リクエストの特性、認可サーバー内のポリシー、 またはその他の基準に基づいて発行される場合があります。認可サーバーが リフレッシュトークンを発行する場合、それはアクセストークンの発行時 (つまり Figure 2 の手順 (2))に 含まれます。リフレッシュトークンの有効期間も 認可サーバーの裁量によります。

リフレッシュトークンは、リソース所有者によってクライアントに 付与された認可を表す文字列です。この文字列はクライアントにとって 不透明であるとみなされます。リフレッシュトークンは、認可情報を取得するための 識別子である場合もあれば、この情報を文字列自体にエンコードする場合もあります。 アクセストークンとは異なり、リフレッシュトークンは認可サーバーでのみ 使用されることを意図しており、リソースサーバーへ送信されることはありません。

+--------+                                           +---------------+
|        |--(1)------- Authorization Grant --------->|               |
|        |                                           |               |
|        |<-(2)----------- Access Token -------------|               |
|        |               & Refresh Token             |               |
|        |                                           |               |
|        |                            +----------+   |               |
|        |--(3)---- Access Token ---->|          |   |               |
|        |                            |          |   |               |
|        |<-(4)- Protected Resource --| Resource |   | Authorization |
| Client |                            |  Server  |   |     Server    |
|        |--(5)---- Access Token ---->|          |   |               |
|        |                            |          |   |               |
|        |<-(6)- Invalid Token Error -|          |   |               |
|        |                            +----------+   |               |
|        |                                           |               |
|        |--(7)----------- Refresh Token ----------->|               |
|        |                                           |               |
|        |<-(8)----------- Access Token -------------|               |
+--------+           & Optional Refresh Token        +---------------+
図 2: 失効した アクセストークンの更新

Figure 2 に示されるフローは、次の手順を含みます:

  1. クライアントは認可サーバーで認証し、 認可グラントを提示することにより、アクセストークンを要求します。

  2. 認可サーバーはクライアントを認証し、 認可グラントを検証し、有効であればアクセストークンと 任意でリフレッシュトークンを発行します。

  3. クライアントはアクセストークンを提示することにより、 リソースサーバーへ保護されたリソースリクエストを行います。

  4. リソースサーバーはアクセストークンを検証し、 有効であればリクエストに応答します。

  5. 手順 (3) と (4) はアクセストークンが失効するまで繰り返されます。 クライアントがアクセストークンの失効を知っている場合は手順 (7) へ進み、 そうでなければ別の保護されたリソースリクエストを行います。

  6. アクセストークンが無効であるため、リソースサーバーは 無効なトークンエラーを返します。

  7. クライアントはリフレッシュトークンを提示し、 クレデンシャルが発行されている場合はクライアント認証を提供して、 新しいアクセストークンを要求します。クライアント認証要件は、 クライアント種別と認可サーバーのポリシーに基づきます。

  8. 認可サーバーはクライアントを認証し、 リフレッシュトークンを検証し、有効であれば新しいアクセストークン (および任意で新しいリフレッシュトークン)を発行します。

リフレッシュトークンの有効期間をクライアントへ伝える必要はないことに 注意してください。クライアントはその有効期間を知っても、 何か別のことができるわけではないためです。さらに、認可サーバーは 動的な有効期間を使用することを選択する場合があります(たとえば、 リフレッシュトークンが少なくとも 7 日に 1 回使用される限り、 その有効期限を延長するなど)。または、ユーザーがアプリケーションの アクセスを取り消した場合など、任意の理由で予定された失効日より前に リフレッシュトークンを取り消す場合もあります。これは、クライアントがすでに 任意の時点でリフレッシュトークンが失効する場合を処理しなければならないことを 意味します。

リフレッシュトークンがなぜ、いつ失効するかに関係なく、 クライアントが新しいトークンを取得するための道筋は 1 つだけであり、 それは最初から新しい OAuth フローを開始することです。そのため、 リフレッシュトークンの失効をクライアントに伝えるためのプロパティは 定義されていません。

1.3.3. クライアントクレデンシャル

クライアントクレデンシャルまたはその他の形式のクライアント認証 (たとえば、[RFC7523] およびその更新 [I-D.ietf-oauth-rfc7523bis] で説明されているような、 JWT に署名するために使用される秘密鍵)は、認可スコープが クライアントの制御下にある保護されたリソース、または認可サーバーと 事前に取り決められた保護されたリソースに限定されている場合に、 認可グラントとして使用できます。クライアントクレデンシャルは、 認可サーバーと事前に取り決められた認可に基づいて、クライアントが 保護されたリソースへのアクセスを要求する場合に使用されます。

1.4. アクセストークン

アクセストークンは、保護されたリソースにアクセスするために使用される クレデンシャルです。アクセストークンは、クライアントに発行された認可を 表す文字列です。

その文字列は、構造を持っている場合でも、クライアントにとって 不透明であるとみなされます。クライアントはアクセストークン値を 解析できることを期待してはなりません (MUST NOT)。認可サーバーは、 リソースサーバーが期待するもの以外に、一貫したアクセストークンの エンコーディングや形式を使用する必要はありません。

リソース所有者によってクライアントに付与されたアクセスは、 認可サーバーによって作成されるアクセストークンによって表されます。 アクセストークンは、漏えいしたアクセストークンの影響範囲を減らすために 短命です。アクセストークンの有効期限は認可サーバーによって設定されます。

認可サーバーの実装に応じて、トークン文字列はリソースサーバーが 認可情報を取得するために使用される場合もあれば、トークン自体が検証可能な 方法で認可情報を自己包含する場合もあります(つまり、署名されたデータペイロードから 成るトークン文字列)。トークン取得メカニズムの一例は Token Introspection [RFC7662] であり、そこでは RS が AS 上のエンドポイントを呼び出して、クライアントによって提示されたトークンを検証します。 構造化トークン形式の一例は JWT Profile for Access Tokens [RFC9068] であり、 これはアクセストークンデータを JSON Web Token [RFC7519] としてエンコードし署名する方法です。

この仕様の範囲外である追加の認証クレデンシャルが、 クライアントがアクセストークンを使用するために必要となる場合があります。 これは通常、DPoP [RFC9449] や Mutual TLS Certificate-Bound Access Tokens [RFC8705] のような、送信者制約付き アクセストークンと呼ばれます。

アクセストークンは抽象化レイヤーを提供し、異なる認可構成要素 (たとえばユーザー名とパスワード)を、リソースサーバーが理解する 単一のトークンで置き換えます。この抽象化により、取得に使用された 認可グラントよりも制限の強いアクセストークンを発行できるほか、 リソースサーバーが幅広い認証方式を理解する必要をなくすことができます。

アクセストークンは、リソースサーバーのセキュリティ要件に基づいて、 異なる形式、構造、および利用方法(たとえば暗号学的性質)を持つことができます。 アクセストークン属性および保護されたリソースにアクセスするために使用される 方法は、この仕様で説明されている範囲を超えて拡張される場合があります。

アクセストークン(および機密性のあるアクセストークン属性)は、 転送中および保存時に機密として保持されなければならず (MUST)、 認可サーバー、アクセストークンが有効なリソースサーバー、および アクセストークンが発行されたクライアントの間でのみ共有されなければなりません。

認可サーバーは、権限のない当事者が有効なアクセストークンを生成、 変更、または推測できないことを保証しなければなりません (MUST)。

1.4.1. アクセストークンのスコープ

アクセストークンは、アクセスを付与するユーザーが持つ権限よりも 少ない権限でクライアントに発行されることを意図しています。 これは限定された "scope" アクセストークンとして知られています。 認可サーバーとリソースサーバーは、このスコープメカニズムを使用して、 特定のクライアントが持てるリソースの種類やアクセスレベルを 制限できます。

たとえば、クライアントはユーザーのリソースに対する "read" アクセスだけを 必要とし、リソースを更新する必要はない場合があります。そのため、 クライアントは認可サーバーによって定義された読み取り専用スコープを要求し、 リソースの更新には使用できないアクセストークンを取得できます。 これには、認可サーバー、リソースサーバー、およびクライアントの間の 調整が必要です。認可サーバーはクライアントに特定のスコープを 要求する能力を提供し、それらのスコープをクライアントに発行される アクセストークンに関連付けます。リソースサーバーは、限定スコープの アクセストークンが提示されたときにスコープを強制する責任を負います。

OAuth はスコープ値を定義しません。代わりに、スコープは 認可サーバー、または OAuth の拡張やプロファイルによって定義されます。 スコープを定義するそのような拡張の 1 つに [OpenID.Connect] があり、これは ユーザーのプロファイル情報への細粒度アクセスを提供するスコープの集合を 定義します。既知の拡張のスコープと衝突するカスタムスコープを 定義することは避けることが推奨されます。

限定スコープのアクセストークンを要求するために、クライアントは 使用されるグラント種別に応じて、認可エンドポイントまたはトークンエンドポイントで scope リクエストパラメーターを使用します。次に、認可サーバーは scope レスポンスパラメーターを使用して、発行されたアクセストークンのスコープを クライアントに通知します。

scope パラメーターの値は、大文字小文字を区別する文字列の 空白区切りリストとして表現されます。文字列は認可サーバーによって 定義されます。値に複数の空白区切り文字列が含まれる場合、 それらの順序は重要ではなく、各文字列は要求されたスコープに 追加のアクセス範囲を加えます。

    scope       = scope-token *( SP scope-token )
    scope-token = 1*( %x21 / %x23-5B / %x5D-7E )

認可サーバーは、認可サーバーのポリシーまたはリソース所有者の指示に 基づいて、クライアントが要求したスコープを完全に、または部分的に 無視してもよいです (MAY)。発行されたアクセストークンのスコープが クライアントによって要求されたものと異なる場合、認可サーバーは 実際に付与されたスコープをクライアントに通知するため、トークンレスポンス (Section 3.2.3)に scope レスポンスパラメーターを含めなければなりません (MUST)。

クライアントが認可を要求する際に scope パラメーターを省略した場合、 認可サーバーは事前定義されたデフォルト値を使用してリクエストを 処理するか、無効なスコープを示してリクエストを失敗させなければなりません (MUST)。 認可サーバーは、そのスコープ要件とデフォルト値(定義されている場合)を 文書化するべきです (SHOULD)。

1.4.2. Bearer Token

Bearer Token は、トークンを保持する任意の当事者("bearer")が、 それを保持する他の当事者と同じ方法でそのトークンを使用できるという 性質を持つセキュリティトークンです。Bearer Token の使用は、 bearer が暗号鍵材料の所持(proof-of-possession)を証明することを 要求しません。

Bearer Token は、DPoP [RFC9449] や mTLS [RFC8705] などの proof-of-possession 仕様によって拡張され、 proof-of-possession 特性を提供できます。

アクセストークンの開示から保護するため、クライアントとリソースサーバー間の 通信相互作用は、Section 1.5 で説明される 機密性および完全性保護を利用しなければなりません (MUST)。

bearer token の特定の構造や形式に関する要件はありません。 bearer token が認可情報への参照である場合、そのような参照は、 十分に長い暗号学的にランダムな文字列を使用するなどして、攻撃者が 推測できないものでなければなりません (MUST)。bearer token がトークン自体に 認可情報を含めるためにエンコーディングメカニズムを使用する場合、 アクセストークンは、トークンが変更されることを防ぐのに十分な 完全性保護を使用しなければなりません (MUST)。アクセストークンの エンコードおよび署名メカニズムの一例は、JSON Web Token Profile for Access Tokens [RFC9068] に記述されています。

1.4.3. 送信者制約付きアクセストークン

送信者制約付きアクセストークンは、アクセストークンの使用を 特定の送信者に結び付けます。この送信者は、受信者 (たとえばリソースサーバー)でそのアクセストークンが受け入れられるための 前提条件として、特定の秘密の知識を示す義務があります。

認可サーバーおよびリソースサーバーは、OAuth Demonstration of Proof of Possession (DPoP) [RFC9449] または Mutual TLS for OAuth 2.0 [RFC8705] などの、アクセストークンを送信者制約付きにする メカニズムを使用するべきです (SHOULD)。 盗難または漏えいしたアクセストークンの悪用を防ぐには、 [RFC9700] の Section 4.10.1 を参照してください。

クライアントとリソースサーバーの間でエンドツーエンド TLS を使用することが 推奨されます (RECOMMENDED)。TLS トラフィックを中間者で終端する必要がある場合は、 さらなるセキュリティ上の助言について [RFC9700] の Section 4.13 を参照してください。

1.5. 通信セキュリティ

実装は、Transport-Layer Security [RFC8446] など、通信の認証、完全性、および機密性を提供するメカニズムを 使用しなければなりません (MUST)。 これは、コンテンツまたはヘッダーフィールド内の平文の クレデンシャルおよびトークンの交換を、リプレイを可能にする 盗聴から保護するためです (たとえば、Section 2.4.1Section 7.5.1Section 3.2、および Section 1.4.2 を参照)。

すべての OAuth プロトコル URL(AS、RS、および Client によって公開される URL)は、 ループバックインターフェイスのリダイレクト URI を除き、 https スキームを使用しなければなりません (MUST)。 ループバックインターフェイスのリダイレクト URI は http スキームを使用してもよいです (MAY)。 https を使用する場合、TLS 証明書は [RFC9110] の Section 4.3.4 に従って確認されなければなりません (MUST)。 執筆時点では、TLS バージョン 1.3 [RFC8446] が 最新バージョンです。

実装は、そのセキュリティ要件を満たす追加のトランスポート層 セキュリティメカニズムもサポートしてもよいです (MAY)。

TLS バージョンおよびアルゴリズムの識別は、 この仕様の範囲外です。 トランスポート層セキュリティに関する最新の推奨事項については [BCP195] を参照し、 証明書検証およびその他のセキュリティ上の考慮事項については 関連仕様を参照してください。

1.6. HTTP リダイレクト

この仕様は HTTP リダイレクトを広範に使用します。そこでは、 クライアントまたは認可サーバーがリソース所有者のユーザーエージェントを 別の宛先へ誘導します。この仕様の例では HTTP 302 ステータスコードの 使用を示していますが、HTTP 307 を除き、このリダイレクトを実現するために ユーザーエージェント経由で利用可能なその他の方法は許可され、 実装詳細とみなされます。詳細については Section 7.5.3 を参照してください。

1.7. 相互運用性

OAuth 2.1 は、明確に定義されたセキュリティ特性を持つ、 豊富な認可フレームワークを提供します。

この仕様は、いくつかの必須構成要素を部分的または完全に 未定義のままにしています(たとえば、クライアント登録、 認可サーバー機能、エンドポイント発見)。これらの挙動の一部は、 実装が使用を選択できる任意の拡張で定義されています。たとえば:

  • [RFC8414]: Authorization Server Metadata。特定の OAuth サーバーと相互作用するために必要な 情報を検索するためにクライアントが使用できるエンドポイントを定義します。

  • [RFC7591]: Dynamic Client Registration。認可サーバーにクライアントをプログラムで 登録するためのメカニズムを提供します。

  • [RFC7592]: Dynamic Client Management。動的に登録されたクライアント情報を更新するための メカニズムを提供します。

  • [RFC7662]: Token Introspection。リソースサーバーがアクセストークンに関する情報を 取得するためのメカニズムを定義します。

この公開時点で現在知られている拡張の一覧については、 Appendix D を参照してください。

1.8. OAuth 2.0 との 互換性

OAuth 2.1 は、既知の最新ベストプラクティスからの拡張と制限を 適用したうえで、OAuth 2.0 と互換性があります。具体的には、PKCE など OAuth 2.0 コアで指定されていない機能が OAuth 2.1 では必須です。 さらに、Implicit グラントや Resource Owner Credentials グラント種別など、 OAuth 2.0 で利用可能な一部の機能は OAuth 2.1 では指定されていません。 さらに、OAuth 2.0 で許可されていた一部の挙動は、OAuth 2.1 で必要とされる リダイレクト URI の厳密な文字列一致など、OAuth 2.1 では制限されています。

OAuth 2.0 との差分の詳細については Section 10 を参照してください。

1.9. 表記規則

この文書におけるキーワード "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", および "OPTIONAL" は、ここに示すようにすべて大文字で 出現する場合に限り、BCP 14 [RFC2119] [RFC8174] で説明されるように 解釈されます。

この仕様は [RFC5234] の Augmented Backus-Naur Form (ABNF) 表記を使用します。さらに、 rule URI-reference は "Uniform Resource Identifier (URI): Generic Syntax" [RFC3986] から取り込まれています。

特定のセキュリティ関連用語は [RFC4949] で定義される意味で理解されます。 これらの用語には、次のものが含まれますが、これらに限定されません: "attack", "authentication", "authorization", "certificate", "confidentiality", "credential", "encryption", "identity", "sign", "signature", "trust", "validate", および "verify"。

"content" という用語は、 [RFC9110] の Section 6.4 で説明されるように 解釈されます。

"user agent" という用語は、 [RFC9110] の Section 3.5 で説明されるように 解釈されます。

別段の記載がない限り、すべてのプロトコルパラメーター名および値は 大文字小文字を区別します。

2. クライアント登録

プロトコルを開始する前に、クライアントは認可サーバーで識別子 (Section 2.2)を 確立していなければなりません。クライアント識別子が認可サーバーで 確立される手段は、この仕様の範囲外ですが、通常はクライアント開発者が 認可サーバーの Web サイトでクライアントを手動登録すること (アカウントを作成し、サービスの利用規約に同意した後)、または Dynamic Client Registration [RFC7591] を使用することを含みます。 拡張は、クライアント登録を確立するためのその他のプログラム可能な方法も 定義できます。

クライアント登録は、クライアントと認可サーバーとの直接的な 相互作用を必要としません。認可サーバーによってサポートされる場合、 登録は、信頼を確立し、必要なクライアントプロパティ (たとえば、リダイレクト URI、クライアント種別)を取得するための その他の手段に依存できます。たとえば、登録は自己発行または第三者発行の アサーションを使用して達成される場合や、認可サーバーが信頼されたチャネルを 使用してクライアント発見を実行することによって達成される場合があります。

クライアント登録は次を含まなければなりません (MUST):

Dynamic Client Registration [RFC7591] は、手動のクライアント登録でも使用できる クライアントの共通の一般データモデルを定義しています。

2.1. クライアント種別

OAuth 2.1 は、認可サーバーに対して安全に認証できる能力に基づいて、 2 つのクライアント種別を定義します。

"confidential":

AS とのクレデンシャルを持つクライアントは "confidential clients" と指定されます。

"public":

クレデンシャルを持たないクライアントは "public clients" と呼ばれます。

クレデンシャルを持つクライアントは、そのクレデンシャルの漏えいおよび 悪用を防ぐための予防措置を講じなければなりません (MUST)。

クライアント認証により、認可サーバーは OAuth フロー内で 特定のクライアント(その client_id によって識別される)と 相互作用していることを保証できます。認可サーバーは、 たとえば各認可のたびにユーザーへ同意を求めるか、最初の一度だけ求めるかなどの ポリシー判断を、認可サーバーが正当なクライアントと実際に通信しているという 確信の度合いに基づいて行う場合があります。

認可サーバーがクライアントのアイデンティティ、またはこのクライアントを 提供/運用する当事者のアイデンティティを検証するかどうか、およびその方法は、 この仕様の範囲外です。認可サーバーは、Client Credentials グラント種別のような より機密性の高いリソースや操作へのクライアントアクセスを許可するか、 およびユーザーに同意を求める頻度を決定する際に、クライアントの アイデンティティに対する確信の度合いを考慮するべきです (SHOULD)。

認可サーバーが特定のクライアント種別をサポートする必要はありません。

単一の client_id は、複数のクライアント種別として 扱われるべきではありません (SHOULD NOT)。

この仕様は、次のクライアントプロファイルを念頭に設計されています:

"web application":

Web アプリケーションは、Web サーバー上で実行される クライアントです。リソース所有者は、そのリソース所有者が使用する デバイス上のユーザーエージェントでレンダリングされた HTML ユーザー インターフェイスを介してクライアントにアクセスします。クライアント クレデンシャル、およびクライアントに発行された任意のアクセストークンは、 Web サーバーに保存され、リソース所有者に公開されることも、 リソース所有者からアクセス可能になることもありません。

"browser-based application":

ブラウザベースのアプリケーションは、クライアントコードが Web サーバーからダウンロードされ、リソース所有者が使用するデバイス上の ユーザーエージェント(たとえば Web ブラウザ)内で実行されるクライアントです。 プロトコルデータおよびクレデンシャルは、リソース所有者から容易に アクセス可能(かつ多くの場合可視)です。そのようなアプリケーションが クライアントクレデンシャルを使用したい場合は、backend for frontend パターンを 利用することが推奨されます。そのようなアプリケーションはユーザーエージェント内に 存在するため、認可を要求する際にユーザーエージェントの機能を シームレスに利用できます。

"native application":

ネイティブアプリケーションは、リソース所有者が使用するデバイスに インストールされ実行されるクライアントです。プロトコルデータおよび クレデンシャルはリソース所有者からアクセス可能です。アプリケーションに 含まれる任意のクライアント認証クレデンシャルは抽出され得るものと 想定されます。動的に発行されるアクセストークンおよびリフレッシュトークンは、 許容可能なレベルの保護を受けることができます。一部のプラットフォームでは、 これらのクレデンシャルは同じデバイス上に存在する他のアプリケーションから 保護されます。そのようなアプリケーションがクライアントクレデンシャルを 使用したい場合は、backend for frontend パターンを利用するか、 Dynamic Client Registration [RFC7591] を使用して実 許容可能なレベルの保護を受けることができます。一部のプラットフォームでは、 これらのクレデンシャルは同じデバイス上に存在する他のアプリケーションから 保護されます。そのようなアプリケーションがクライアントクレデンシャルを 使用したい場合は、backend for frontend パターンを利用するか、 Dynamic行時にクレデンシャルを発行することが 推奨されます。

2.2. クライアント識別子

すべてのクライアントは、認可サーバーのコンテキストにおいて、 クライアント識別子によって識別されます。これは、クライアントによって 提供された登録情報を表す一意の文字列です。認可サーバーは通常、 クライアント識別子を自ら発行しますが、認可サーバー以外の当事者によって 作成されたクライアント識別子を持つクライアントに対応する場合もあります。 クライアント識別子は秘密ではありません。これはリソース所有者に公開され、 単独でクライアント認証に使用してはなりません (MUST NOT)。 クライアント識別子は認可サーバーのコンテキストで一意です。

クライアント識別子は不透明な文字列であり、そのサイズはこの仕様では 未定義のままです。クライアントは識別子のサイズについて仮定することを 避けるべきです。認可サーバーは、自らが発行する任意の識別子のサイズを 文書化するべきです (SHOULD)。

認可サーバーが、認可サーバー以外の当事者によって発行された クライアント識別子を持つクライアントをサポートする場合、認可サーバーは Section 7.4 で説明されるように、 クライアントがリソース所有者になりすますことを避けるための予防措置を 講じるべきです (SHOULD)。

2.3. クライアントリダイレクト エンドポイント

クライアントリダイレクトエンドポイント("redirect endpoint" とも呼ばれる)は、 リソース所有者との相互作用を完了した後に、認可サーバーがユーザー エージェントを戻すクライアントの URI です。

認可サーバーは、クライアント登録プロセス中に認可サーバーで 事前に確立されたクライアントのリダイレクトエンドポイントの 1 つへ ユーザーエージェントをリダイレクトします。

redirect URI は、 [RFC3986] の Section 4.3 で定義される 絶対 URI でなければなりません (MUST)。redirect URI は クエリ文字列コンポーネント(Appendix C.1)を含んでもよく (MAY)、 追加のクエリパラメーターを追加する際にはそれを保持しなければなりません (MUST)。 redirect URI はフラグメントコンポーネントを含んではなりません (MUST NOT)。

2.3.1. 登録 要件

認可サーバーは、クライアントに完全な redirect URI (パスコンポーネントを含む)を登録することを要求しなければなりません (MUST)。 認可サーバーは、登録済みのものと完全に一致しない redirect URI を 指定する認可リクエストを拒否しなければなりません (MUST)。ただし、 ループバックリダイレクトは例外であり、ポート URI コンポーネントを除き 完全一致が必要です。詳細については Section 4.1.1 を参照してください。

認可サーバーは、クライアントが複数の redirect URI を登録することを 許可してもよいです (MAY)。

登録は、認可サーバーでクライアント情報を設定する手動手順などの 帯域外で発生する場合もあれば、Pushed Authorization Requests [RFC9126] における初期 POST のように 実行時に発生する場合もあります。

私的使用 URI スキームベースの redirect URI について、 認可サーバーは、クライアントが逆ドメイン名ベースのスキームを使用するという Section 8.4.3 の要件を強制するべきです (SHOULD)。 少なくとも、ピリオド文字(.)を含まない私的使用 URI スキームは 拒否されるべきです (SHOULD)。

衝突耐性の性質に加えて、これは 2 つのアプリが同じ 私的使用 URI スキームを主張する紛争(片方のアプリが悪意を持っている場合)において、 所有権を証明する助けとなります。たとえば、2 つのアプリが com.example.app を主張した場合、 example.com の所有者はアプリストア運営者に対し、 偽造アプリの削除を申し立てることができます。汎用 URI スキームが 使用された場合、そのような申し立てを証明することはより困難です。

クライアントは、クエリパラメーターから取得した任意の URI へ ユーザーのブラウザを転送する URL("open redirector")を公開してはなりません (MUST NOT)。 これは Section 7.12 で説明されています。 Open redirector は、認可コードおよびアクセストークンの流出を可能にし得ます。

クライアントは、リクエストごとに redirect URI を変えるのではなく、 必要に応じてリクエストごとのカスタマイズを実現するために state リクエストパラメーターを使用してもよいです (MAY)。

redirect URI の登録を要求しない場合、攻撃者は Section 7.12 で説明されるように、 認可エンドポイントを open redirector として使用できます。

2.3.2. 複数の Redirect URI

クライアントに複数の redirect URI が登録されている場合、 クライアントは認可リクエストに redirect_uri リクエストパラメーター (Section 4.1.1)を使用して redirect URI を 含めなければなりません (MUST)。 クライアントに単一の redirect URI のみが登録されている場合、 redirect_uri リクエストパラメーターは任意です。

2.3.3. CSRF 攻撃の防止

クライアントは Cross-Site Request Forgery (CSRF) 攻撃を防がなければ なりません (MUST)。この文脈で CSRF とは、認可サーバーからではなく、 悪意ある第三者から発生したリダイレクトエンドポイントへのリクエストを指します (詳細については [RFC6819] の Section 4.4.1.8 を参照)。 認可サーバーが code_challenge パラメーターをサポートしていることを 確認したクライアントは、そのメカニズムによって提供される CSRF 保護に 依存してもよいです (MAY)。OpenID Connect フローでは、 nonce パラメーターを検証することで CSRF 保護が提供されます。 それ以外の場合、ユーザーエージェントに安全に結び付けられた state パラメーター内の一回限り使用の CSRF トークンを、 CSRF 保護のために使用しなければなりません (MUST) (Section 7.9 を参照)。

2.3.4. Mix-Up 攻撃の防止

OAuth クライアントが 1 つの認可サーバーとのみ相互作用できる場合、 mix-up 防御は不要です。しかし、OAuth クライアントが 2 つ以上の認可サーバーと 相互作用するシナリオでは、クライアントは mix-up 攻撃を防がなければなりません (MUST)。 mix-up 攻撃を防ぐために、クライアントは、それぞれのリクエストを送信した 発行者からのリダイレクトレスポンスのみを、かつこの認可リクエストが 開始された同じユーザーエージェントからのものとしてのみ処理しなければなりません (MUST)。

mix-up 攻撃に対する 2 つの異なる防御の詳細な説明については Section 7.14 を参照してください。

2.3.5. 無効なエンドポイント

認可リクエストが、欠落、無効、または不一致の redirect URI のために 検証に失敗した場合、認可サーバーはリソース所有者にエラーを 通知するべきであり (SHOULD)、ユーザーエージェントを無効な redirect URI へ 自動的にリダイレクトしてはなりません (MUST NOT)。

2.3.6. エンドポイントの内容

クライアントのエンドポイントへのリダイレクトリクエストは、通常、 ユーザーエージェントによって処理される HTML 文書レスポンスになります。 HTML レスポンスがリダイレクトリクエストの結果として直接提供される場合、 HTML 文書に含まれる任意のスクリプトは、redirect URI とそれに含まれる 生成物(たとえば認可コード)への完全なアクセス権で実行されます。 さらに、認可コードを含むリクエスト URL は、ページに読み込まれる 埋め込み画像、スタイルシート、およびその他の要素へ HTTP Referer ヘッダーで 送信される場合があります。

クライアントは、redirect URI エンドポイントレスポンスに 第三者スクリプト(たとえば、第三者アナリティクス、ソーシャルプラグイン、 広告ネットワーク)を含めるべきではありません (SHOULD NOT)。代わりに、 URI から生成物を抽出し、生成物を(URI 内でもそれ以外でも)露出しない 別のエンドポイントへユーザーエージェントを再度リダイレクトするべきです (SHOULD)。 第三者スクリプトが含まれる場合、クライアントは、URI からクレデンシャルを 抽出して削除するために使用される自身のスクリプトが最初に実行されることを 保証しなければなりません (MUST)。

2.4. クライアント認証

認可サーバーは、基礎となるクレデンシャルの発行/登録および配布の プロセスがその機密性を保証する場合にのみ、クライアント認証に 依存しなければなりません (MUST)。

confidential client について、認可サーバーは、そのセキュリティ要件を 満たす任意の形式のクライアント認証(たとえば、クライアントシークレット、 公開鍵/秘密鍵ペア)を受け入れてもよいです (MAY)。

クライアント認証には、mTLS [RFC8705] や、[RFC7521][RFC7523]、 およびそれらの更新 [I-D.ietf-oauth-rfc7523bis] に従った 署名付き JWT("Private Key JWT")など、非対称(公開鍵ベース)の方法を 使用することが推奨されます (RECOMMENDED) ([OpenID.Connect] では クライアント認証方式 private_key_jwt として定義)。 そのようなクライアント認証方式が使用される場合、認可サーバーは 機密性の高い対称鍵を保存する必要がないため、これらの方式は 多くの攻撃に対してより堅牢になり、クライアントが自身の鍵と 鍵ローテーションを管理できるようになります。

JWT ベースのクライアント認証を使用する場合、クライアントおよび 認可サーバーは、[I-D.ietf-oauth-rfc7523bis] における aud 値に関する 更新された指針に従わなければなりません (MUST)。

クライアント認証が不可能な場合、認可サーバーは、たとえば クライアントの redirect URI の登録を要求する、またはリソース所有者に アイデンティティ確認を依頼するなど、クライアントのアイデンティティを 検証するための他の手段を用いるべきです (SHOULD)。有効な redirect URI は、 リソース所有者の認可を求める際にクライアントのアイデンティティを 検証するには十分ではありませんが、リソース所有者の認可を取得した後に 偽造クライアントへクレデンシャルを渡すことを防ぐために使用できます。

クライアントは、リクエストに対してどの認証メカニズムが 権威を持つかの衝突を防ぐため、各リクエストで複数の認証方式を 使用してはなりません (MUST NOT)。

認可サーバーは、未認証クライアントと相互作用することの セキュリティ上の影響を考慮し、そのようなクライアントに発行される トークンの潜在的な露出を制限するための措置を講じなければなりません (MUST) (たとえば、リフレッシュトークンの有効期間を制限する)。

認可サーバーが特定のクライアントアイデンティティに関連付ける権限は、 クライアント識別およびクライアントクレデンシャルのライフサイクル管理の 全体的なプロセスの評価に依存しなければなりません (MUST)。 追加の詳細については Section 7.2 を 参照してください。

2.4.1. クライアントシークレット

クライアントシークレットを所持する confidential client をサポートするため、 認可サーバーは、クライアントがリクエストボディコンテンツ内で 次のパラメーターを使用してクライアントクレデンシャルを含めることを サポートしなければなりません (MUST):

"client_id":

REQUIRED。Section 2.2 で説明される登録プロセス中に クライアントへ発行されたクライアント識別子。

"client_secret":

REQUIRED。クライアントシークレット。

パラメーターはリクエストコンテンツ内でのみ送信でき、 リクエスト URI に含めてはなりません (MUST NOT)。

これは [RFC7591] の Section 2 で定義される client_secret_post としても知られています。

たとえば、コンテンツパラメーターを使用してアクセストークンを更新する リクエスト(Section 4.3) (表示目的のためだけに追加の改行を含む):

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

認可サーバーは、クライアントシークレットを発行されたクライアントを 認証するために、HTTP Basic 認証スキームをサポートしてもよいです (MAY)。

[RFC9110] の Section 11 で定義される HTTP Basic 認証スキームを使用して 認可サーバーで認証する場合、クライアント識別子は Appendix B に従い application/x-www-form-urlencoded エンコーディングアルゴリズムを使用して エンコードされ、そのエンコード値がユーザー名として使用されます。 クライアントシークレットは同じアルゴリズムを使用してエンコードされ、 パスワードとして使用されます。

これは [RFC7591] の Section 2 で定義される client_secret_basic としても知られています。

例(表示目的のためだけに追加の改行を含む):

Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

注記: クライアント識別子とシークレットを最初にフォームエンコードし、 その後エンコードされた値を HTTP Basic 認証のユーザー名および パスワードとして使用するこの方法は、過去に多くの相互運用性の問題を 引き起こしてきました。一部の実装はエンコード手順を見落としたり、 特定の文字だけをエンコードすることを決めたり、クレデンシャル検証時に エンコード要件を無視したりしたため、クライアントは個々の認可サーバーに クレデンシャルを提示する方法を特別扱いしなければならなくなりました。 リクエストボディコンテンツにクレデンシャルを含めることは、 エンコーディングの問題を避け、より相互運用性の高い実装につながります。

クライアントシークレット認証方式はパスワードを伴うため、 認可サーバーはそれを利用する任意のエンドポイントを ブルートフォース攻撃から保護しなければなりません (MUST)。

2.4.2. その他の 認証方式

認可サーバーは、そのセキュリティ要件に一致する任意の適切な 認証スキームをサポートしてもよいです (MAY)。その他の認証方式を 使用する場合、認可サーバーはクライアント識別子(登録レコード)と 認証スキームとの間の対応付けを定義しなければなりません (MUST)。

mTLS [RFC8705] や Private Key JWT([RFC7523][I-D.ietf-oauth-rfc7523bis])などの 追加の認証方式は、 "OAuth Token Endpoint Authentication Methods" レジストリで定義されており、 トークンエンドポイント保護という特定の用途を超えた汎用的な クライアント認証方式として有用な場合があります。

2.5. 未登録クライアント

この仕様は、クライアントが認可サーバーに登録されていることを 要求しません。 ただし、未登録クライアントの使用はこの仕様の範囲外であり、 追加のセキュリティ分析と、相互運用性への影響のレビューを必要とします。

3. プロトコルエンドポイント

認可プロセスは、2 つの認可サーバーエンドポイント (HTTP リソース)を利用します:

また、1 つのクライアントエンドポイントもあります:

すべての認可グラント種別が両方のエンドポイントを利用するわけではありません。 拡張グラント種別は、必要に応じて追加のエンドポイントを定義してもよいです (MAY)。

3.1. 認可エンドポイント

認可エンドポイントは、リソース所有者と相互作用し、 認可グラントを取得するために使用されます。認可サーバーは、まず リソース所有者を認証しなければなりません (MUST)。認可サーバーが リソース所有者を認証する方法(たとえば、ユーザー名とパスワードによるログイン、 passkey、フェデレーテッドログイン、または確立済みセッションの使用)は、 この仕様の範囲外です。

クライアントが認可エンドポイントの URL を取得する手段は、 この仕様の範囲外ですが、その URL は通常、サービス文書で提供されるか、 認可サーバーのメタデータ文書 [RFC8414] で提供されます。

認可エンドポイント URL はフラグメントコンポーネントを 含んではならず (MUST NOT)、クエリ文字列コンポーネント Appendix C.1 を含んでもよく (MAY)、 追加のクエリパラメーターを追加する際にはそれを保持しなければなりません (MUST)。

認可サーバーは、認可エンドポイントに対して HTTP GET メソッド([RFC9110] の Section 9.3.1)の使用をサポートしなければならず (MUST)、 POST メソッド([RFC9110] の Section 9.3.3)もサポートしてもよいです (MAY)。

認可サーバーは、認可エンドポイントへ送信された認識されない リクエストパラメーターを無視しなければなりません (MUST)。

この仕様で定義されるリクエストパラメーターおよびレスポンスパラメーターは、 複数回含まれてはなりません (MUST NOT)。 この要件は、拡張が特定のパラメーターについて明示的に別段の定義を しない限り、拡張で定義されるパラメーターにも適用されます。 値なしで送信されたパラメーターは、リクエストから省略されたものとして 扱われなければなりません (MUST)。

ユーザークレデンシャルを含む可能性のあるリクエストをリダイレクトする 認可サーバーは、これらのユーザークレデンシャルを誤って転送することを 避けなければなりません (MUST) (詳細については Section 7.5.3 を参照)。

Cross-Origin Resource Sharing [WHATWG.CORS] は、Authorization Endpoint で サポートされてはなりません (MUST NOT)。クライアントはこのエンドポイントへ 直接アクセスせず、代わりにユーザーエージェントをそこへリダイレクトするためです。

3.2. トークンエンドポイント

トークンエンドポイントは、Section 4 および Section 4.3 で説明されるような グラントを使用して、クライアントがアクセストークンを取得するために使用されます。

クライアントがトークンエンドポイントの URL を取得する手段は この仕様の範囲外ですが、その URL は通常、サービス文書で提供され、 クライアントの開発中に設定されるか、認可サーバーのメタデータ文書 [RFC8414] で提供され、 実行時にプログラムで取得されます。

トークンエンドポイント URL はフラグメントコンポーネントを 含んではならず (MUST NOT)、クエリ文字列コンポーネント Appendix C.1 を含んでもよいです (MAY)。

クライアントは、トークンエンドポイントへのリクエストを行う際に HTTP POST メソッドを使用しなければなりません (MUST)。

認可サーバーは、トークンエンドポイントへ送信された認識されない リクエストパラメーターを無視しなければなりません (MUST)。

値なしで送信されたパラメーターは、リクエストから省略されたものとして 扱われなければなりません (MUST)。この仕様で定義されるリクエストパラメーター およびレスポンスパラメーターは、複数回含まれてはなりません (MUST NOT)。 この要件は、拡張が特定のパラメーターについて明示的に別段の定義を しない限り、拡張で定義されるパラメーターにも適用されます。

ブラウザベースのアプリケーション (たとえば、支援用バックエンドサーバーへアクセスできないクライアント側 JavaScript のみで 実行されるアプリケーション)をサポートしたい認可サーバーは、トークンエンドポイントが 必要な CORS [WHATWG.CORS] ヘッダーをサポートし、 レスポンスがアプリケーションから見えるようにする必要があります。 認可サーバーが、メタデータ URL、動的クライアント登録、取消、 introspection、発見、またはユーザー情報エンドポイントなどの追加エンドポイントを アプリケーションに提供する場合、これらのエンドポイントもブラウザベースの アプリケーションからアクセスされる可能性があり、アクセスを許可するために CORS ヘッダーを定義する必要があります。 詳細については [I-D.ietf-oauth-browser-based-apps] を参照してください。

3.2.1. クライアント 認証

confidential client は、トークンエンドポイントへリクエストを行う際に、 Section 2.4 で説明されるように 認可サーバーで認証しなければなりません (MUST)。

クライアント認証は次の目的で使用されます:

  • リフレッシュトークンおよび認可コードを、 それらが発行されたクライアントに結び付けることを強制するため。 クライアント認証は、認可コードが安全でないチャネル上で リダイレクトエンドポイントへ送信される場合に、追加のセキュリティレイヤーを 加えます。

  • 侵害されたクライアントから回復するために、 クライアントを無効化するか、そのクレデンシャルを変更し、 攻撃者が盗まれたリフレッシュトークンを悪用することを防ぎます。 クライアントクレデンシャルの単一セットを変更することは、 リフレッシュトークンの全体セットを取り消すよりも大幅に高速です。

  • 定期的なクレデンシャルローテーションを必要とする 認証管理のベストプラクティスを実装するため。リフレッシュトークンの 全体セットのローテーションは困難な場合がありますが、クライアント クレデンシャルの単一セットのローテーションは大幅に容易です。

3.2.2. トークンエンドポイント リクエスト

クライアントは、HTTP リクエストコンテンツ内で UTF-8 の 文字エンコーディングを用い、Appendix C.2 に従った フォームエンコードシリアル化形式を使用して、次のパラメーターを送信することにより トークンエンドポイントへリクエストを行います:

"grant_type":

REQUIRED。特定のトークンリクエストでクライアントが使用する グラント種別の識別子。 この仕様は値 authorization_coderefresh_token、および client_credentials を定義します。 グラント種別は、トークンリクエストでさらに必要またはサポートされる パラメーターを決定します。それらのグラント種別の詳細は以下で定義されます。

"client_id":

OPTIONAL。パラメーターに依存する形式の クライアント認証が使用される場合、または grant_type が public client の識別を必要とする場合、クライアント識別子が必要です。

confidential client は、Section 3.2.1 で説明されるように、 認可サーバーで認証しなければなりません (MUST)。

たとえば、クライアントは次の HTTPS リクエストを行います (表示目的のためだけに追加の改行を含む):

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
&code_verifier=3641a2d12d66101249cdf7a79c000c1f8c05d2aafcf14bf146497bed

認可サーバーは次を行わなければなりません (MUST):

  • confidential client(またはその他の認証要件を持つクライアント)に対して クライアント認証を要求すること、

  • クライアント認証が含まれる場合、クライアントを認証すること

さらにグラント種別固有の処理規則が適用され、それぞれの グラント種別とともに指定されます。

3.2.3. トークンエンドポイント レスポンス

アクセストークンリクエストが有効で認可されている場合、 認可サーバーはアクセストークンと任意のリフレッシュトークンを発行します。

クライアント認証が失敗したか無効である場合、認可サーバーは Section 3.2.4 で説明されるエラーレスポンスを返します。

認可サーバーは、Appendix C.3 に従って HTTP レスポンスを作成し、 [RFC8259] で定義される application/json メディア型を使用し、次のパラメーターと HTTP 200 (OK) ステータスコードを用いて、アクセストークンと任意の リフレッシュトークンを発行します:

"access_token":

REQUIRED。認可サーバーによって発行されたアクセストークン。

"token_type":

REQUIRED。Section 1.4 で説明される、 発行されたアクセストークンの種別。値は大文字小文字を区別しません。

"expires_in":

RECOMMENDED。アクセストークンの有効期間を秒単位で表す JSON 数値。たとえば、値 3600 は、レスポンスが生成された時点から 1 時間後にアクセストークンが失効することを示します。 省略された場合、認可サーバーは他の手段で有効期間を提供するか、 デフォルト値を文書化するべきです (SHOULD)。認可サーバーは アクセストークンを早期に失効させる可能性があり、クライアントは 提供された有効期間中アクセストークンが有効であることを期待しては ならないことに注意してください (MUST NOT)。

"scope":

クライアントによって要求されたスコープと同一である場合は RECOMMENDED。 それ以外の場合は REQUIRED。Section 1.4.1 で説明されるアクセストークンのスコープ。

"refresh_token":

OPTIONAL。対応するトークンリクエストで渡されたグラントに基づいて 新しいアクセストークンを取得するために使用できるリフレッシュトークン。

認可サーバーは、リスク評価および自らのポリシーに基づいて、 特定のクライアントにリフレッシュトークンを発行するかどうかを 決定するべきです (SHOULD)。認可サーバーがリフレッシュトークンを 発行しないと決定した場合、クライアントは、たとえば新しい認可コード リクエストを開始するなど、OAuth フローを最初からやり直すことで 新しいアクセストークンを取得してもよいです (MAY)。そのような場合、 認可サーバーはユーザー体験を最適化するために Cookie や永続グラントを 利用する場合があります。

リフレッシュトークンが発行される場合、それらのリフレッシュトークンは リソース所有者によって同意されたスコープおよびリソースサーバーに 結び付けられなければなりません (MUST)。 これは、正当なクライアントによる権限昇格を防ぎ、 リフレッシュトークン漏えいの影響を低減するためです。

パラメーターは、Appendix C.3 で説明されるように JavaScript Object Notation (JSON) 構造へシリアル化されます。

認可サーバーは、トークン、クレデンシャル、またはその他の機密情報を 含む任意のレスポンスにおいて、値 no-store を持つ HTTP Cache-Control レスポンスヘッダーフィールド([RFC9111] の Section 5.2 を参照)を含めなければなりません (MUST)。

例:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "access_token": "2YotnFZFEjr1zCsicMWpAA",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter": "example_value"
}

クライアントは、レスポンス内の認識されない値名を無視しなければ なりません (MUST)。認可サーバーから受け取るトークンおよびその他の 値のサイズは未定義のままです。クライアントは値のサイズについて 仮定することを避けるべきです。認可サーバーは、自らが発行する 任意の値のサイズを文書化するべきです (SHOULD)。

3.2.4. トークンエンドポイント エラーレスポンス

認可サーバーは、HTTP 400 (Bad Request) ステータスコード (別段の指定がある場合を除く)で応答し、レスポンスに次の パラメーターを含めます:

"error":

REQUIRED。次の中からの単一の ASCII [USASCII] エラーコード:

"invalid_request":

リクエストに必須パラメーターが欠落している、 (グラント種別以外の)サポートされていないパラメーター値を 含んでいる、パラメーターを繰り返している、複数のクレデンシャルを 含んでいる、クライアントを認証するために複数のメカニズムを 利用している、認可リクエストで code_challenge が 送信されていないにもかかわらず code_verifier を含んでいる、 またはその他の形式不正である。

"invalid_client":

クライアント認証に失敗した (たとえば、未知のクライアント、クライアント認証が含まれていない、 またはサポートされていない認証方式)。認可サーバーは、 サポートされる HTTP 認証スキームを示すために HTTP 401 (Unauthorized) ステータスコードを返してもよいです (MAY)。 クライアントが Authorization リクエストヘッダーフィールドを介して 認証を試みた場合、認可サーバーは HTTP 401 (Unauthorized) ステータスコードで応答し、クライアントが使用した認証スキームに 一致する WWW-Authenticate レスポンスヘッダーフィールドを 含めなければなりません (MUST)。

"invalid_grant":

提供された認可グラント (たとえば、認可コード、リソース所有者クレデンシャル)または リフレッシュトークンが無効、失効済み、取り消し済みである、 認可リクエストで使用された redirect URI と一致しない、 または別のクライアントに発行されたものである。

"unauthorized_client":

認証されたクライアントは、この 認可グラント種別を使用することを認可されていない。

"unsupported_grant_type":

認可グラント種別は認可サーバーによって サポートされていない。

"invalid_scope":

要求されたスコープが無効、不明、 形式不正、またはリソース所有者によって付与されたスコープを 超えている。

error パラメーターの値は、 集合 %x20-21 / %x23-5B / %x5D-7E の外の文字を 含んではなりません (MUST NOT)。

"error_description":

OPTIONAL。発生したエラーをクライアント開発者が 理解するのを支援するために使用される、追加情報を提供する 人間可読の ASCII [USASCII] テキスト。 error_description パラメーターの値は、集合 %x20-21 / %x23-5B / %x5D-7E の外の文字を含んでは なりません (MUST NOT)。

"error_uri":

OPTIONAL。エラーに関する情報を持つ 人間可読の Web ページを識別する URI。クライアント開発者に エラーに関する追加情報を提供するために使用されます。 error_uri パラメーターの値は URI-reference 構文に適合しなければならず、 したがって集合 %x21 / %x23-5B / %x5D-7E の外の文字を 含んではなりません (MUST NOT)。

パラメーターは、Appendix C.3 で定義される application/json メディア型を使用して、HTTP レスポンスのコンテンツ内に 含まれます。

例:

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store

{
 "error": "invalid_request"
}

4. グラント種別

アクセストークンを要求するために、クライアントは リソース所有者から認可を取得します。この仕様は、次の認可グラント種別を定義します:

また、追加のグラント種別を定義するための拡張メカニズムも提供します。

4.1. 認可コード グラント

認可コードグラント種別は、アクセストークンと リフレッシュトークンの両方を取得するために使用されます。

このグラント種別は、リソースアクセスへの同意を得るために 認可サーバーがリソース所有者と相互作用できるよう、 追加の認可エンドポイントを使用します。

これはリダイレクトベースのフローであるため、クライアントは リソース所有者のユーザーエージェント(通常は Web ブラウザ)で フローを開始でき、かつ認可サーバーからリダイレクトで戻されることが できなければなりません。

 +----------+
 | Resource |
 |   Owner  |
 +----------+
       ^
       |
       |
 +-----|----+          Client Identifier      +---------------+
 | .---+---------(1)-- & Redirect URI ------->|               |
 | |   |    |                                 |               |
 | |   '---------(2)-- User authenticates --->|               |
 | | User-  |                                 | Authorization |
 | | Agent  |                                 |     Server    |
 | |        |                                 |               |
 | |    .--------(3)-- Authorization Code ---<|               |
 +-|----|---+                                 +---------------+
   |    |                                         ^      v
   |    |                                         |      |
   ^    v                                         |      |
 +---------+                                      |      |
 |         |>---(4)-- Authorization Code ---------'      |
 |  Client |          & Redirect URI                     |
 |         |                                             |
 |         |<---(5)----- Access Token -------------------'
 +---------+       (w/ Optional Refresh Token)
図 3: 認可コードフロー

Figure 3 に示されるフローは、次の手順を含みます:

(1) クライアントは、リソース所有者の ユーザーエージェントを認可エンドポイントへ誘導することでフローを開始します。 クライアントは、そのクライアント識別子、コードチャレンジ (生成されたコードベリファイアから導出されるもの)、任意の要求スコープ、 任意のローカル状態、およびアクセスが許可(または拒否)された後に 認可サーバーがユーザーエージェントを戻す redirect URI を含めます。

(2) 認可サーバーは(ユーザーエージェントを介して) リソース所有者を認証し、リソース所有者がクライアントのアクセス要求を 許可するか拒否するかを確立します。

(3) リソース所有者がアクセスを許可したと仮定すると、 認可サーバーは、以前に提供された redirect URI(リクエスト内または クライアント登録時)を使用して、ユーザーエージェントをクライアントへ リダイレクトして戻します。redirect URI には、認可コードと、 クライアントが以前に提供した任意のローカル状態が含まれます。

(4) クライアントは、前の手順で受け取った認可コードと、 そのコードベリファイアを含めることにより、認可サーバーの トークンエンドポイントからアクセストークンを要求します。 リクエストを行う際、クライアントは可能であれば認可サーバーで認証します。 クライアントは、検証のために認可コードを取得する際に使用した redirect URI を含めます。

(5) 認可サーバーは可能な場合にクライアントを認証し、 認可コードを検証し、コードベリファイアを検証し、受け取った redirect URI が 手順 (3) でユーザーエージェントをクライアントへリダイレクトするために 使用された URI と一致することを確認します。有効であれば、 認可サーバーはアクセストークンと、任意でリフレッシュトークンを返します。

4.1.1. 認可 リクエスト

認可リクエストを開始するために、クライアントは 認可サーバーの認可エンドポイント URI にパラメーターを追加して 認可リクエスト URI を構築します。クライアントは最終的に、 リクエストを開始するためにユーザーエージェントをこの URI へ リダイレクトします。

クライアントは、認可コードインジェクションおよび CSRF 攻撃から保護するために、認可リクエストごとに "code verifier" と呼ばれる一意の秘密値を使用します。 クライアントはまずコードベリファイアを生成し、次に認可リクエストに 含める "code challenge" を導出します。クライアントは、トークンエンドポイントで 認可コードを交換するときにコードベリファイアを使用し、 認可コードを使用しているクライアントが、それを要求した同じクライアントであることを 証明します。

クライアントは、Appendix C.1 で説明されるように、 認可エンドポイント URI のクエリコンポーネントに次のパラメーターを 追加してリクエスト URI を構築します:

"response_type":

REQUIRED。認可エンドポイントは、異なる リクエストパラメーターおよびレスポンスパラメーターの集合を サポートします。クライアントは特定の response_type 値を使用することで、フローの種別を決定します。この仕様は 値 code を定義しており、クライアントが認可コードフローを 使用したいことを示すために使用されなければなりません。

拡張レスポンス種別は、空白区切り(%x20)の 値リストを含んでもよく (MAY)、値の順序は重要ではありません (たとえば、レスポンス種別 a bb a と同じです)。 そのような複合レスポンス種別の意味は、それぞれの仕様で定義されます。

一部の拡張レスポンス種別は [OpenID.Connect] によって定義されています。

認可リクエストに response_type パラメーターが欠落している場合、 またはレスポンス種別が理解されない場合、認可サーバーは Section 4.1.2.1 で説明されるエラーレスポンスを返さなければなりません (MUST)。

"client_id":

REQUIRED。Section 2.2 で説明される クライアント識別子。

"code_challenge":

Section 7.5.1 の 特定の要件が満たされない限り REQUIRED。コードベリファイアから 導出されたコードチャレンジ。

"code_challenge_method":

OPTIONAL。リクエストに存在しない場合は plain がデフォルトになります。コードベリファイア変換方式は S256 または plain です。

"redirect_uri":

このクライアントに登録されている redirect URI が 1 つだけの場合は OPTIONAL。 このクライアントに複数の redirect URI が登録されている場合は REQUIRED。 Section 2.3.2 を参照してください。

"scope":

OPTIONAL。 Section 1.4.1 で 説明されるアクセスリクエストのスコープ。

"state":

OPTIONAL。リクエストとコールバックの間で 状態を維持するためにクライアントが使用する不透明な値。 認可サーバーは、ユーザーエージェントをクライアントへ リダイレクトして戻す際にこの値を含めます。

code_verifier は、各認可リクエストごとに 生成される、一意で高エントロピーの暗号学的にランダムな文字列であり、 非予約文字 [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" を使用し、 最小長 43 文字、最大長 128 文字です。

クライアントは code_verifier を一時的に保存し、 認可リクエストで使用する code_challenge を計算します。

code_verifier の ABNF は次のとおりです。

code-verifier = 43*128unreserved
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA = %x41-5A / %x61-7A
DIGIT = %x30-39

クライアントは、認可リクエストで code_verifier を公開しないコードチャレンジ方式を使用するべきです (SHOULD)。 そうでない場合、認可リクエストを読み取ることができる攻撃者 ([RFC9700] の Attacker A4 参照)は、このメカニズムによって提供される セキュリティを破ることができます。現在、S256 がそのような唯一の方式です。

NOTE: コードベリファイアは、その値を推測することが非現実的になるだけの 十分なエントロピーを持つべきです (SHOULD)。32 オクテットの シーケンスを作成するために、適切な乱数生成器の出力を使用することが 推奨されます (RECOMMENDED)。その後、オクテットシーケンスは base64url エンコードされ、 コードベリファイアとして使用する 43 オクテットの URL 安全文字列を生成します。

次に、クライアントはコードベリファイアに対して次のいずれかの 変換を使用することにより、コードベリファイアから導出された code_challenge を作成します:

S256
  code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

plain
  code_challenge = code_verifier

クライアントが S256 を使用できる場合、 S256 を使用しなければなりません (MUST)。 S256 はサーバーにおいて Mandatory To Implement (MTI) であるためです。 クライアントが plain を使用することが許可されるのは、 たとえばハッシュ関数が利用できない制約環境など、何らかの技術的理由により S256 をサポートできず、かつ帯域外設定または Authorization Server Metadata [RFC8414] を通じて、サーバーが plain をサポートしていることを知っている場合のみです。

code_challenge の ABNF は次のとおりです。

code-challenge = 43*128unreserved
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA = %x41-5A / %x61-7A
DIGIT = %x30-39

プロパティ code_challenge および code_verifier は、"Proof-Key for Code Exchange"、すなわち PKCE [RFC7636] として知られる OAuth 2.0 拡張から採用されたものであり、 この技術はそこで最初に開発されました。

認可サーバーは code_challenge および code_verifier パラメーターをサポートしなければなりません (MUST)。

クライアントは code_challenge および code_verifier を使用しなければならず (MUST)、 認可サーバーは Section 7.5.1 で説明される条件下を除き、その使用を強制しなければなりません (MUST)。 その場合であっても、上記のように code_challenge および code_verifier を使用し強制することは、なお推奨されます (RECOMMENDED)。

state および scope パラメーターは、 機密性の高いクライアント情報またはリソース所有者情報を平文で 含めるべきではありません (SHOULD NOT)。それらは安全でないチャネルで 送信されたり、安全でない方法で保存されたりする可能性があるためです。

クライアントは、HTTP リダイレクト、またはユーザーエージェントを介して 利用可能なその他の手段を使用して、構築された URI へ リソース所有者を誘導します。

たとえば、クライアントはユーザーエージェントに次の HTTPS リクエストを行わせます(表示目的のためだけに追加の改行を含む):

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
    &code_challenge=6fdkQaPm51l13DSukcAH3Mdx7_ntecHYd1vi3n0hMZY
    &code_challenge_method=S256 HTTP/1.1
Host: server.example.com

認可サーバーは、すべての必須パラメーターが存在し、 有効であることを確認するためにリクエストを検証します。

特に、認可サーバーは、リクエストに redirect_uri が存在する場合、それを検証しなければならず (MUST)、 クライアント登録(Section 2)中に 以前に確立された登録済み redirect URI の 1 つと一致することを 確認しなければなりません。2 つの URI を比較する際、認可サーバーは それら 2 つの URI が等しいことを保証しなければなりません (MUST)。 詳細については、Simple String Comparison である [RFC3986] の Section 6.2.1 を参照してください。 唯一の例外は、localhost URI を使用するネイティブアプリです。この場合、 認可サーバーは [RFC8252] の Section 7.3 で説明されるように、可変ポート番号を許可しなければなりません (MUST)。

リクエストが有効な場合、 認可サーバーはリソース所有者を認証し、(リソース所有者に尋ねるか、 または他の手段で承認を確立することにより)認可判断を取得します。

判断が確立されると、認可サーバーは HTTP リダイレクトレスポンス、 またはユーザーエージェントを介して利用可能なその他の手段を使用して、 ユーザーエージェントを提供されたクライアント redirect URI へ誘導します。

4.1.2. 認可 レスポンス

リソース所有者がアクセスリクエストを許可した場合、 認可サーバーは認可コードを発行し、拡張で別段の指定がない限り、 Appendix C.1 で 説明されるクエリ文字列シリアル化を使用して、次のパラメーターを redirect URI のクエリコンポーネントに追加することにより、 それをクライアントへ配信します:

"code":

REQUIRED。認可コードは認可サーバーによって生成され、 クライアントにとって不透明です。認可コードは、漏えいのリスクを 軽減するために、発行後すぐに失効しなければなりません (MUST)。 認可コードの最大有効期間は 10 分が推奨されます (RECOMMENDED)。 認可コードは、クライアント識別子、コードチャレンジ、および redirect URI に結び付けられます。

"state":

クライアントの認可リクエストに state パラメーターが存在した場合は REQUIRED。 クライアントから受け取った正確な値。

"iss":

OPTIONAL。クライアントが複数の認可サーバーと 相互作用する場合に、mix-up 攻撃を防ぐために使用できる 認可サーバーの識別子。このパラメーターが必要になる場合と、 クライアントがそれを使用して mix-up 攻撃を防ぐ方法に関する 追加の詳細については、Section 7.14 および [RFC9207] を参照してください。

たとえば、認可サーバーは次の HTTP レスポンスを送信することで ユーザーエージェントをリダイレクトします:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
          &state=xyz&iss=https%3A%2F%2Fauthorization-server.example.com

クライアントは認識されないレスポンスパラメーターを 無視しなければなりません (MUST)。認可コード文字列のサイズは この仕様では未定義のままです。クライアントはコード値のサイズに関して 仮定することを避けるべきです。認可サーバーは、自らが発行する 任意の値のサイズを文書化するべきです (SHOULD)。

認可サーバーは、後でコードチャレンジを検証できるよう、 code_challenge および code_challenge_method 値を、発行された認可コードに 関連付けなければなりません (MUST)。

サーバーが code_challenge を 発行されたコードに関連付けるために使用する正確な方法は、 この仕様の範囲外です。コードチャレンジはサーバー上に保存され、 そこでコードと関連付けられる場合があります。code_challenge および code_challenge_method 値は、コード自体に暗号化された形式で 保存されてもよいですが、サーバーは AS 以外の主体が抽出できる形式で、 レスポンスパラメーターに code_challenge 値を含めては なりません (MUST NOT)。

クライアントは、攻撃者による認可コードの 認可レスポンスへの注入(リプレイ)を防がなければなりません (MUST)。 code_challenge および code_verifier を使用することで、 認可サーバーが一致しない code_verifier を持つ トークンリクエストを拒否するため、認可コードの注入を防ぎます。 詳細については Section 7.5.1 を参照してください。

4.1.2.1. 認可エラーレスポンス

redirect URI が欠落、無効、または不一致であるために リクエストが失敗した場合、またはクライアント識別子が欠落または無効である場合、 認可サーバーはユーザーエージェントを無効な redirect URI へ リダイレクトしてはならず (MUST NOT)、たとえばユーザーのブラウザに メッセージを表示することにより、リソース所有者にエラーを 通知するべきです (SHOULD)。

認可サーバーは、public client からの code_challenge を持たないリクエストを拒否しなければならず (MUST)、 クライアントが他の方法で認可コードインジェクションを軽減するという 合理的な保証がない限り、他のクライアントからのそのようなリクエストも 拒否しなければなりません (MUST)。詳細については Section 7.5.1 を参照してください。

サーバーが要求された code_challenge_method 変換をサポートしていない場合、 認可エンドポイントは、error 値を invalid_request に設定した認可エラーレスポンスを 返さなければなりません (MUST)。error_description または error_uri のレスポンスは、たとえば変換アルゴリズムが サポートされていないなど、エラーの性質を説明するべきです (SHOULD)。

リソース所有者がアクセスリクエストを拒否した場合、 または redirect URI の欠落または無効以外の理由でリクエストが失敗した場合、 認可サーバーは、ユーザーエージェントを redirect URI へリダイレクトし、 Appendix C.1 で説明されるように redirect URI のクエリコンポーネントに 次のパラメーターを追加することによってクライアントへ通知します:

"error":

REQUIRED。次の中からの単一の ASCII [USASCII] エラーコード:

"invalid_request":

リクエストに必須パラメーターが 欠落している、無効なパラメーター値を含んでいる、 パラメーターを複数回含んでいる、またはその他の形式不正である。

"unauthorized_client":

クライアントはこの方式を使用して 認可コードを要求することを認可されていない。

"access_denied":

リソース所有者または認可サーバーが リクエストを拒否した。

"unsupported_response_type":

認可サーバーはこの方式を使用して 認可コードを取得することをサポートしていない。

"invalid_scope":

要求されたスコープが無効、不明、 または形式不正である。

"server_error":

認可サーバーが、リクエストを 遂行できない予期しない状態に遭遇した。 (HTTP 500 Internal Server Error ステータスコードを HTTP リダイレクトを介してクライアントへ返すことができないため、 このエラーコードが必要です。)

"temporarily_unavailable":

認可サーバーは、サーバーの一時的な 過負荷またはメンテナンスのため、現在リクエストを処理できない。 (HTTP 503 Service Unavailable ステータスコードを HTTP リダイレクトを介してクライアントへ返すことができないため、 このエラーコードが必要です。)

error パラメーターの値は、 集合 %x20-21 / %x23-5B / %x5D-7E の外の文字を 含んではなりません (MUST NOT)。

"error_description":

OPTIONAL。発生したエラーを クライアント開発者が理解するのを支援するために使用される、 追加情報を提供する人間可読の ASCII [USASCII] テキスト。 error_description パラメーターの値は、 集合 %x20-21 / %x23-5B / %x5D-7E の外の文字を 含んではなりません (MUST NOT)。

"error_uri":

OPTIONAL。エラーに関する情報を持つ 人間可読の Web ページを識別する URI。クライアント開発者に エラーに関する追加情報を提供するために使用されます。 error_uri パラメーターの値は URI-reference 構文に 適合しなければならず、したがって集合 %x21 / %x23-5B / %x5D-7E の 外の文字を含んではなりません (MUST NOT)。

"state":

クライアントの認可リクエストに state パラメーターが存在した場合は REQUIRED。 クライアントから受け取った正確な値。

"iss":

OPTIONAL。認可サーバーの識別子。 詳細については上記の Section 4.1.2 を参照してください。

たとえば、認可サーバーは次の HTTP レスポンスで ユーザーエージェントをリダイレクトすることにより、リクエストが拒否されたことを示します:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?error=access_denied
          &state=xyz&iss=https%3A%2F%2Fauthorization-server.example.com

4.1.3. トークンエンドポイント 拡張

認可グラント種別は、トークンエンドポイントにおいて authorization_codegrant_type 値で識別されます。

この値が設定されている場合、Section 3.2.2 を 超えて次の追加トークンリクエストパラメーターがサポートされます:

"code":

REQUIRED。認可サーバーから受け取った認可コード。

"code_verifier":

認可リクエストに code_challenge パラメーターが 含まれていた場合は REQUIRED。それ以外では使用してはなりません (MUST NOT)。 元のコードベリファイア文字列。

"client_id":

クライアントが Section 3.2.1 で説明されるように 認可サーバーで認証していない場合は REQUIRED。

認可サーバーは、与えられた認可コードに対して アクセストークンを一度だけ返さなければなりません (MUST)。

以前に成功したトークンリクエストと同じ認可コードで 2 回目の有効なトークンリクエストが行われた場合、 認可サーバーはリクエストを拒否しなければならず (MUST)、 その認可コードに基づいて以前に発行されたすべてのアクセストークンおよび リフレッシュトークンを(可能であれば)取り消すべきです (SHOULD)。 さらなる詳細については Section 7.5.2 を 参照してください。

たとえば、クライアントは次の HTTPS リクエストを行います (表示目的のためだけに追加の改行を含む):

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&code_verifier=3641a2d12d66101249cdf7a79c000c1f8c05d2aafcf14bf146497bed

Section 3.2.2 の処理規則に加えて、 認可サーバーは次を行わなければなりません (MUST):

  • 認可コードが、認証済みの confidential client に発行されたことを確認する、またはクライアントが public である場合は、 リクエスト内の client_id に発行されたことを確認する、

  • 認可コードが有効であることを検証する、

  • 認可リクエストに code_challenge パラメーターが存在した場合に限り、 code_verifier パラメーターが存在することを検証する、

  • code_verifier が存在する場合、 まずクライアントによって指定された code_challenge_method 方式に従って それを変換し、その後、受け取った code_verifier から コードチャレンジを計算して、以前に関連付けられた code_challenge と比較することにより code_verifier を検証する、および

  • トークンリクエスト内の認可コードに関連付けられた 認可リクエストに code_challenge が存在しなかった場合、 認可サーバーはトークンリクエストを拒否しなければなりません (MUST)。

トークンリクエスト内の redirect_uri パラメーターに関する OAuth 2.0 クライアントとの後方互換性の詳細については、 Section 10.2 を参照してください。

4.2. クライアントクレデンシャル グラント

クライアントは、自身の制御下にある保護されたリソース、 または認可サーバーと事前に取り決められた別のリソース所有者の 保護されたリソース(その方法はこの仕様の範囲外)へのアクセスを 要求している場合、自身のクライアントクレデンシャルのみ (またはその他のサポートされる認証手段)を使用して アクセストークンを要求できます。

クライアントクレデンシャルグラント種別は、confidential client によってのみ 使用されなければなりません (MUST)。

     +---------+                                  +---------------+
     |         |                                  |               |
     |         |>--(1)- Client Authentication --->| Authorization |
     | Client  |                                  |     Server    |
     |         |<--(2)---- Access Token ---------<|               |
     |         |                                  |               |
     +---------+                                  +---------------+
図 4: クライアントクレデンシャルグラント

Figure 4 に示される クライアントクレデンシャルグラントの使用は、次の手順を含みます:

(1) クライアントは認可サーバーで認証し、 トークンエンドポイントからアクセストークンを要求します。

(2) 認可サーバーはクライアントを認証し、有効であれば アクセストークンを発行します。

4.2.1. トークンエンドポイント 拡張

クライアントクレデンシャルグラント種別は、トークン エンドポイントにおいて client_credentialsgrant_type 値で 識別されます。

この値が設定されている場合、Section 3.2.2 を 超えて次の追加トークンリクエストパラメーターがサポートされます:

"scope":

OPTIONAL。 Section 1.4.1 で 説明されるアクセスリクエストのスコープ。

たとえば、クライアントはトランスポート層セキュリティを使用して 次の HTTP リクエストを行います(表示目的のためだけに追加の改行を含む):

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

認可サーバーはクライアントを認証しなければなりません (MUST)。

4.3. リフレッシュトークン グラント

リフレッシュトークンは、認可サーバーによってクライアントへ 発行されるクレデンシャルであり、既存のグラントに基づいて 新しい(fresh)アクセストークンを取得するために使用できます。 クライアントがこの選択肢を使用するのは、以前のアクセストークンが 失効したため、またはクライアントが以前にそれぞれのグラントで 承認されたものより狭いスコープのアクセストークンを取得しており、 後で同じグラントの下で異なるスコープを持つアクセストークンを 必要とするためです。

リフレッシュトークンは、転送中および保存時に機密として保持され、 認可サーバーとリフレッシュトークンが発行されたクライアントの間でのみ 共有されなければなりません (MUST)。認可サーバーは、 リフレッシュトークンと、それが発行されたクライアントとの結び付きを 維持しなければなりません (MUST)。

認可サーバーは、クライアントアイデンティティを認証できる場合は常に、 リフレッシュトークンとクライアントアイデンティティの結び付きを検証しなければ なりません (MUST)。クライアント認証が不可能な場合、認可サーバーは 送信者制約付きリフレッシュトークンを発行するか、 Section 4.3.1 で説明されるように リフレッシュトークンローテーションを使用するべきです (SHOULD)。

認可サーバーは、権限のない当事者が有効なリフレッシュトークンを 生成、変更、または推測できないことを保証しなければなりません (MUST)。

4.3.1. トークンエンドポイント 拡張

リフレッシュトークングラント種別は、トークンエンドポイントにおいて refresh_tokengrant_type 値で識別されます。

この値が設定されている場合、Section 3.2.2 を超えて 次の追加パラメーターがサポートされます:

"refresh_token":

REQUIRED。クライアントに発行されたリフレッシュトークン。

"scope":

OPTIONAL。 Section 1.4.1 で 説明されるアクセスリクエストのスコープ。 要求されたスコープは、リソース所有者によって最初に付与された ものではないスコープを含んではならず (MUST NOT)、省略された場合は リソース所有者によって最初に付与されたスコープと等しいものとして 扱われます。

リフレッシュトークンは通常、追加のアクセストークンを 要求するために使用される長期的なクレデンシャルであるため、 リフレッシュトークンはそれが発行されたクライアントに結び付けられます。 confidential client は、Section 3.2.1 で説明されるように、認可サーバーで認証しなければなりません (MUST)。

たとえば、クライアントはトランスポート層セキュリティを使用して 次の HTTP リクエストを行います(表示目的のためだけに追加の改行を含む):

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

Section 3.2.2 の処理規則に加えて、 認可サーバーは次を行わなければなりません (MUST):

  • クライアント認証がリクエストに含まれる場合、 リフレッシュトークンが認証済みクライアントに発行されたことを確認する、 または client_id がリクエストに含まれる場合、リフレッシュトークンが 一致するクライアントに発行されたことを確認する

  • このリフレッシュトークンに対応するグラントが まだ有効であることを検証する

  • リフレッシュトークンを検証する

認可サーバーは、public client に対する悪意ある行為者による リフレッシュトークンリプレイを検出するために、次のいずれかの方法を 利用しなければなりません (MUST):

  • 送信者制約付きリフレッシュトークン: 認可サーバーは、たとえば DPoP [RFC9449] または mTLS [RFC8705] を利用することにより、 リフレッシュトークンを特定のクライアントインスタンスに 暗号学的に結び付けます。

  • リフレッシュトークンローテーション: 認可サーバーは、アクセストークン更新レスポンスごとに 新しいリフレッシュトークンを発行します。以前のリフレッシュトークンは 無効化されますが、その関係に関する情報は認可サーバーによって 保持されます。リフレッシュトークンが侵害され、その後攻撃者と 正当なクライアントの両方によって使用された場合、そのうちの一方が 無効化されたリフレッシュトークンを提示することになり、これにより 認可サーバーは侵害を知ることができます。認可サーバーは どちらの当事者が無効なリフレッシュトークンを提出したかを判断できませんが、 アクティブなリフレッシュトークンと、それに関連付けられたアクセス認可 グラントも取り消します。これにより、正当なクライアントに新しい 認可グラントの取得を強制する代償を払って、攻撃の進行を停止します。

実装上の注記: リフレッシュトークンが属するグラントは、 リフレッシュトークン自体にエンコードされる場合があります。これにより、 認可サーバーはリフレッシュトークンが属するグラントを効率的に判断でき、 ひいては取り消す必要があるすべてのリフレッシュトークンを判断できます。 この場合、認可サーバーは、たとえば署名を使用して、 リフレッシュトークン値の完全性を保証しなければなりません (MUST)。

4.3.2. リフレッシュトークン レスポンス

有効で認可されている場合、認可サーバーは Section 3.2.3 で説明されるようにアクセストークンを発行します。

認可サーバーは新しいリフレッシュトークンを発行してもよく (MAY)、 その場合、クライアントは古いリフレッシュトークンを破棄し、 新しいリフレッシュトークンに置き換えなければなりません (MUST)。

4.3.3. リフレッシュトークン 推奨事項

認可サーバーは、クライアントに新しいリフレッシュトークンを 発行した後、古いリフレッシュトークンを取り消してもよいです (MAY)。 新しいリフレッシュトークンが発行される場合、リフレッシュトークンの スコープは、クライアントがリクエストに含めたリフレッシュトークンの スコープと同一でなければなりません (MUST)。

認可サーバーは、次のようなセキュリティイベントの場合に リフレッシュトークンを自動的に取り消してもよいです (MAY):

  • パスワード変更

  • 認可サーバーでのログアウト

クライアントが一定期間非アクティブであった場合、 すなわちリフレッシュトークンが一定期間新しいアクセストークンを 取得するために使用されていない場合、リフレッシュトークンは 失効するべきです (SHOULD)。失効時刻は認可サーバーの裁量によります。 これはグローバル値である場合もあれば、クライアントポリシーまたは リフレッシュトークンに関連付けられたグラント(およびその機密性)に 基づいて決定される場合もあります。

4.4. 拡張グラント

クライアントは、トークンエンドポイントの grant_type パラメーターの値として、(認可サーバーによって定義される) 絶対 URI を使用してグラント種別を指定し、必要な追加パラメーターを 追加することで、拡張グラント種別を使用します。

たとえば、ユーザーが別のデバイス上でクライアントを認可した後、 [RFC8628] で定義される Device Authorization Grant を使用してアクセストークンを要求するには、 クライアントは次の HTTPS リクエストを行います (表示目的のためだけに追加の改行を含む):

  POST /token HTTP/1.1
  Host: server.example.com
  Content-Type: application/x-www-form-urlencoded

  grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code
  &device_code=GmRhmhcxhwEzkoEqiMEg_DnyEysNkuNhszIySk9eS
  &client_id=C409020731

アクセストークンリクエストが有効で認可されている場合、 認可サーバーは Section 3.2.3 で 説明されるように、アクセストークンと任意のリフレッシュトークンを発行します。 リクエストがクライアント認証に失敗したか無効である場合、認可サーバーは Section 3.2.4 で説明されるエラーレスポンスを返します。

5. リソースリクエスト

クライアントは、アクセストークンをリソースサーバーに提示することで 保護されたリソースにアクセスします。リソースサーバーはアクセストークンを 検証し、それが失効していないこと、およびそのスコープが要求されたリソースを カバーしていることを確認しなければなりません (MUST)。リソースサーバーが アクセストークンを検証するために使用する方法はこの仕様の範囲外ですが、 一般にリソースサーバーと認可サーバーの間の相互作用または調整を伴います。 たとえば、リソースサーバーと認可サーバーが同じ場所に配置されている、 または同じシステムの一部である場合、それらはデータベースまたはその他の ストレージを共有する場合があります。2 つのコンポーネントが独立して 運用されている場合、それらは Token Introspection [RFC7662] または JWT [RFC9068] などの構造化アクセストークン形式を使用する場合があります。

5.1. Bearer Token リクエスト

この節は、リソースサーバーへのリソースリクエストで Bearer token を送信する 2 つの方法を定義します。クライアントは以下で 定義される 2 つの方法のうち 1 つを使用しなければならず (MUST)、 各リクエストでトークンを送信するために複数の方法を使用してはなりません (MUST NOT)。

特に、クライアントは URI クエリパラメーターで アクセストークンを送信してはならず (MUST NOT)、 リソースサーバーは URI クエリパラメーター内のアクセストークンを 無視しなければなりません (MUST)。

5.1.1. Authorization リクエストヘッダーフィールド

HTTP/1.1 [RFC7235] によって定義される Authorization リクエストヘッダーフィールドでアクセストークンを 送信する場合、クライアントはアクセストークンを送信するために Bearer スキームを使用します。

例:

 GET /resource HTTP/1.1
 Host: server.example.com
 Authorization: Bearer mF_9.B5f-4.1JqM

このスキームにおける Authorization ヘッダーフィールドの構文は、 [RFC2617] の Section 2 で 定義される Basic スキームの使用法に従います。 Basic と同様に、これは [RFC2617] の Section 1.2 で定義される 汎用構文には準拠していませんが、既存の配備を反映するために そこで概説される推奨プラクティスには従わないものの、 HTTP 1.1 Authentication [RFC7235] の 一般認証フレームワークとは互換性があります。 Bearer クレデンシャルの構文は次のとおりです:

token68    = 1*( ALPHA / DIGIT /
                 "-" / "." / "_" / "~" / "+" / "/" ) *"="
credentials = "bearer" 1*SP token68

クライアントは、Bearer HTTP 認可スキームを持つ Authorization リクエストヘッダーフィールドを使用して、 bearer token による認証済みリクエストを行うべきです (SHOULD)。 リソースサーバーはこの方法をサポートしなければなりません (MUST)。

[RFC9110] の Section 11.1 で説明されるように、 文字列 bearer は大文字小文字を区別しません。これは、次のすべてが Authorization ヘッダーの有効な使用法であることを意味します:

  • Authorization: Bearer mF_9.B5f-4.1JqM

  • Authorization: bearer mF_9.B5f-4.1JqM

  • Authorization: BEARER mF_9.B5f-4.1JqM

  • Authorization: bEaReR mF_9.B5f-4.1JqM

5.1.2. フォームエンコードされた コンテンツパラメーター

HTTP リクエストコンテンツでアクセストークンを送信する場合、 クライアントは access_token パラメーターを使用して リクエストコンテンツにアクセストークンを追加します。クライアントは、 次のすべての条件が満たされない限り、この方法を使用してはなりません (MUST NOT):

  • HTTP リクエストが、application/x-www-form-urlencoded に 設定された Content-Type ヘッダーフィールドを含むこと。

  • コンテンツが、URL Living Standard [WHATWG.URL] によって定義される application/x-www-form-urlencoded content-type の エンコーディング要件に従うこと。

  • HTTP リクエストコンテンツが単一パートであること。

  • リクエスト内でエンコードされるコンテンツは、 完全に ASCII [USASCII] 文字で構成されなければなりません (MUST)。

  • HTTP リクエストメソッドは、コンテンツに 定義済みのセマンティクスがあるものであること。特に、これは GET メソッドを使用してはならない (MUST NOT) ことを意味します。

コンテンツは他のリクエスト固有パラメーターを含んでもよく (MAY)、 その場合、access_token パラメーターは & 文字 (ASCII コード 38)を使用してリクエスト固有パラメーターから 適切に分離されなければなりません (MUST)。

たとえば、クライアントはトランスポート層セキュリティを使用して 次の HTTP リクエストを行います:

POST /resource HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

access_token=mF_9.B5f-4.1JqM

application/x-www-form-urlencoded 方式は、 参加するクライアントが Authorization リクエストヘッダーフィールドへ アクセスできないアプリケーションコンテキストを除いて、使用されるべきではありません (SHOULD NOT)。 リソースサーバーはこの方法をサポートしてもよいです (MAY)。

5.2. アクセストークン 検証

アクセストークンを受け取った後、リソースサーバーは アクセストークンがまだ失効しておらず、要求されたリソースへのアクセスを 認可されており、適切なスコープで発行されており、保護されたリソースへ アクセスするためのリソースサーバーのその他のポリシー要件を満たしていることを 確認しなければなりません (MUST)。

アクセストークンは一般に、参照トークンまたは自己エンコードトークンの 2 つのカテゴリに分類されます。 参照トークンは、認可サーバーへ問い合わせるか、トークンデータベースで トークンを検索することによって検証できます。一方、自己エンコードトークンは、 リソースサーバーが抽出できる暗号化および/または署名された文字列内に 認可情報を含みます。

アクセストークンの有効性を確認するために認可サーバーへ 問い合わせる標準化された方法は、Token Introspection [RFC7662] で定義されています。

トークン文字列内に情報をエンコードする標準化された方法は、 JWT Profile for Access Tokens [RFC9068] で定義されています。

アクセストークンの作成および検証に関する追加の考慮事項については、 Section 7.1 を参照してください。

5.3. エラーレスポンス

リソースアクセスリクエストが失敗した場合、リソースサーバーは クライアントにエラーを通知するべきです (SHOULD)。エラーレスポンスの詳細は、 Section 5.3.2 の Bearer token の説明など、 特定のトークン種別によって決定されます。

5.3.1. WWW-Authenticate レスポンスヘッダーフィールド

保護されたリソースリクエストに認証クレデンシャルが 含まれていない場合、または保護されたリソースへのアクセスを可能にする アクセストークンが含まれていない場合、リソースサーバーは HTTP WWW-Authenticate レスポンスヘッダーフィールドを含めなければなりません (MUST)。 他の条件へのレスポンスにもこれを含めてもよいです (MAY)。 WWW-Authenticate ヘッダーフィールドは、HTTP/1.1 [RFC7235] によって定義されるフレームワークを使用します。

このトークン種別のすべてのチャレンジは、auth-scheme 値 Bearer を使用しなければなりません (MUST)。このスキームには 1 つ以上の auth-param 値が続かなければなりません (MUST)。 このトークン種別についてこの仕様で使用または定義される auth-param 属性は次のとおりです。その他の auth-param 属性も 使用してもよいです (MAY)。

"realm":

HTTP/1.1 [RFC7235] で 説明される方法で保護の範囲を示すために、 realm 属性を含めてもよいです (MAY)。 realm 属性は複数回出現してはなりません (MUST NOT)。

"scope":

scope 属性は Section 1.4.1 で 定義されています。scope 属性は、大文字小文字を区別する スコープ値の空白区切りリストであり、要求されたリソースに アクセスするためにアクセストークンに必要なスコープを示します。 scope 値は実装定義であり、それらのための集中レジストリはありません。 許可される値は認可サーバーによって定義されます。 scope 値の順序は重要ではありません。場合によっては、 保護されたリソースを利用するために十分なアクセススコープを持つ 新しいアクセストークンを要求する際に、scope 値が使用されます。 scope 属性の使用は OPTIONAL です。scope 属性は 複数回出現してはなりません (MUST NOT)。scope 値は プログラムによる使用を意図しており、エンドユーザーに表示されることを 意図していません。

2 つのスコープ値の例を以下に示します。 これらはそれぞれ、OpenID Connect [OpenID.Messages] および Open Authentication Technology Committee (OATC) Online Multimedia Authorization Protocol [OMAP] OAuth 2.0 ユースケースから取られています:

scope="openid profile email"
scope="urn:example:channel=HBO&urn:example:rating=G,PG-13"
"error":

保護されたリソースリクエストがアクセストークンを 含んでおり、認証に失敗した場合、リソースサーバーは アクセスリクエストが拒否された理由をクライアントに提供するために error 属性を含めるべきです (SHOULD)。パラメーター値は Section 5.3.2 で説明されます。

"error_description":

リソースサーバーは、開発者に エンドユーザーに表示されることを意図しない人間可読の説明を 提供するために、error_description 属性を含めてもよいです (MAY)。

"error_uri":

リソースサーバーは、エラーを説明する 人間可読の Web ページを識別する絶対 URI を持つ error_uri 属性を含めてもよいです (MAY)。

errorerror_description、および error_uri 属性は複数回出現してはなりません (MUST NOT)。

Appendix A.4 で指定される scope 属性の値は、スコープ値を表すための集合 %x21 / %x23-5B / %x5D-7E、およびスコープ値間の区切り文字である %x20 の外の文字を含んではなりません (MUST NOT)。 Appendix A.7 および Appendix A.8 で指定される error および error_description 属性の値は、 集合 %x20-21 / %x23-5B / %x5D-7E の外の文字を含んでは なりません (MUST NOT)。 Appendix A.9 で指定される error_uri 属性の値は、URI-reference 構文に適合しなければならず、 したがって集合 %x21 / %x23-5B / %x5D-7E の外の文字を 含んではなりません (MUST NOT)。

5.3.2. エラーコード

リクエストが失敗した場合、リソースサーバーは 適切な HTTP ステータスコード(通常は 400、401、403、または 405)を使用して応答し、 レスポンスに次のエラーコードのいずれかを含めます:

"invalid_request":

リクエストに必須パラメーターが欠落している、 サポートされていないパラメーターまたはパラメーター値を含んでいる、 同じパラメーターを繰り返している、アクセストークンを含めるために 複数の方法を使用している、またはその他の形式不正である。 リソースサーバーは HTTP 400 (Bad Request) ステータスコードで 応答するべきです (SHOULD)。

"invalid_token":

提供されたアクセストークンが失効済み、取り消し済み、 形式不正、またはその他の理由で無効である。リソースサーバーは HTTP 401 (Unauthorized) ステータスコードで応答するべきです (SHOULD)。 クライアントは新しいアクセストークンを要求し、保護されたリソースリクエストを 再試行してもよいです (MAY)。

"insufficient_scope":

リクエストは、クライアントに付与されアクセストークンによって 表されるスコープよりも高い権限(スコープ)を必要とする。 リソースサーバーは HTTP 403 (Forbidden) ステータスコードで 応答するべきであり (SHOULD)、保護されたリソースへアクセスするために 必要なスコープを持つ scope 属性を含めてもよいです (MAY)。

拡張は、追加のエラーコードを定義したり、 上記のエラーコードが返される追加の状況を指定したりできます。

リクエストに認証情報がまったくない場合 (たとえば、クライアントが認証が必要であることを知らなかった、 またはサポートされていない認証方式を使用して試行した場合)、 リソースサーバーはエラーコードまたはその他のエラー情報を 含めるべきではありません (SHOULD NOT)。

例:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example"

また、失効したアクセストークンを使用した認証試行を伴う 保護されたリソースリクエストへのレスポンスでは次のようになります:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
                  error="invalid_token",
                  error_description="The access token expired"

6. 拡張性

6.1. アクセストークン 種別の定義

アクセストークン種別は、次の 2 つの方法のいずれかで定義できます。 Access Token Types レジストリに登録する([RFC6749] の Section 11.1 の 手順に従う)、または名前として一意の絶対 URI を使用する。

6.1.1. 登録済み アクセストークン種別

[RFC6750] は、 OAuth トークン認証スキーム間で共有されるエラー値のために、 [RFC6749] の Section 11.4 に共通レジストリを確立しています。

主に OAuth トークン認証のために設計された新しい認証スキームは、 エラー状態コードをクライアントに提供するためのメカニズムを 定義するべきであり (SHOULD)、そこで許可されるエラー値は この仕様によって確立されるエラーレジストリに登録されます。

そのようなスキームは、有効なエラーコードの集合を 登録値の部分集合に制限してもよいです (MAY)。エラーコードが名前付き パラメーターを使用して返される場合、パラメーター名は error であるべきです (SHOULD)。

OAuth トークン認証に使用できるものの、その目的を主として 設計されていないその他のスキームは、同じ方法でそのエラー値を レジストリに結び付けてもよいです (MAY)。

新しい認証スキームは、この仕様での使用法と並行する方法で エラー情報を返すために、error_description および error_uri パラメーターの使用も指定することを 選択してもよいです (MAY)。

種別名は type-name ABNF に適合しなければなりません (MUST)。 種別定義が新しい HTTP 認証スキームを含む場合、種別名は ([RFC2617] で定義される) HTTP 認証スキーム名と同一であるべきです (SHOULD)。 トークン種別 example は例での使用のために予約されています。

type-name  = 1*name-char
name-char  = "-" / "." / "_" / DIGIT / ALPHA

6.1.2. ベンダー固有アクセストークン種別

URI 名を利用する種別は、一般に適用可能ではなく、 使用されるリソースサーバーの実装詳細に固有の、 ベンダー固有実装に限定されるべきです (SHOULD)。

その他すべての種別は登録されなければなりません (MUST)。

6.2. 新しいエンドポイント パラメーターの定義

認可エンドポイントまたはトークンエンドポイントで使用する 新しいリクエストパラメーターまたはレスポンスパラメーターは、 [RFC6749] の Section 11.2 の 手順に従って、OAuth Parameters レジストリで定義および登録されます。

パラメーター名は param-name ABNF に適合しなければならず (MUST)、 パラメーター値の構文は十分に定義されなければなりません (MUST) (たとえば ABNF、または既存パラメーターの構文への参照を使用)。

param-name  = 1*name-char
name-char   = "-" / "." / "_" / DIGIT / ALPHA

登録されていないベンダー固有パラメーター拡張で、 一般に適用可能ではなく、使用される認可サーバーの実装詳細に 固有のものは、他の登録済み値と衝突しにくいベンダー固有プレフィックス (たとえば 'companyname_' で始まる)を利用するべきです (SHOULD)。

6.3. 新しい 認可グラント種別の定義

新しい認可グラント種別は、grant_type パラメーターで 使用するために一意の絶対 URI を割り当てることで定義できます。 拡張グラント種別が追加のトークンエンドポイントパラメーターを必要とする場合、 それらは [RFC6749] の Section 11.2 で説明されるように、OAuth Parameters レジストリに 登録されなければなりません (MUST)。

6.4. 新しい 認可エンドポイントレスポンス種別の定義

認可エンドポイントで使用する新しいレスポンス種別は、 [RFC6749] の Section 11.3 の 手順に従って、Authorization Endpoint Response Types レジストリで 定義および登録されます。レスポンス種別名は response-type ABNF に 適合しなければなりません (MUST)。

response-type  = response-name *( SP response-name )
response-name  = 1*response-char
response-char  = "_" / DIGIT / ALPHA

レスポンス種別が 1 つ以上の空白文字(%x20)を含む場合、 値の順序が重要ではない空白区切りの値リストとして比較されます。 値の順序は 1 つだけ登録でき、それは同じ値集合の他のすべての 配置を包含します。

たとえば、拡張は code other_token レスポンス種別を定義および登録できます。登録されると、同じ組み合わせを other_token code として登録することはできませんが、 両方の値は同じレスポンス種別を示すために使用できます。

6.5. 追加の エラーコードの定義

プロトコル拡張(すなわちアクセストークン種別、 拡張パラメーター、または拡張グラント種別)が、認可コードグラントの エラーレスポンス(Section 4.1.2.1)、トークンエラーレスポンス(Section 3.2.4)、または リソースアクセスエラーレスポンス(Section 5.3)で使用する追加の エラーコードを必要とする場合、そのようなエラーコードを定義してもよいです (MAY)。

拡張エラーコードは、それらが関連して使用される拡張が 登録済みアクセストークン種別、登録済みエンドポイントパラメーター、 または拡張グラント種別である場合、([RFC6749] の Section 11.4 の 手順に従って)登録されなければなりません (MUST)。 未登録拡張で使用されるエラーコードは登録してもよいです (MAY)。

エラーコードは error ABNF に適合しなければならず (MUST)、 可能な場合は識別名をプレフィックスとして付けるべきです (SHOULD)。 たとえば、拡張パラメーター example に設定された無効な値を 識別するエラーは、example_invalid と名付けられるべきです (SHOULD)。

error      = 1*error-char
error-char = %x20-21 / %x23-5B / %x5D-7E

7. セキュリティ上の考慮事項

柔軟で拡張可能なフレームワークとして、OAuth の セキュリティ上の考慮事項は多くの要因に依存します。以下の節は、 Section 2.1 で説明される 3 つのクライアントプロファイル、すなわち Web アプリケーション、 ブラウザベースアプリケーション、およびネイティブアプリケーションに焦点を当てた セキュリティ指針を実装者に提供します。

包括的な OAuth セキュリティモデルと分析、および プロトコル設計の背景は、 [RFC6819] および [RFC9700] によって提供されています。

7.1. アクセストークンのセキュリティ上の 考慮事項

7.1.1. セキュリティ脅威

次の一覧は、何らかの形式のトークンを利用するプロトコルに対する いくつかの一般的な脅威を示します。この脅威一覧は NIST Special Publication 800-63 [NIST800-63] に基づいています。

7.1.1.1. アクセストークンの 生成/変更

攻撃者は偽のアクセストークンを生成したり、 既存トークンの内容(認証または属性ステートメントなど)を変更したりして、 リソースサーバーにクライアントへ不適切なアクセスを付与させる可能性があります。 たとえば、攻撃者は有効期間を延長するようトークンを変更する可能性があります。 悪意あるクライアントは、本来閲覧できないはずの情報へアクセスするために アサーションを変更する可能性があります。

7.1.1.2. アクセストークンの 情報開示

アクセストークンは、機密情報を含む認証および 属性ステートメントを含む場合があります。

クライアントがアクセストークンの内容を観察できないように する必要がある場合、コンテンツ暗号化が適用されなければなりません (MUST)。

Cookie はデフォルトで平文で送信されるため、 それらに含まれる任意の情報は開示のリスクにさらされます: Bearer token は、平文で送信され得る Cookie に保存されては なりません (MUST NOT)。 Cookie に関するセキュリティ上の考慮事項については、 [RFC6265] の Section 7 および 8 を参照してください。

7.1.1.3. アクセストークン リダイレクト

攻撃者は、あるリソースサーバーで使用されるために 生成されたアクセストークンを使用して、別のリソースサーバーへアクセスします。 その別のリソースサーバーは、そのトークンが自分のためのものであると 誤って信じます。

7.1.1.4. アクセストークン リプレイ

攻撃者は、そのリソースサーバーで過去にすでに 使用されたアクセストークンを使用しようとします。

7.1.2. 脅威の軽減

デジタル署名を使用してアクセストークンの内容を保護し、 定期的な鍵ローテーションなど署名鍵管理のベストプラクティスに従うことで、 広範な脅威を軽減できます。

あるいは、bearer token は、認可情報を直接エンコードするのではなく、 認可情報への参照を含むことができます。参照を使用する場合、 その参照を認可情報に解決するために、リソースサーバーと認可サーバーとの間で 追加の相互作用が必要になる場合があります。そのような相互作用の仕組みは この仕様では定義されませんが、そのようなメカニズムの 1 つは Token Introspection [RFC7662] で定義されています。

この文書はアクセストークンのエンコーディングまたは内容を 指定しません。したがって、アクセストークンの完全性保護を保証する 手段に関する詳細な推奨事項は、この仕様の範囲外です。 アクセストークンのエンコードおよび署名メカニズムの一例は、 JSON Web Token Profile for Access Tokens [RFC9068] で説明されています。

アクセストークンリダイレクトに対処するには、 認可サーバーが、トークン内に意図された受信者(audience)の アイデンティティ、通常は単一のリソースサーバー(またはリソースサーバーの リスト)を含めることが重要です。トークンの使用を特定のスコープに 制限することも推奨されます (RECOMMENDED)。

Section 1.5 は、アクセストークンの開示から保護し、 クライアント、リソースサーバー、および認可サーバー間の通信に 機密性と完全性を提供するための情報を提供します。

7.1.3. 推奨事項の 要約

7.1.3.1. bearer token を 保護する

クライアント実装は、 bearer token が意図しない当事者へ漏えいしないことを保証しなければなりません (MUST)。 それらの当事者は、それを使用して保護されたリソースへのアクセスを 得ることができるためです。これは bearer token を使用する際の 主要なセキュリティ上の考慮事項であり、以下のより具体的な 推奨事項すべての基礎となります。

7.1.3.2. TLS 証明書チェーンを検証する

クライアントは、保護されたリソースへリクエストを 行う際に TLS 証明書チェーンを検証しなければなりません (MUST)。 そうしないと、DNS ハイジャック攻撃がトークンを盗み、 意図しないアクセスを得ることを可能にする場合があります。

7.1.3.3. 常に TLS (https) を使用する

クライアントは、bearer token を使用して リクエストを行う際、常に TLS (https) または同等のトランスポート セキュリティを使用しなければなりません (MUST)。そうしないと、 トークンが多数の攻撃にさらされ、攻撃者が意図しないアクセスを 得る可能性があります。

7.1.3.4. bearer token を HTTP Cookie に保存しない

実装は、平文で送信され得る Cookie (Cookie のデフォルト送信モード)内に bearer token を保存しては なりません (MUST NOT)。bearer token を Cookie に保存する実装は、 クロスサイトリクエストフォージェリに対する予防措置を 講じなければなりません (MUST)。

7.1.3.5. 短命な bearer token を発行する

認可サーバーは、特に Web ブラウザ内または 情報漏えいが発生する可能性のあるその他の環境で実行される クライアントにトークンを発行する場合、短命な bearer token を 発行するべきです (SHOULD)。短命な bearer token を使用することで、 それらが漏えいした場合の影響を減らすことができます。

7.1.3.6. スコープ付き bearer token を発行する

認可サーバーは、意図されたリソースサーバーまたは リソースサーバーの集合に使用範囲を限定する audience 制限を含む bearer token を発行するべきです (SHOULD)。

7.1.3.7. bearer token を ページ URL で渡さない

Bearer token はページ URL (たとえばクエリ文字列パラメーター)で渡されてはなりません (MUST NOT)。 代わりに、bearer token は、機密性対策が取られた HTTP メッセージヘッダーまたは メッセージボディで渡されるべきです (SHOULD)。 ブラウザ、Web サーバー、およびその他のソフトウェアは、ブラウザ履歴、 Web サーバーログ、およびその他のデータ構造内の URL を 十分に保護しない場合があります。bearer token がページ URL で渡される場合、 攻撃者は履歴データ、ログ、またはその他の保護されていない場所から それらを盗むことができる可能性があります。

7.1.4. アクセストークンの 権限制限

アクセストークンに関連付けられる権限は、 特定のアプリケーションまたはユースケースに必要な最小限に 制限されるべきです (SHOULD)。これにより、クライアントがリソース所有者によって 認可された権限を超えることを防ぎます。また、ユーザーがそれぞれの セキュリティポリシーによって認可された権限を超えることも防ぎます。 権限制限は、アクセストークン漏えいの影響を減らす助けにもなります。

特に、アクセストークンは特定のリソースサーバー (audience 制限)、望ましくは単一のリソースサーバーに制限されるべきです (SHOULD)。 これを実現するために、認可サーバーはアクセストークンを特定の リソースサーバーと関連付け、各リソースサーバーは、すべてのリクエストについて、 そのリクエストとともに送信されたアクセストークンがその特定の リソースサーバーで使用されることを意図したものかどうかを検証する義務があります。 そうでない場合、リソースサーバーはそれぞれのリクエストへの応答を 拒否しなければなりません (MUST)。クライアントおよび認可サーバーは、 アクセスしたいリソースサーバーを決定するために、この文書および [RFC8707] でそれぞれ指定される scope または resource パラメーターを利用してもよいです (MAY)。

さらに、アクセストークンは、リソースサーバーまたはリソース上の 特定のリソースおよびアクションに制限されるべきです (SHOULD)。 これを実現するために、認可サーバーはアクセストークンをそれぞれの リソースおよびアクションと関連付け、各リソースサーバーは、 すべてのリクエストについて、そのリクエストとともに送信されたアクセストークンが その特定のリソースに対するその特定のアクションで使用されることを 意図したものかどうかを検証する義務があります。そうでない場合、 リソースサーバーはそれぞれのリクエストへの応答を拒否しなければなりません。 クライアントおよび認可サーバーは、それらのリソースおよび/またはアクションを 決定するために、[RFC9396] で指定される scope パラメーターおよび authorization_details を利用してもよいです (MAY)。

7.2. クライアント認証

クライアント登録およびクレデンシャルライフサイクル管理の 全体的なプロセスに応じて、これは認可サーバーが特定のクライアントに対して 持つ信頼度に影響する場合があります。

たとえば、動的に登録されたクライアントの認証は、 クライアントのアイデンティティを証明するものではなく、認可サーバーへの 繰り返しのリクエストが同じクライアントインスタンスから行われたことを 保証するだけです。そのようなクライアントは、要求が許可されるスコープの点で 制限されたり、より短いトークン有効期間などのその他の制限を持ったりする場合があります。

対照的に、開発者のアイデンティティが検証され、契約に署名し、 安全なバックエンドサービスでのみ使用されるクライアントシークレットを 発行された登録済みアプリケーションがある場合、認可サーバーはこのクライアントに より機密性の高いスコープを要求すること、またはより長期間有効なトークンの 発行を許可する場合があります。

7.3. クライアントなりすまし

confidential client のクレデンシャルが盗まれた場合、 悪意あるクライアントはそのクライアントになりすまし、保護されたリソースへの アクセスを取得できます。

認可サーバーは、明示的なリソース所有者認証を強制し、 リソース所有者にクライアントと要求された認可スコープおよび有効期間に関する 情報を提供するべきです (SHOULD)。リソース所有者は、現在のクライアントの 文脈でその情報を確認し、リクエストを認可するか拒否するかを判断します。

認可サーバーは、クライアントを認証するか、繰り返しリクエストが なりすましではなく元のクライアントから来ていることを保証するための 他の手段に依存することなく、(能動的なリソース所有者の相互作用なしに) 繰り返しの認可リクエストを自動的に処理するべきではありません (SHOULD NOT)。

7.3.1. ネイティブアプリの なりすまし

上記のように、認可サーバーは、 クライアントのアイデンティティを保証できる場合を除き、 ユーザーの同意または相互作用なしに認可リクエストを自動的に処理する べきではありません (SHOULD NOT)。これには、ユーザーが以前に 特定のクライアント ID に対する認可リクエストを承認している場合も含まれます。 クライアントのアイデンティティを証明できない限り、そのリクエストは 以前のリクエストが承認されていなかったかのように処理されるべきです (SHOULD)。

claimed https スキームリダイレクトなどの措置は、 アイデンティティ証明として認可サーバーに受け入れられてもよいです (MAY)。 一部のオペレーティングシステムは、適切な場合に受け入れられてもよい 代替のプラットフォーム固有アイデンティティ機能を提供する場合があります (MAY)。

7.3.2. アクセストークンの 権限制限

クライアントは必要最小限のスコープでアクセストークンを 要求するべきです (SHOULD)。認可サーバーは、要求されたスコープを どのように認めるかを選択する際にクライアントアイデンティティを考慮するべきであり (SHOULD)、 要求されたものより少ないスコープでアクセストークンを発行してもよいです (MAY)。

アクセストークンに関連付けられる権限は、 特定のアプリケーションまたはユースケースに必要な最小限に 制限されるべきです (SHOULD)。これにより、クライアントがリソース所有者によって 認可された権限を超えることを防ぎます。また、ユーザーがそれぞれの セキュリティポリシーによって認可された権限を超えることも防ぎます。 権限制限は、アクセストークン漏えいの影響を減らす助けにもなります。

特に、アクセストークンは特定のリソースサーバー (audience 制限)、望ましくは単一のリソースサーバーに制限されるべきです (SHOULD)。 これを実現するために、認可サーバーはアクセストークンを特定の リソースサーバーと関連付け、各リソースサーバーは、すべてのリクエストについて、 そのリクエストとともに送信されたアクセストークンがその特定の リソースサーバーで使用されることを意図したものかどうかを検証する義務があります。 そうでない場合、リソースサーバーはそれぞれのリクエストへの応答を 拒否しなければなりません (MUST)。クライアントおよび認可サーバーは、 アクセスしたいリソースサーバーを決定するために、 [RFC8707] でそれぞれ指定される scope または resource パラメーターを利用してもよいです (MAY)。

7.4. リソース所有者になりすます クライアント

リソースサーバーは、アクセストークンが発行されたリソース所有者の アイデンティティに基づいて、またはクライアントクレデンシャルグラントにおける クライアントのアイデンティティに基づいてアクセス制御判断を行う場合があります。 実装の詳細に応じて両方の選択肢が可能である場合、クライアントのアイデンティティが リソース所有者のアイデンティティと誤認される可能性があります。たとえば、 クライアントが認可サーバーへの登録時に自身の client_id を 選択できる場合、悪意あるクライアントはそれをエンドユーザーを識別する値 (たとえば OpenID Connect が使用される場合の sub 値)に設定する可能性があります。 リソースサーバーがクライアントに発行されたアクセストークンとエンドユーザーに 発行されたアクセストークンを適切に区別できない場合、そのクライアントは エンドユーザーのリソースにアクセスできる可能性があります。

認可サーバーがクライアント ID とユーザー識別子に共通の名前空間を 持ち、その結果リソースサーバーがリソース所有者によって認可された アクセストークンとクライアント自身によって認可されたアクセストークンを 区別できなくなる場合、認可サーバーは、真正なリソース所有者との混同を 引き起こし得る場合に、クライアントがその client_id またはその他の Claim に影響を与えることを許可するべきではありません (SHOULD NOT)。 これを避けられない場合、認可サーバーはリソースサーバーが 2 種類の アクセストークンを区別するためのその他の手段を提供しなければなりません (MUST)。

7.5. 認可コードの セキュリティ上の考慮事項

7.5.1. 認可 コードインジェクション

認可コードインジェクションは、クライアントが正当な認可サーバーからの 認可コードではなく、攻撃者からの認可コードをその redirect URI で受け取る 攻撃です。保護策がない場合、クライアントは攻撃が発生したことを知るための メカニズムを持ちません。認可コードインジェクションは、攻撃者が被害者の アカウントへのアクセスを取得することと、被害者が誤って攻撃者の アカウントへアクセスしてしまうことの両方につながる可能性があります。

7.5.1.1. 対策

認可コードがクライアントに注入されることを 防ぐために、クライアントには code_challenge および code_verifier の使用が REQUIRED であり、認可サーバーは、 次の両方の基準が満たされる場合を除き、その使用を強制しなければ なりません (MUST):

  • クライアントが confidential client である。

  • 特定の配備および特定のリクエストにおいて、 クライアントが OpenID Connect nonce メカニズムを 適切に実装しているという合理的な保証が認可サーバーにある。

この場合でも、 code_challenge および code_verifier を使用し 強制することはなお推奨されます (RECOMMENDED)。

code_challenge または OpenID Connect nonce 値はトランザクション固有でなければならず (MUST)、 そのトランザクションが開始されたクライアントおよびユーザーエージェントに 安全に結び付けられていなければなりません。トランザクションがエラーに つながる場合、code_challenge または nonce には 新しい値が選択されなければなりません (MUST)。

OpenID Connect nonce パラメーターの検証を クライアントに依存することは、認可サーバーが、クライアントが実際に 認可コードインジェクション攻撃から自身を保護していることを確認する 方法を持たないことを意味します。攻撃者がクライアントに認可コードを 注入できる場合、クライアントは注入された認可コードをなお交換して トークンを取得し、その後になって nonce を検証して一致しないことを 見た後に ID トークンを拒否するだけです。対照的に、認可サーバーが code_challenge および code_verifier パラメーターを 強制することは、より高いセキュリティ結果を提供します。認可サーバーは 認可コードインジェクション攻撃を事前に認識し、最初からトークンを 発行することを避けられるためです。

歴史的注記: PKCE [RFC7636]code_challenge および code_verifier パラメーターが 作成された場所)は、もともとネイティブアプリを認可コード流出攻撃から 保護するメカニズムとして設計されましたが、Web アプリケーションや その他の confidential client を含むあらゆる種類の OAuth クライアントは、 code_challenge および code_verifier メカニズムによって 解決される認可コードインジェクション攻撃の影響を受けます。

7.5.2. 認可コードの 再利用

認可コードが複数回使用できる場合、いくつかの種類の 攻撃が可能になります。

Section 4.1.3 で説明されるように、 認可サーバーは、すでにアクセストークンの発行に使用された認可コードを 使用した 2 回目の有効なリクエストを受信した場合、トークンリクエストを 拒否し、発行済みの任意のトークンを取り消さなければなりません。 攻撃者が認可コードを流出させ、正当なクライアントより先にそれを使用できる場合、 攻撃者はアクセストークンを取得し、正当なクライアントは取得できません。 発行済みの任意のトークンを取り消すことは、攻撃者のトークンも取り消されることを 意味し、攻撃がそれ以上進行することを止めます。

ただし、認可サーバーは、認可コードを含むリクエストも code_verifier やクライアント認証などのその他のパラメーターを含めて 有効である場合にのみ、発行済みトークンを取り消すべきです。 認可サーバーは、無効なパラメーターを含むリプレイされた認可コードを 受信した場合、発行済みトークンを取り消すべきではありません (SHOULD NOT)。 そうしてしまうと、認可コードを取得できるものの、クライアント認証または code_verifier を取得できない攻撃者が、正当なクライアントより先に 無効な認可コードリクエストを送信し、正当なクライアントが有効なリクエストを 行った時点でそのトークンを取り消すことによって、サービス拒否の機会を 作り出すことになります。

7.5.3. HTTP 307 リダイレクト

ユーザークレデンシャルを含む可能性のあるリクエストを リダイレクトする認可サーバーは、リダイレクトに 307 ステータスコード ([RFC9110] の Section 15.4.8)を使用してはなりません (MUST NOT)。 そのようなリクエストに HTTP リダイレクト(たとえば JavaScript ではなく)が 使用される場合、AS はステータスコード 303 ("See Other") を使用するべきです (SHOULD)。

認可エンドポイントでは、典型的なプロトコルフローとして、 AS がユーザーにフォームでクレデンシャルを入力するよう促し、そのフォームが (POST メソッドを使用して)認可サーバーへ送信されます。AS は クレデンシャルを確認し、成功した場合、ユーザーエージェントをクライアントの redirect URI へリダイレクトします。

ステータスコード 307 がリダイレクトに使用された場合、 ユーザーエージェントは POST リクエストを介してユーザークレデンシャルを クライアントへ送信します。

これにより、機密クレデンシャルがクライアントに開示されます。 クライアントが悪意ある場合、AS でユーザーになりすますために そのクレデンシャルを使用できます。

この挙動は開発者にとって予期しないものかもしれませんが、 [RFC9110] の Section 15.4.8 で定義されています。このステータスコードは、 ユーザーエージェントに POST リクエストを GET リクエストへ書き換え、 それによって POST リクエストコンテンツ内のフォームデータを破棄することを 要求しません。

HTTP [RFC9110] では、ステータスコード 303 のみが HTTP POST リクエストを HTTP GET リクエストへ書き換えることを明確に 強制します。一般的な 302 を含む他のすべてのステータスコードでは、 ユーザーエージェントは POST を GET リクエストへ書き換えないことを 選択でき、そのためユーザークレデンシャルをクライアントに開示する可能性があります。 (ただし実際には、ほとんどのユーザーエージェントは 307 リダイレクトでのみ この挙動を示します。)

7.6. エンドポイントの真正性の 確保

中間者攻撃に関連するリスクは、Authorization Endpoint および Token Endpoint と通信するために [RFC8446] などのチャネルセキュリティメカニズムを 必須で使用することによって軽減されます。 さらなる詳細については Section 1.5 を参照してください。

7.7. クレデンシャル推測 攻撃

認可サーバーは、攻撃者がアクセストークン、認可コード、 リフレッシュトークン、リソース所有者のパスワード、およびクライアント クレデンシャルを推測することを防がなければなりません (MUST)。

攻撃者が生成されたトークン(およびエンドユーザーが扱うことを 意図されていないその他のクレデンシャル)を推測する確率は 2^(-128) 以下でなければならず (MUST)、2^(-160) 以下であるべきです (SHOULD)。

認可サーバーは、エンドユーザーによる使用を意図した クレデンシャルを保護するために、その他の手段を利用しなければなりません (MUST)。

7.8. フィッシング攻撃

このプロトコルおよび類似プロトコルが広く配備されることで、 エンドユーザーはパスワードの入力を求められる Web サイトへ リダイレクトされる慣行に慣れてしまう可能性があります。エンドユーザーが クレデンシャルを入力する前にこれらの Web サイトの真正性を慎重に 検証しない場合、攻撃者はこの慣行を悪用してリソース所有者の パスワードや、OTP などのその他のフィッシング可能なクレデンシャルを 盗むことが可能になります。

サービスプロバイダーは、フィッシング攻撃がもたらすリスクについて エンドユーザーを教育しようとするべきであり、フィッシング耐性のある authenticator を使用するなど、エンドユーザーが自分たちのサイトの真正性を 簡単に確認できるメカニズムを提供するべきです。フィッシング耐性のある authenticator は、プラットフォームがそのサイトの origin を正常に検証した場合にのみ、 特定のサイトへログインするためのクレデンシャルをユーザーに提供するためです。 クライアント開発者は、ユーザーエージェントとの相互作用の方法 (たとえば外部、埋め込み)に関するセキュリティ上の影響、および エンドユーザーが認可サーバーの真正性を検証できる能力を考慮するべきです。

フィッシング攻撃のリスクを軽減する詳細については、 Section 1.5 を参照してください。

7.9. Cross-Site Request Forgery

攻撃者は、正当なクライアントの redirect URI へのリクエストを 被害者のデバイス上で注入しようとする場合があります。たとえば、 クライアントに攻撃者の制御下にあるリソースへアクセスさせるためです。 これは Cross-Site Request Forgery (CSRF) として知られる攻撃の一種です。

従来の対策は、クライアントが state パラメーターで CSRF Token とも呼ばれるランダム値を渡し、説明されるようにリクエストを redirect URI とユーザーエージェントセッションに結び付けることです。 この対策は [RFC6819] の Section 5.3.5 で 詳細に説明されています。同じ保護は、code_verifier パラメーターまたは OpenID Connect nonce 値によって提供されます。

CSRF 保護のために state または nonce の代わりに code_verifier を使用する場合、 次に注意することが重要です:

  • クライアントは、AS がクライアントによって使用されることを 意図した code_challenge_method をサポートしていることを 確認しなければなりません (MUST)。認可サーバーが要求された方式を サポートしない場合、代わりに CSRF 保護のために state または nonce が使用されなければなりません (MUST)。

  • state がアプリケーション状態を運ぶために 使用され、その内容の完全性が懸念事項である場合、クライアントは state を改ざんおよび入れ替えから保護しなければなりません (MUST)。 これは、state の内容をブラウザセッションに結び付けること、および/または 署名/暗号化された state 値 [I-D.bradley-oauth-jwt-encoded-state] によって 達成できます。

したがって AS は、[RFC8414] に従った AS メタデータを通じて、 またはサポートを保証または判断するための配備固有の方法を提供することにより、 サポートしているコードチャレンジ方式を検出する方法を提供しなければなりません (MUST)。

7.10. クリックジャッキング

[RFC6819] の Section 4.4.1.9 で説明されるように、 認可リクエストは、ユーザーインターフェイス偽装とも呼ばれる クリックジャッキング攻撃の影響を受けやすいです。そのような攻撃では、 攻撃者は認可エンドポイントのユーザーインターフェイスを無害に見える 文脈に埋め込みます。ユーザーはその文脈と相互作用していると思い、 たとえばボタンをクリックすることで、意図せず認可エンドポイントの ユーザーインターフェイスと相互作用してしまいます。逆のことも可能です。 認可エンドポイントと相互作用していると思ったユーザーが、元のユーザー インターフェイス上に重ねられた攻撃者提供の入力フィールドに 意図せずパスワードを入力してしまう場合があります。クリックジャッキング攻撃は、 たとえば他の要素の上にほぼ見えない iframe を重ねることにより、 ユーザーが攻撃にほとんど気付けないように設計できます。

攻撃者はこのベクトルを使用して、ユーザーの認証クレデンシャルを取得し、 クライアントに付与されるアクセススコープを変更し、場合によっては ユーザーのリソースへアクセスできます。

認可サーバーはクリックジャッキング攻撃を防がなければなりません (MUST)。 [RFC6819] では、X-Frame-Options HTTP レスポンスヘッダーフィールドや frame-busting JavaScript の使用を含む 複数の対策が説明されています。それらに加えて、認可サーバーは Content Security Policy (CSP) level 2 [CSP-2] 以上も使用するべきです (SHOULD)。

有効であるためには、CSP は認可エンドポイント、および該当する場合は ユーザーを認証しクライアントを認可するために使用されるその他のエンドポイント (たとえば、デバイス認可エンドポイント、ログインページ、エラーページなど)で 使用されなければなりません。これにより、CSP をサポートするユーザーエージェントで、 認可されていない origin によるフレーミングを防ぎます。クライアントは、 そのリダイレクトエンドポイントで使用される origin 以外の別の origin による フレーミングを許可してもよいです (MAY)。このため、認可サーバーは、 管理者が特定のクライアントに対して許可された origin を設定できるようにする、 および/またはクライアントがこれらを動的に登録できるようにするべきです (SHOULD)。

CSP を使用すると、認可サーバーは単一のレスポンスヘッダーフィールドで 複数の origin を指定し、柔軟なパターンを使用してそれらを制約できます (詳細については [CSP-2] を参照)。 この標準の Level 2 は、(frame-ancestors を使用して)フレームの origin を制限するポリシーと、(script-src を使用して)HTML ページ上で 実行が許可されるスクリプトのソースを制限するポリシーを組み合わせることで、 クリックジャッキングから保護する堅牢なメカニズムを提供します。 そのようなポリシーの非規範的な例を次の一覧に示します:

HTTP/1.1 200 OK
Content-Security-Policy: frame-ancestors https://ext.example.org:8000
Content-Security-Policy: script-src 'self'
X-Frame-Options: ALLOW-FROM https://ext.example.org:8000
...

一部のユーザーエージェントは [CSP-2] をサポートしていないため、 そのようなレガシーユーザーエージェントが認可サーバーによって明示的に サポートされていない場合を除き、この技術は [RFC6819] で説明されるものを含む その他の技術と組み合わせるべきです (SHOULD)。そのような場合であっても、 追加の対策をなお採用するべきです (SHOULD)。

7.11. インジェクションと入力 検証

インジェクション攻撃は、入力またはその他の外部変数が アプリケーションによってサニタイズされずに使用され、アプリケーションロジックに 変更を引き起こす場合に発生します。これにより、攻撃者がアプリケーション デバイスまたはそのデータへアクセスしたり、サービス拒否を引き起こしたり、 広範な悪意ある副作用を導入したりできる場合があります。

認可サーバーおよびクライアントは、受け取ったパラメーターを 潜在的に悪意ある外部入力として扱い、特に state および redirect_uri パラメーターの値に対して、適切な保護を 適用しなければなりません (MUST)。

7.12. オープンリダイレクト

open redirector は、クエリパラメーターから取得された任意の URI へ ユーザーのブラウザを転送するエンドポイントです。 そのようなエンドポイントは、たとえばユーザーが外部 Web サイトへ リダイレクトされる前にメッセージを表示するため、またはログインプロンプトなどで 中断される前にユーザーが訪れようとしていた URL へ戻すために、 実装される場合があります。

AS またはクライアントが open redirector を持つ場合、次の攻撃が 発生する可能性があります。

7.12.1. Open Redirector としてのクライアント

クライアントは open redirector を公開してはなりません (MUST NOT)。 攻撃者は open redirector を使用してクライアントを指す URL を生成し、 [RFC9700] の Section 4.1.1 で説明されるように、 それらを利用して認可コードを流出させる可能性があります。 もう 1 つの悪用例は、クライアントを指しているように見える URL を 生成することです。これによりユーザーはその URL を信頼してブラウザで 開くよう騙される可能性があります。これはフィッシングに悪用できます。

オープンリダイレクトを防ぐために、クライアントは 対象 URL がホワイトリスト登録されている場合、またはリクエストの origin と 完全性を認証できる場合にのみリダイレクトするべきです。 オープンリダイレクトに対する対策は OWASP [owasp_redir] によって説明されています。

7.12.2. Open Redirector としての 認可サーバー

クライアントの場合と同様に、攻撃者は、フィッシング攻撃を 実行するために、ユーザーの認可サーバー(特にその URL)への信頼を 利用しようとする可能性があります。OAuth 認可サーバーは定期的に ユーザーを他の Web サイト(クライアント)へリダイレクトしますが、 それを安全に行わなければなりません。

Section 4.1.2.1 は、 client_idredirect_uri の組み合わせが無効な場合に 認可サーバーがユーザーエージェントを自動的にリダイレクトしてはならない (MUST NOT) と述べることで、すでにオープンリダイレクトを防いでいます。

しかし、攻撃者は正しく登録された redirect URI を利用して フィッシング攻撃を行うこともできます。たとえば、攻撃者は dynamic client registration [RFC7591] を介してクライアントを登録し、 次のいずれかの攻撃を実行する可能性があります:

  1. たとえば無効なスコープ値を使用するなどして、 意図的に誤った認可リクエストを送信し、認可サーバーに ユーザーエージェントをそのフィッシングサイトへリダイレクトするよう 指示する。

  2. 攻撃者によって制御される client_id および redirect_uri を持つ有効な認可リクエストを 意図的に送信する。ユーザーが認証した後、認可サーバーはユーザーに リクエストへの同意を求めます。ユーザーがリクエストの問題に気付き、 リクエストを拒否した場合でも、認可サーバーはユーザーエージェントを フィッシングサイトへリダイレクトします。この場合、ユーザーエージェントは ユーザーが取った行動に関係なくフィッシングサイトへリダイレクトされます。

  3. 攻撃者によって制御される client_id および redirect_uri を持つ有効なサイレント認証 リクエスト(prompt=none)を意図的に送信する。この場合、 認可サーバーはユーザーエージェントをフィッシングサイトへ 自動的にリダイレクトします。

認可サーバーはこれらの脅威を防ぐための予防措置を 講じなければなりません (MUST)。認可サーバーは常にまずユーザーを 認証しなければならず (MUST)、サイレント認証のユースケースを除いて、 ユーザーをリダイレクトする前に必要に応じてユーザーにクレデンシャルを 求めなければなりません。認可サーバーは、そのリスク評価に基づいて、 redirect URI を信頼できるかどうかを決定する必要があります。 URI の背後にあるコンテンツの信用性と信頼性、および redirect URI と その他のクライアントデータの出所を評価するために、内部的または 何らかの外部サービスを通じて行われる URI 分析を考慮することができます。

認可サーバーは、redirect URI を信頼する場合にのみ ユーザーエージェントを自動的にリダイレクトするべきです (SHOULD)。 URI が信頼されていない場合、認可サーバーはユーザーに通知し、 ユーザーが正しい判断を行うことに依存してもよいです (MAY)。

7.13. トランスポートセキュリティ

ロードバランサーを利用するものを含む一部の配備では、 リソースサーバーへの TLS 接続が、リソースを提供する実際のサーバーより前で 終端されます。これにより、TLS 接続が終端されるフロントエンドサーバーと、 リソースを提供するバックエンドサーバーとの間で、トークンが保護されないままに なる可能性があります。そのような配備では、フロントエンドサーバーと バックエンドサーバーの間でアクセストークンの機密性を保証するために、 十分な措置が採用されなければなりません (MUST)。トークンの暗号化は、 そのような可能な措置の 1 つです。

さらなる情報については、[RFC9110] の Section 17.2 を参照してください。

7.14. 認可サーバー Mix-Up の軽減

Mix-up は、OAuth クライアントが 2 つ以上の認可サーバーと 相互作用し、少なくとも 1 つの認可サーバーが攻撃者の制御下にある シナリオに対する攻撃です。これは、たとえば攻撃者が動的登録を使用して 自身の認可サーバーにクライアントを登録する場合、または認可サーバーが 侵害された場合に発生し得ます。

OAuth クライアントが 1 つの認可サーバーとのみ相互作用できる場合、 mix-up 防御は不要です。しかし、OAuth クライアントが 2 つ以上の認可サーバーと 相互作用するシナリオでは、クライアントは mix-up 攻撃を防がなければなりません (MUST)。 以下では 2 つの異なる方法について説明します。

どちらの防御でも、クライアントは各認可リクエストごとに、 認可リクエストを送信した発行者を保存し、この情報をユーザーエージェントに 結び付け、認可レスポンスが正しい発行者から受信されたことを確認しなければ なりません (MUST)。クライアントは、該当する場合、その後のアクセストークン リクエストが同じ発行者へ送信されることを保証しなければなりません (MUST)。 発行者は、関連付けられたメタデータを介して、フローで使用される 認可エンドポイントとトークンエンドポイントの組み合わせの抽象識別子として 機能します。発行者識別子が利用できない場合、たとえば OAuth 2.0 Authorization Server Metadata [RFC8414] も OpenID Connect Discovery [OpenID.Discovery] も使用されていない場合、 このタプルの別の一意識別子またはタプル自体を代わりに使用できます。 表現を簡潔にするため、以下ではそのような配備固有識別子を 発行者(または発行者識別子)に含めて扱います。

注記: 認可サーバー URL だけを保存することでは、 mix-up 攻撃を識別するには不十分です。攻撃者は、侵害されていない AS の 認可エンドポイント URL を「自分の」AS URL として宣言しつつ、 自身の制御下にあるトークンエンドポイントを宣言する可能性があります。

複数の種類の mix-up 攻撃の詳細な説明については、 [RFC9700] の Section 4.4 を参照してください。

7.14.1. 発行者識別による Mix-Up 防御

この防御では、認可サーバーがその発行者識別子を 認可レスポンスでクライアントへ送信する必要があります。 認可レスポンスを受け取ると、クライアントは受け取った発行者識別子を 保存済みの発行者識別子と比較しなければなりません (MUST)。 不一致がある場合、クライアントは相互作用を中止しなければなりません (MUST)。

この発行者識別子をクライアントへ転送する方法は複数あります:

  • 発行者情報は、たとえば任意のレスポンスパラメーター issSection 4.1.2 を参照)を介して転送できます。

  • OpenID Connect が使用され、ID Token が 認可レスポンスで返される場合、クライアントは ID Token 内の iss Claim を評価できます。

どちらの場合も、iss 値は [RFC9207] に従って 評価されなければなりません (MUST)。

この防御は、発行者情報を転送するための追加パラメーターを 使用する必要がある場合がありますが、mix-up に対する堅牢で比較的単純な 防御です。

7.14.2. 個別の Redirect URI による Mix-Up 防御

この防御では、クライアントは相互作用する各発行者ごとに 個別の redirect URI を使用しなければなりません (MUST)。

クライアントは、発行者用の個別の redirect URI を、 認可レスポンスを受信した URI と比較することで、認可レスポンスが 正しい発行者から受信されたことを確認しなければなりません (MUST)。 不一致がある場合、クライアントはフローを中止しなければなりません (MUST)。

この防御は既存の OAuth 機能の上に構築されていますが、 クライアントが多くの異なる発行者の使用に対して一度だけ登録する シナリオ(いくつかのオープンバンキングスキームなど)では使用できず、 クライアント登録との密接な統合のため、自動的に配備することが より困難です。

さらに、攻撃者は、クライアントが攻撃者の AS に割り当てた redirect URI を使用して "honest" AS に新しいクライアントを登録することで、 この防御によって提供される保護を回避できる可能性があります。 攻撃者はその後、新しく作成したクライアントのクライアント ID に置き換えて、 上記の攻撃を実行できます。

したがって、この防御は他の選択肢が利用できない場合にのみ 使用されるべきです (SHOULD)。

8. ネイティブアプリケーション

ネイティブアプリケーションとは、リソース所有者が使用する デバイス上にインストールされ実行されるクライアント (すなわち、デスクトップアプリケーションまたはネイティブモバイル アプリケーション)です。ネイティブアプリケーションでは、 セキュリティ、プラットフォーム機能、およびエンドユーザー体験全体に 関連する特別な考慮が必要です。

この節の指針は、デスクトップアプリではなく、主にネイティブモバイルアプリの 文脈を対象としています。ネイティブモバイルプラットフォームは、ここで説明される OAuth フローに関連してアプリ開発者へ提供される機能という点で、 デスクトッププラットフォームよりも成熟しています。この指針は主に モバイルアプリに焦点を当てていますが、その多くは一般にデスクトップアプリにも 適用できます。

認可エンドポイントでは、クライアントとリソース所有者の ユーザーエージェントとの間の相互作用が必要です。現在のベストプラクティスは、 OAuth 認可リクエストを、埋め込みユーザーエージェント (Web ビューで実装されたものなど)ではなく、外部ユーザーエージェント (通常はブラウザ)で実行することです。

ネイティブアプリケーションは、認可サーバーからの レスポンスを、それぞれ異なるセキュリティ特性を持つ複数の方法で 取得できます。たとえば、オペレーティングシステムに登録された "app-claimed URL" またはカスタム URL スキームを持つ redirect URI を使用して クライアントをハンドラーとして呼び出す方法、クレデンシャルを手動で コピーアンドペーストする方法、ローカル Web サーバーを実行する方法、 ユーザーエージェント拡張をインストールする方法、またはクライアントの 制御下にあるサーバーホスト型リソースを識別する redirect URI を提供し、 そのリソースがレスポンスをネイティブアプリケーションに利用可能にする方法などです。

以前は、ネイティブアプリが OAuth 認可リクエストに 埋め込みユーザーエージェント(一般に Web ビューで実装される)を使用することが 一般的でした。この方式には、ホストアプリがユーザーのクレデンシャルや Cookie をコピーできること、ユーザーが各アプリで最初から認証し直す必要があることなど、 多くの欠点があります。OAuth で埋め込みユーザーエージェントを使用することの 欠点についてのより深い分析については、Section 8.5.1 を参照してください。

システムブラウザを使用するネイティブアプリの認可リクエストは、 より安全であり、デバイス上のユーザーの認証状態を活用できます。 ブラウザ内の既存の認証セッションを使用できることで、シングルサインオンが 可能になります。ユーザーは、新しいアプリを使用するたびに 認可サーバーへ認証する必要がないためです(認可サーバーのポリシーで 要求される場合を除く)。

ネイティブアプリとブラウザの間の認可フローをサポートすることは、 OAuth プロトコル自体を変更せずに可能です。OAuth 認可リクエストおよび レスポンスは、すでに URI の観点で定義されているためです。 これには、アプリ間通信に使用できる URI も含まれます。すべての クライアントが confidential web client であると仮定している一部の OAuth サーバー実装では、このベストプラクティスをサポートするために、 public native app client と、それらが使用する redirect URI の種類を 理解する必要があります。

8.1. ネイティブアプリの クライアント認証

複数のユーザーへ配布されるアプリの一部として静的に含まれる シークレットは、機密シークレットではありません。なぜなら、ある ユーザーが自分のコピーを調査して共有シークレットを知る可能性が あるからです。このため、認可サーバーは、共有シークレットを使用して ネイティブアプリクライアントのクライアント認証を要求してはなりません (MUST NOT)。 これは、client_id リクエストパラメーターによってすでに提供されている クライアント識別を超える価値を持たないためです。

ネイティブアプリクライアントに対して、静的に含まれる共有 シークレットをなお要求する認可サーバーは、そのクライアントを (Section 2.1 で定義される) public client として扱わなければならず (MUST)、そのシークレットを クライアントのアイデンティティの証明として受け入れてはなりません。 追加措置がなければ、そのようなクライアントはクライアントなりすましの 影響を受けます(Section 7.3.1 を参照)。

8.1.1. ネイティブアプリクライアントの 登録

Dynamic Client Registration [RFC7591] のような メカニズムを使用してインスタンスごとのクレデンシャルをプロビジョニングする場合を除き、 ネイティブアプリは Section 2.1 で定義される public client として分類され、そのようなものとして認可サーバーへ 登録されなければなりません (MUST)。認可サーバーは、リクエストを 適切に識別して処理するために、クライアント登録詳細にクライアント種別を 記録しなければなりません (MUST)。

8.1.2. ネイティブアプリ アテステーション

ドラフト仕様 [I-D.ietf-oauth-attestation-based-client-auth] は、ネイティブアプリが認可サーバーまたはリソースサーバーへ 認証するための鍵結合アテステーションを取得するために使用できる メカニズムを定義しています。これは、モバイルアプリのアイデンティティについて、 より高い保証レベルを提供できます。

8.2. ネイティブアプリにおける OAuth のための アプリ間 URI 通信の使用

Web 上の OAuth で、認可リクエストを開始し、 認可レスポンスを要求元 Web サイトへ返すために URI が使用されるのと同様に、 ネイティブアプリでも、デバイスのブラウザで認可リクエストを開始し、 レスポンスを要求元ネイティブアプリへ返すために URI を使用できます。

Web 上の OAuth で使用されるのと同じ方法を採用することで、 シングルサインオンセッションの使いやすさや、分離された認証コンテキストの セキュリティといった Web 文脈で見られる利点が、ネイティブアプリの 文脈でも同様に得られます。同じ方式を再利用することで、特定の プラットフォームに固有ではない標準ベースの Web フローに依存できるため、 実装の複雑さも軽減され、相互運用性も向上します。

ネイティブアプリは、OAuth 認可リクエストを実行するために 外部ユーザーエージェントを使用しなければなりません (MUST)。 これは、ブラウザで認可リクエストを開くこと (Section 8.3 で詳述) および認可レスポンスをネイティブアプリへ戻す redirect URI を使用すること (Section 8.4 で定義) によって達成されます。

8.3. ネイティブアプリからの 認可リクエストの開始

ユーザー認可を必要とするネイティブアプリは、 Section 4.1 に従って認可コードグラント種別を用い、 ネイティブアプリが受信可能な redirect URI を使用して認可リクエスト URI を 作成します。

ネイティブアプリ認可リクエストにおける redirect URI の機能は、 Web ベースの認可リクエストにおけるものと似ています。 OAuth クライアントのサーバーへ認可レスポンスを返す代わりに、 ネイティブアプリで使用される redirect URI はレスポンスをアプリへ返します。 異なるプラットフォームで認可レスポンスをネイティブアプリへ返すための redirect URI の選択肢は、Section 8.4 に文書化されています。 アプリが URI を受信し、そのパラメーターを調査できる任意の redirect URI は 利用可能です。

認可リクエスト URI を構築した後、アプリは プラットフォーム固有 API を使用して、その URI を外部ユーザーエージェントで 開きます。通常、使用される外部ユーザーエージェントはデフォルトブラウザ、 すなわちシステム上で http および https スキーム URI を処理するよう設定されたアプリケーションです。ただし、異なる ブラウザ選択基準や、その他のカテゴリの外部ユーザーエージェントを 使用してもよいです (MAY)。

このベストプラクティスは、ネイティブアプリに推奨される 外部ユーザーエージェントとしてブラウザに焦点を当てています。 ユーザー認可専用に設計され、ブラウザのように認可リクエストおよび レスポンスを処理できる外部ユーザーエージェントを使用してもよいです (MAY)。 認可サーバーによって提供されるネイティブアプリなど、その他の外部ユーザー エージェントも、同じ redirect URI 特性を使用することを含め、この ベストプラクティスで定められた基準を満たす場合がありますが、 それらの使用はこの仕様の範囲外です。

一部のプラットフォームは "in-app browser tabs" と呼ばれる ブラウザ機能をサポートしており、アプリはアプリの文脈内でブラウザの タブを提示できます。アプリを切り替えることなく、共有認証状態や セキュリティコンテキストなど、ブラウザの主要な利点を保持できます。 それらがサポートされているプラットフォームでは、使いやすさの理由から、 アプリが認可リクエストに in-app browser tabs を使用することが 推奨されます (RECOMMENDED)。

8.4. ネイティブアプリにおける 認可レスポンスの受信

ネイティブアプリがブラウザから認可レスポンスを受け取るために 利用可能な redirect URI の選択肢はいくつかあり、それらの利用可能性および ユーザー体験はプラットフォームによって異なります。

8.4.1. Claimed "https" スキーム URI リダイレクション

一部のオペレーティングシステム、特にモバイル オペレーティングシステムでは、アプリが自分たちの制御するドメイン内で https URI (Section 4.2.2 of [RFC9110] を参照) を claim できます。ブラウザが claimed URI に遭遇すると、 ページをブラウザで読み込む代わりに、ネイティブアプリが 起動され、その URI が起動パラメーターとして渡されます。

そのような URI は、ネイティブアプリによって redirect URI として 使用できます。それらは認可サーバーにとって、通常の Web ベース クライアントの redirect URI と区別できません。例を示します:

https://app.example.com/oauth2redirect/example-provider

redirect URI だけでは public native app client と confidential web client を区別するには不十分であるため、 Section 8.1.1 では、 サーバーがクライアント種別を判断し、それに応じて動作できるように、 クライアント登録時にクライアント種別を記録することが REQUIRED です。

App-claimed https スキーム redirect URI は、 他のネイティブアプリ用 redirect 選択肢と比べて、宛先アプリの アイデンティティがオペレーティングシステムによって認可サーバーへ 保証されるという利点があります。このため、ネイティブアプリは 可能な場合、他の選択肢よりもそれらを使用するべきです (SHOULD)。

8.4.2. ループバック インターフェイスリダイレクション

特別な権限なしにループバックネットワーク インターフェイス上でポートを開くことができるネイティブアプリ (通常はデスクトップオペレーティングシステム上のもの)は、 OAuth redirect を受信するためにループバックインターフェイスを 使用できます。

ループバック redirect URI は http スキームを使用し、 ループバック IP リテラルと、クライアントが待ち受けている任意のポートで 構築されます。

すなわち、IPv4 では http://127.0.0.1:{port}/{path}、 IPv6 では http://[::1]:{port}/{path} です。ランダムに割り当てられたポートを 使用した IPv4 ループバックインターフェイスによる redirect の例:

http://127.0.0.1:51004/oauth2redirect/example-provider

ランダムに割り当てられたポートを使用した IPv6 ループバックインターフェイスによる redirect の例:

http://[::1]:61023/oauth2redirect/example-provider

localhost という名前を使用する redirect URI (すなわち http://localhost:{port}/{path})は、ループバック IP redirect と同様に機能しますが、localhost の使用は 推奨されません (NOT RECOMMENDED)。localhost ではなく ループバック IP リテラルを持つ redirect URI を指定することで、 誤ってループバックインターフェイス以外のネットワーク インターフェイスで待ち受けることを避けられます。また、ユーザーの デバイス上のクライアント側ファイアウォールや誤設定されたホスト名解決の 影響を受けにくくなります。

認可サーバーは、ループバック IP redirect URI について、 クライアントがリクエスト時にオペレーティングシステムから利用可能な 一時ポートを取得することに対応するため、リクエスト時に任意のポートが 指定されることを許可しなければなりません (MUST)。

クライアントは、デバイスが特定のバージョンの Internet Protocol をサポートしていると仮定するべきではありません (SHOULD NOT)。 クライアントは IPv4 と IPv6 の両方を使用してループバック インターフェイスへのバインドを試み、利用可能な方を使用することが 推奨されます (RECOMMENDED)。

8.4.3. Private-Use URI スキームリダイレクション

多くのモバイルおよびデスクトップコンピューティング プラットフォームは、アプリが com.example.app のような private-use URI スキーム(俗に "custom URL schemes" と呼ばれることもあります)を 登録できるようにすることで、URI を介したアプリ間通信をサポートしています。 ブラウザまたは別のアプリが private-use URI スキームを持つ URI を 読み込もうとすると、それを登録したアプリがリクエストを処理するために 起動されます。

private-use URI スキームをサポートする多くの環境では、 スキームを claim し、他の当事者が別のアプリケーションのスキームを 使用することを防ぐメカニズムが提供されていません。そのため、 private-use URI スキームを使用するクライアントは、自分たちの redirect URI に対する潜在的な攻撃に脆弱です。したがって、この選択肢は、 前述のより安全な選択肢が利用できない場合にのみ使用されるべきです。

private-use URI スキーム redirect を使用して認可リクエストを 実行するために、ネイティブアプリは標準的な認可リクエストを用いて ブラウザを起動します。ただし、その redirect URI は、オペレーティング システムに登録した private-use URI スキームを利用します。

アプリに関連付ける URI スキームを選択する際、アプリは、 private-use URI スキームについて Section 3.8 of [RFC7595] で 推奨されるように、自分たちの制御下にあるドメイン名に基づき、 逆順で表された URI スキームを使用しなければなりません (MUST)。

たとえば、ドメイン名 app.example.com を制御するアプリは、そのスキームとして com.example.app を 使用できます。一部の認可サーバーは、たとえば client1234.usercontent.example.net のように、ドメイン名に基づいて クライアント識別子を割り当てます。これは、同じ方法で逆順にした場合、 スキームのドメイン名としても使用できます。しかし、 myapp のようなスキームは、ドメイン名に基づいていないため、 この要件を満たしません。

同じ発行者による複数のアプリがある場合、 各スキームがそのグループ内で一意になるよう注意しなければなりません。 逆順ドメイン名に基づくアプリ識別子を使用するプラットフォームでは、 この問題を避けるために、それらの識別子を OAuth redirect 用の private-use URI スキームとして再利用できます。

Section 3.2 of [RFC3986] の 要件に従い、private-use URI スキーム redirect には命名機関がないため、 スキームコンポーネントの後には単一のスラッシュ(/)だけが 現れます。private-use URI スキームを利用する完全な redirect URI の例は 次のとおりです:

com.example.app:/oauth2redirect/example-provider

認可サーバーがリクエストを完了すると、通常どおり クライアントの redirect URI へリダイレクトします。 redirect URI は private-use URI スキームを使用しているため、 その結果、オペレーティングシステムがネイティブアプリを起動し、 URI を起動パラメーターとして渡します。その後、ネイティブアプリは 認可レスポンスの通常の処理を使用します。

8.5. ネイティブアプリにおける セキュリティ上の考慮事項

8.5.1. ネイティブアプリにおける 埋め込みユーザーエージェント

埋め込みユーザーエージェントは、ネイティブアプリを 認可するための技術的には可能な方法です。これらの埋め込みユーザー エージェントは、認可サーバーに対する第三者による使用には、 定義上安全ではありません。埋め込みユーザーエージェントをホストする アプリは、そのアプリのために意図された OAuth 認可グラントだけでなく、 ユーザーの完全な認証クレデンシャルにアクセスできるためです。 また通常、オペレーティングシステムによってサンドボックス化されており、 Web origin に依存する WebAuthn などのメカニズムは無効化されます。

Web ビューに基づく埋め込みユーザーエージェントの典型的な実装では、 ホストアプリケーションはログインフォームに入力されたすべてのキー入力を 記録してユーザー名とパスワードを取得し、ユーザー同意を回避するために フォームを自動送信し、セッション Cookie をコピーしてユーザーとして 認証済みアクションを実行できます。

認可サーバーと同じ当事者に属する信頼されたアプリで 使用される場合であっても、埋め込みユーザーエージェントは、 必要以上に強力なクレデンシャルへアクセスできるため、最小権限の原則に 違反し、攻撃面を増加させる可能性があります。

ブラウザが持つ通常のアドレスバーや可視の証明書検証機能なしに、 埋め込みユーザーエージェントでユーザーにクレデンシャルを入力するよう 促すことは、ユーザーが正当なサイトにサインインしているかどうかを 知ることを不可能にします。たとえ正当なサイトであっても、サイトを 先に検証せずにクレデンシャルを入力してもよいという行動を ユーザーに学習させてしまいます。

セキュリティ上の懸念に加えて、埋め込みユーザーエージェントは 認証状態を他のアプリやブラウザと共有しないため、ユーザーは各 認可リクエストごとにログインする必要があり、これはしばしば劣った ユーザー体験と見なされます。

8.5.2. ネイティブアプリにおける 偽の外部ユーザーエージェント

認可リクエストを開始しているネイティブアプリは、 ユーザーインターフェイスに対して大きな制御権を持っており、 偽の外部ユーザーエージェント、すなわち外部ユーザーエージェントに 見えるよう作られた埋め込みユーザーエージェントを提示できる可能性があります。

すべての善意のアクターが外部ユーザーエージェントを 使用している場合の利点は、セキュリティ専門家が悪意あるアクターを 検出できることです。外部ユーザーエージェントを偽装している者は、 証明可能に悪意があるためです。一方、善意のアクターも悪意あるアクターも 同様に埋め込みユーザーエージェントを使用している場合、悪意あるアクターは 何も偽装する必要がなくなり、検出が困難になります。 悪意あるアプリが検出された後は、この知識を用いてマルウェアスキャン ソフトウェアでアプリの署名をブラックリスト登録し、(アプリストアで 配布されているアプリの場合は)削除措置を講じ、悪意あるアプリの影響と 拡散を減らすためのその他の手段を取ることが可能な場合があります。

認可サーバーは、真の外部ユーザーエージェントでのみ 利用可能な認証要素を要求することにより、偽の外部ユーザーエージェントに 直接対抗することもできます。

in-app browser tabs を使用する際にセキュリティを特に懸念する ユーザーは、追加の手段として、in-app browser tab からフルブラウザで リクエストを開き、そこで認可を完了することもできます。 in-app browser tab パターンのほとんどの実装は、そのような機能を 提供しているためです。

8.5.3. ネイティブアプリにおける 悪意ある外部ユーザーエージェント

悪意あるアプリがオペレーティングシステム内で https スキーム URI のデフォルトハンドラーとして 自分自身を設定できる場合、デフォルトブラウザを使用する認可リクエストを 傍受し、この信頼された位置をフィッシングなどの悪意ある目的に 悪用できます。

この攻撃は OAuth に限定されません。このように設定された 悪意あるアプリは、ネイティブアプリによる OAuth 使用を超えて、 ユーザーに対する一般的かつ継続的なリスクをもたらします。 多くのオペレーティングシステムは、http および https スキーム URI のデフォルトハンドラーを変更するために、明示的な ユーザー操作を要求することで、この問題を軽減しています。

8.5.4. ネイティブアプリにおける ループバック redirect の考慮事項

ループバックインターフェイス redirect URI は http スキーム(すなわち TLS なし)を使用してもよいです (MAY)。 HTTP リクエストがデバイスから出ないため、これはループバック インターフェイス redirect URI では許容されます。

クライアントは、認可リクエストを開始するときだけ ネットワークポートを開き、レスポンスが返されたらそれを閉じるべきです (SHOULD)。

クライアントは、他のネットワークアクターによる干渉を 避けるため、ループバックネットワークインターフェイスのみで 待ち受けるべきです (SHOULD)。

クライアントは、Section 8.4.2 で説明されるように、 文字列 localhost ではなくループバック IP リテラルを 使用するべきです (SHOULD)。

9. ブラウザベースアプリ

ブラウザベースアプリとは、Web ブラウザ内で実行されるクライアントであり、 通常は JavaScript で記述され、"single-page apps" としても知られています。 この種のアプリには、ネイティブアプリと同様の特有のセキュリティ上の考慮事項があります。

TODO: ブラウザベースアプリ BCP が最終化された時点で、その規範的テキストを取り込む。

10. OAuth 2.0 との差異

このドラフトは、OAuth 2.0 [RFC6749]、 OAuth 2.0 for Native Apps [RFC8252]、 Proof Key for Code Exchange [RFC7636]、 OAuth 2.0 for Browser-Based Apps [I-D.ietf-oauth-browser-based-apps]、 OAuth Security Best Current Practice [RFC9700]、 および Bearer Token Usage [RFC6750] の 機能を統合しています。

後続のドラフトが元の [RFC6749] に見られる機能を 更新または廃止する場合、このドラフト内のその機能は、後続ドラフトで説明される 規範的変更によって更新されるか、完全に削除されます。

OAuth 2.0 からの変更点の非規範的な一覧を以下に示します:

10.1. OAuth 2.0 Implicit grant の削除

OAuth 2.0 Implicit grant は、 [RFC9700] で非推奨化されたため、 OAuth 2.1 から省略されています。

Implicit grant を削除する意図は、認可レスポンスで アクセストークンを発行しないようにすることです。そのようなトークンは 漏えいおよびインジェクションに脆弱であり、クライアントへ送信者制約することが できないためです。この動作は、クライアントが response_type=token パラメーターを使用することによって示されていました。 response_type パラメーターのこの値は、OAuth 2.1 ではもはや 定義されていません。

response_type=token の削除は、 認可エンドポイントから他の成果物を返す他の拡張レスポンス種別には 影響しません。たとえば、[OpenID.Connect] で定義される response_type=id_token などです。

10.2. トークンリクエストにおける Redirect URI パラメーター

OAuth 2.0 では、認可コードフローにおけるトークンエンドポイントへの リクエスト(Section 4.1.3 of [RFC6749])は、 任意の redirect_uri パラメーターを含みます。このパラメーターは 認可コードインジェクション攻撃を防ぐことを意図しており、元の 認可リクエストで redirect_uri パラメーターが送信された場合に 必須でした。認可リクエストは、特定のクライアントに複数の redirect URI が 登録されている場合にのみ、redirect_uri パラメーターを要求していました。 しかし実際には、多くの認可サーバー実装が、登録されているものが 1 つだけで あっても認可リクエストで redirect_uri パラメーターを要求していたため、 redirect_uri パラメーターはトークンエンドポイントでも必須になりました。

OAuth 2.1 では、認可コードインジェクションは code_challenge および code_verifier パラメーターによって 防止されるため、トークンリクエストに redirect_uri パラメーターを 含めることは目的を持ちません。そのため、これは削除されました。

OAuth 2.0 と OAuth 2.1 の両方のクライアントをサポートしたい 認可サーバーの後方互換性のために、認可サーバーは、クライアントが トークンリクエスト(Section 4.1.3)で redirect_uri パラメーターを送信することを許可しなければならず (MUST)、 [RFC6749] で説明されるように そのパラメーターを強制しなければなりません (MUST)。認可サーバーは、 リクエスト内の client_id を使用して、古い OAuth 2.0 の動作を 使用することがわかっている特定のクライアントに対してこの動作を 強制するかどうかを判断できます。

OAuth 2.1 の推奨事項のみに従うクライアントは、 トークンリクエストで redirect_uri を送信しません。 したがって、トークンリクエストでそのパラメーターを期待する認可サーバーとは 互換性がありません。

11. IANA に関する考慮事項

この文書は、いかなる IANA アクションも必要としません。

参照されるすべてのレジストリは、 [RFC6749] およびこの作業の基礎となる関連文書によって 定義されています。この仕様では、それらのレジストリに対する変更は必要ありません。

12. 参考文献

12.1. 規範参考文献

[BCP195]
Saint-Andre, P., "Transport Layer Security (TLS) の安全な使用に関する推奨事項", .
[RFC2119]
Bradner, S., "RFC において 要求レベルを示すために使用するキーワード", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC2617]
Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, DOI 10.17487/RFC2617, , <https://www.rfc-editor.org/info/rfc2617>.
[RFC3629]
Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, , <https://www.rfc-editor.org/info/rfc3629>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC4949]
Shirey, R., "Internet Security Glossary, Version 2", FYI 36, RFC 4949, DOI 10.17487/RFC4949, , <https://www.rfc-editor.org/info/rfc4949>.
[RFC5234]
Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, , <https://www.rfc-editor.org/info/rfc5234>.
[RFC6749]
Hardt, D., Ed., "OAuth 2.0 認可フレームワーク", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC6750]
Jones, M. and D. Hardt, "OAuth 2.0 認可フレームワーク: Bearer Token Usage", RFC 6750, DOI 10.17487/RFC6750, , <https://www.rfc-editor.org/info/rfc6750>.
[RFC7235]
Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Authentication", RFC 7235, DOI 10.17487/RFC7235, , <https://www.rfc-editor.org/info/rfc7235>.
[RFC7521]
Campbell, B., Mortimore, C., Jones, M., and Y. Goland, "Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants", RFC 7521, DOI 10.17487/RFC7521, , <https://www.rfc-editor.org/info/rfc7521>.
[RFC7523]
Jones, M., Campbell, B., and C. Mortimore, "JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants", RFC 7523, DOI 10.17487/RFC7523, , <https://www.rfc-editor.org/info/rfc7523>.
[RFC7595]
Thaler, D., Ed., Hansen, T., and T. Hardie, "URI スキームの 指針および登録手順", BCP 35, RFC 7595, DOI 10.17487/RFC7595, , <https://www.rfc-editor.org/info/rfc7595>.
[RFC8174]
Leiba, B., "RFC 2119 キーワードにおける 大文字と小文字の曖昧性", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8252]
Denniss, W. and J. Bradley, "OAuth 2.0 for Native Apps", BCP 212, RFC 8252, DOI 10.17487/RFC8252, , <https://www.rfc-editor.org/info/rfc8252>.
[RFC8259]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC8446]
Rescorla, E., "Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, , <https://www.rfc-editor.org/info/rfc8446>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC9111]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Caching", STD 98, RFC 9111, DOI 10.17487/RFC9111, , <https://www.rfc-editor.org/info/rfc9111>.
[RFC9207]
Meyer zu Selhausen, K. and D. Fett, "OAuth 2.0 Authorization Server Issuer Identification", RFC 9207, DOI 10.17487/RFC9207, , <https://www.rfc-editor.org/info/rfc9207>.
[RFC9700]
Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, "OAuth 2.0 セキュリティに関する Best Current Practice", BCP 240, RFC 9700, DOI 10.17487/RFC9700, , <https://www.rfc-editor.org/info/rfc9700>.
[USASCII]
Institute, A. N. S., "Coded Character Set -- 7-bit American Standard Code for Information Interchange, ANSI X3.4", .
[W3C.REC-xml-20081126]
Bray, T., Paoli, J., Sperberg-McQueen, C. M., Maler, E., and F. Yergeau, "Extensible Markup Language", , <https://www.w3.org/TR/REC-xml/REC-xml-20081126.xml>.
[WHATWG.CORS]
WHATWG, "Fetch Standard: CORS protocol", , <https://fetch.spec.whatwg.org/#http-cors-protocol>.
[WHATWG.URL]
WHATWG, "URL", , <https://url.spec.whatwg.org/>.

12.2. 参考情報文献

[CSP-2]
"Content Security Policy Level 2", , <https://www.w3.org/TR/CSP2>.
[I-D.bradley-oauth-jwt-encoded-state]
Bradley, J., Lodderstedt, T., and H. Zandbelt, "Encoding claims in the OAuth 2 state parameter using a JWT", 作業中, Internet-Draft, draft-bradley-oauth-jwt-encoded-state-09, , <https://datatracker.ietf.org/doc/html/draft-bradley-oauth-jwt-encoded-state-09>.
[I-D.ietf-oauth-attestation-based-client-auth]
Looker, T., Bastian, P., and C. Bormann, "OAuth 2.0 Attestation-Based Client Authentication", 作業中, Internet-Draft, draft-ietf-oauth-attestation-based-client-auth-07, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-attestation-based-client-auth-07>.
[I-D.ietf-oauth-browser-based-apps]
Parecki, A., De Ryck, P., and D. Waite, "OAuth 2.0 for Browser-Based Applications", 作業中, Internet-Draft, draft-ietf-oauth-browser-based-apps-26, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps-26>.
[I-D.ietf-oauth-rfc7523bis]
Jones, M. B., Campbell, B., Mortimore, C., and F. Skokan, "Updates to OAuth 2.0 JSON Web Token (JWT) Client Authentication and Assertion-Based Authorization Grants", 作業中, Internet-Draft, draft-ietf-oauth-rfc7523bis-05, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-rfc7523bis-05>.
[NIST800-63]
Burr, W., Dodson, D., Newton, E., Perlner, R., Polk, T., Gupta, S., and E. Nabbus, "NIST Special Publication 800-63-1, INFORMATION SECURITY", , <http://csrc.nist.gov/publications/>.
[OMAP]
Huff, J., Schlacht, D., Nadalin, A., Simmons, J., Rosenberg, P., Madsen, P., Ace, T., Rickelton-Abdi, C., and B. Boyer, "Online Multimedia Authorization Protocol: An Industry Standard for Authorized Access to Internet Multimedia Resources", , <https://www.svta.org/product/online-multimedia-authorization-protocol/>.
[OpenID.Connect]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0 incorporating errata set 2", , <https://openid.net/specs/openid-connect-core-1_0.html>.
[OpenID.Discovery]
Sakimura, N., Bradley, J., Jones, M., and E. Jay, "OpenID Connect Discovery 1.0 incorporating errata set 2", , <https://openid.net/specs/openid-connect-discovery-1_0.html>.
[OpenID.Messages]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., Mortimore, C., and E. Jay, "OpenID Connect Messages 1.0", , <http://openid.net/specs/openid-connect-messages-1_0.html>.
[owasp_redir]
"OWASP Cheat Sheet Series - Unvalidated Redirects and Forwards", , <https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html>.
[RFC6265]
Barth, A., "HTTP State Management Mechanism", RFC 6265, DOI 10.17487/RFC6265, , <https://www.rfc-editor.org/info/rfc6265>.
[RFC6819]
Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 Threat Model and Security Considerations", RFC 6819, DOI 10.17487/RFC6819, , <https://www.rfc-editor.org/info/rfc6819>.
[RFC7009]
Lodderstedt, T., Ed., Dronia, S., and M. Scurtescu, "OAuth 2.0 Token Revocation", RFC 7009, DOI 10.17487/RFC7009, , <https://www.rfc-editor.org/info/rfc7009>.
[RFC7519]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, , <https://www.rfc-editor.org/info/rfc7519>.
[RFC7591]
Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and P. Hunt, "OAuth 2.0 Dynamic Client Registration Protocol", RFC 7591, DOI 10.17487/RFC7591, , <https://www.rfc-editor.org/info/rfc7591>.
[RFC7592]
Richer, J., Ed., Jones, M., Bradley, J., and M. Machulak, "OAuth 2.0 Dynamic Client Registration Management Protocol", RFC 7592, DOI 10.17487/RFC7592, , <https://www.rfc-editor.org/info/rfc7592>.
[RFC7636]
Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key for Code Exchange by OAuth Public Clients", RFC 7636, DOI 10.17487/RFC7636, , <https://www.rfc-editor.org/info/rfc7636>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 Token Introspection", RFC 7662, DOI 10.17487/RFC7662, , <https://www.rfc-editor.org/info/rfc7662>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 Authorization Server Metadata", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.
[RFC8628]
Denniss, W., Bradley, J., Jones, M., and H. Tschofenig, "OAuth 2.0 Device Authorization Grant", RFC 8628, DOI 10.17487/RFC8628, , <https://www.rfc-editor.org/info/rfc8628>.
[RFC8705]
Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens", RFC 8705, DOI 10.17487/RFC8705, , <https://www.rfc-editor.org/info/rfc8705>.
[RFC8707]
Campbell, B., Bradley, J., and H. Tschofenig, "Resource Indicators for OAuth 2.0", RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.
[RFC9068]
Bertocci, V., "JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens", RFC 9068, DOI 10.17487/RFC9068, , <https://www.rfc-editor.org/info/rfc9068>.
[RFC9126]
Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., and F. Skokan, "OAuth 2.0 Pushed Authorization Requests", RFC 9126, DOI 10.17487/RFC9126, , <https://www.rfc-editor.org/info/rfc9126>.
[RFC9396]
Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0 Rich Authorization Requests", RFC 9396, DOI 10.17487/RFC9396, , <https://www.rfc-editor.org/info/rfc9396>.
[RFC9449]
Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, DOI 10.17487/RFC9449, , <https://www.rfc-editor.org/info/rfc9449>.
[RFC9470]
Bertocci, V. and B. Campbell, "OAuth 2.0 Step Up Authentication Challenge Protocol", RFC 9470, DOI 10.17487/RFC9470, , <https://www.rfc-editor.org/info/rfc9470>.
[W3C.REC-html401-19991224]
Hors, A. L., Ed., Raggett, D., Ed., and I. Jacobs, Ed., "HTML 4.01 Specification", W3C REC REC-html401-19991224, W3C REC-html401-19991224, , <https://www.w3.org/TR/1999/REC-html401-19991224/>.

Appendix A. Augmented Backus-Naur Form (ABNF) 構文

この節は、[RFC5234] の 記法を使用して、この仕様で定義される要素の Augmented Backus-Naur Form (ABNF) 構文記述を提供します。以下の ABNF は、Unicode コードポイント [W3C.REC-xml-20081126] の観点で定義されています。これらの文字は通常 UTF-8 でエンコードされます。 要素は最初に定義される順序で提示されます。

以下の定義の一部は、 [RFC3986] からの "URI-reference" 定義を使用します。

以下の定義の一部は、これらの共通定義を使用します:

VSCHAR     = %x20-7E
NQCHAR     = %x21 / %x23-5B / %x5D-7E
NQSCHAR    = %x20-21 / %x23-5B / %x5D-7E

A.1. "client_id" 構文

client_id 要素は Section 2.4.1 で定義されます:

client-id     = *VSCHAR

A.2. "client_secret" 構文

client_secret 要素は Section 2.4.1 で定義されます:

client-secret = *VSCHAR

A.3. "response_type" 構文

response_type 要素は Section 4.1.1 および Section 6.4 で定義されます:

response-type = response-name *( SP response-name )
response-name = 1*response-char
response-char = "_" / DIGIT / ALPHA

A.4. "scope" 構文

scope 要素は Section 1.4.1 で定義されます:

 scope       = scope-token *( SP scope-token )
 scope-token = 1*NQCHAR

A.5. "state" 構文

state 要素は Section 4.1.1Section 4.1.2、および Section 4.1.2.1 で定義されます:

 state      = 1*VSCHAR

A.6. "redirect_uri" 構文

redirect_uri 要素は Section 4.1.1 および Section 4.1.3 で定義されます:

 redirect-uri      = URI-reference

A.7. "error" 構文

error 要素は、Sections Section 4.1.2.1Section 3.2.4、 および Section 5.3 で定義されます:

 error             = 1*NQSCHAR

A.8. "error_description" 構文

error_description 要素は、Sections Section 4.1.2.1Section 3.2.4、および Section 5.3 で定義されます:

 error-description = 1*NQSCHAR

A.9. "error_uri" 構文

error_uri 要素は、Sections Section 4.1.2.1Section 3.2.4、 および Section 5.3 で定義されます:

 error-uri         = URI-reference

A.10. "grant_type" 構文

grant_type 要素は Section Section 3.2.2 で定義されます:

 grant-type = grant-name / URI-reference
 grant-name = 1*name-char
 name-char  = "-" / "." / "_" / DIGIT / ALPHA

A.11. "code" 構文

code 要素は Section 4.1.3 で定義されます:

 code       = 1*VSCHAR

A.12. "access_token" 構文

access_token 要素は Section 3.2.3 で定義されます:

 access-token = 1*VSCHAR

A.13. "token_type" 構文

token_type 要素は Section 3.2.3 および Section 6.1 で定義されます:

 token-type = type-name / URI-reference
 type-name  = 1*name-char
 name-char  = "-" / "." / "_" / DIGIT / ALPHA

A.14. "expires_in" 構文

expires_in 要素は Section 3.2.3 で定義されます:

 expires-in = 1*DIGIT

A.15. "refresh_token" 構文

refresh_token 要素は Section 3.2.3 および Section 4.3 で定義されます:

 refresh-token = 1*VSCHAR

A.16. エンドポイントパラメーター 構文

新しいエンドポイントパラメーターの構文は Section 6.2 で定義されます:

 param-name = 1*name-char
 name-char  = "-" / "." / "_" / DIGIT / ALPHA

A.17. "code_verifier" 構文

code_verifier の ABNF は次のとおりです。

code-verifier = 43*128unreserved
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA = %x41-5A / %x61-7A
DIGIT = %x30-39

A.18. "code_challenge" 構文

code_challenge の ABNF は次のとおりです。

code-challenge = 43*128unreserved
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA = %x41-5A / %x61-7A
DIGIT = %x30-39

Appendix B. application/x-www-form-urlencoded メディアタイプの使用

[RFC6749] の公表時点で、 application/x-www-form-urlencoded メディアタイプは [W3C.REC-html401-19991224] の Section 17.13.4 で 定義されていましたが、IANA MIME Media Types レジストリ (http://www.iana.org/assignments/media-types) には登録されていませんでした。さらに、その定義は不完全であり、非 US-ASCII 文字を考慮していません。

このメディアタイプを使用してコンテンツを生成する際に この欠点に対処するため、名前と値はまず UTF-8 文字エンコーディング方式 [RFC3629] を使用して エンコードされなければなりません (MUST)。その結果のオクテット列は、その後 [W3C.REC-html401-19991224] で 定義されるエスケープ規則を使用してさらにエンコードされる必要があります。

このメディアタイプを使用するコンテンツからデータを解析する場合、 名前/値エンコーディングを逆にした結果として得られる名前と値は、 UTF-8 文字エンコーディング方式を使用してデコードされるべきオクテット列として 扱う必要があります。

たとえば、6 つの Unicode コードポイント (1) U+0020 (SPACE)、(2) U+0025 (PERCENT SIGN)、 (3) U+0026 (AMPERSAND)、(4) U+002B (PLUS SIGN)、 (5) U+00A3 (POUND SIGN)、および (6) U+20AC (EURO SIGN) からなる値は、 (16 進表記を使用して)以下のオクテット列にエンコードされます:

20 25 26 2B C2 A3 E2 82 AC

そして、コンテンツ内では次のように表されます:

+%25%26%2B%C2%A3%E2%82%AC

Appendix C. シリアル化

この仕様のさまざまなメッセージは、以下で説明されるいずれかの方法を使用して シリアル化されます。この節では、これらのシリアル化方法の構文を説明します。 他の節では、それらをいつ使用でき、いつ使用しなければならないかを説明します。 すべての方法がすべてのメッセージに使用できるわけではないことに注意してください。

C.1. クエリ文字列 シリアル化

Query String Serialization を使用してパラメーターを シリアル化するために、Client は、[WHATWG.URL] で定義される application/x-www-form-urlencoded 形式を使用して、URL のクエリコンポーネントに パラメーターと値を追加することにより文字列を構築します。Query String Serialization は 通常 HTTP GET リクエストで使用されます。

C.2. Form-Encoded シリアル化

パラメーターとその値は、Appendix B で定義される application/x-www-form-urlencoded 形式を使用して、HTTP リクエストのエンティティボディへ パラメーター名と値を追加することにより Form Serialized されます。 Form Serialization は通常 HTTP POST リクエストで使用されます。

C.3. JSON シリアル化

パラメーターは、各パラメーターを最上位の構造レベルに 追加することで、JSON [RFC8259] オブジェクト構造へシリアル化されます。 パラメーター名と文字列値は JSON 文字列として表されます。 数値は JSON number として表されます。Boolean 値は JSON boolean として 表されます。省略されたパラメーター、および値を持たないパラメーターは、 別段の指定がない限り、オブジェクトから省略されるべきであり (SHOULD)、 JSON null 値として表されるべきではありません。パラメーターは値として JSON オブジェクトまたは JSON 配列を持ってもよいです (MAY)。 パラメーターの順序は重要ではなく、変化する可能性があります。

Appendix D. 拡張

公表時点で十分に確立されている拡張の一覧を以下に示します:

Appendix E. 謝辞

この仕様は OAuth Working Group の作業であり、その出発点は 次の仕様の内容に基づいていました: OAuth 2.0 Authorization Framework (RFC 6749)、 OAuth 2.0 for Native Apps (RFC 8252)、OAuth Security Best Current Practice、および OAuth 2.0 for Browser-Based Apps。編集者は、これが構築される基礎となったそれらの仕様の作成に 関与したすべての人に感謝します。

編集者はまた、この版の仕様を形作るのに役立ったアイデア、 フィードバック、修正、および文言を提供してくれた次の個人にも感謝します: Andrii Deinega, Bob Hamburg, Brian Campbell, Daniel Fett, Deng Chao, Emelia Smith, Falko, Filip Skokan, Joseph Heenan, Justin Richer, Karsten Meyer zu Selhausen, Michael Jones, Michael Peck, Roberto Polli, Tim Würtele and Vittorio Bertocci。

この仕様に関する議論は、2021 年および 2022 年の OAuth Security Workshop でも行われました。著者は、共同作業とコミュニティからの入力に資するイベントを 主催したワークショップの主催者(Guido Schmitz、Steinar Noem、および Daniel Fett)に感謝します。

Appendix F. 文書履歴

[[ 最終仕様から削除される予定 ]]

-15

-14

-13

-12

-11

-10

-09

-08

-07

-06

-05

-04

-03

-02

-01

-00

著者の住所

Dick Hardt
Hellō
Aaron Parecki
Okta
Torsten Lodderstedt
SPRIND