インターネットドラフト OAuth 2.1 認可フレームワーク 2026年9月
Hardt ほか 2027年3月7日失効 [ページ]
作業部会:
OAuth 作業部会
インターネットドラフト:
draft-ietf-oauth-v2-1-16
公開日:
予定ステータス:
標準化過程
失効日:
著者:
D. Hardt
Hellō
A. Parecki
Okta
T. Lodderstedt
SPRIND

OAuth 2.1 認可フレームワーク

概要

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

議論の場

この注記は、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か月間有効なドラフト文書であり、 いつでも他の文書によって更新、置換、または廃止されることが あります。インターネットドラフトを参考 資料として使用したり、「作業中」以外のものとして引用したりすることは適切ではありません。

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

▲

目次

1. はじめに

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

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

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

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

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

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

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

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

2012年10月に OAuth 2.0 認可フレームワーク [RFC6749] が公開されて以来、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] によって更新されてきました。 OAuth 2.0 Authorization Framework: Bearer Token Usage [RFC6750] も [RFC9700] によって更新されています。この 標準化過程の仕様は、これらすべての文書の情報を統合し、 [RFC9700] で安全でないことが判明した機能を 削除します。

1.1. 役割

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

「リソース所有者」:

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

「リソースサーバー」:

保護されたリソースをホストし、アクセストークンを使用して 保護されたリソースへのリクエストを受け付け、 応答できるサーバーです。リソースサーバーは多くの場合 API を介してアクセスできます。 「RS」と略されることもあります。

「クライアント」:

リソース所有者に代わり、その認可を得て 保護されたリソースへのリクエストを行うアプリケーションです。「クライアント」という用語は、 特定の実装特性(たとえば、 アプリケーションがサーバー、デスクトップ、その他の デバイスのいずれで実行されるか)を意味するものではありません。

「認可サーバー」:

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

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

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

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

リソース所有者がエンドユーザーである場合、ユーザーは クライアントと対話します。クライアントが Web ベースのアプリケーションである場合、ユーザーは ユーザーエージェント(3.5節 of [RFC9110] で説明されているもの)を介してクライアントと対話します。 クライアントがネイティブアプリケーションである場合、ユーザーは オペレーティングシステムを介してクライアントと直接対話します。詳細については 2.1節 を参照してください。

1.2. プロトコルフロー

     +--------+                               +---------------+
     |        |--(1)---- 認可リクエスト ----->|   リソース    |
     |        |                               |    所有者     |
     |        |<-(2)------ 認可グラント ------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(3)------ 認可グラント ----->|     認可      |
     |クライアント|                             |    サーバー    |
     |        |<-(4)------ アクセストークン ----|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(5)------ アクセストークン --->|   リソース    |
     |        |                               |   サーバー     |
     |        |<-(6)------ 保護リソース -------|               |
     +--------+                               +---------------+
図 1: 抽象プロトコルフロー

図 1 に示す抽象的な OAuth 2.1 フローは、 4つの役割間の相互作用を説明し、次の手順を含みます。

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

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

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

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

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

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

クライアントがリソース所有者から認可グラントを取得する (手順 (1) と (2) に示される)望ましい方法は、 認可サーバーを仲介者として使用することであり、これは 4.1節 の 図 3 に示されています。

1.3. 認可グラント

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

1.3.1. 認可コード

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

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

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

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

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

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

+--------+                                           +---------------+
|        |--(1)-------- 認可グラント --------------->|               |
|        |                                           |               |
|        |<-(2)-------- アクセストークン -------------|               |
|        |               & リフレッシュトークン       |               |
|        |                                           |               |
|        |                            +----------+   |               |
|        |--(3)--- アクセストークン -->|          |   |               |
|        |                            |          |   |               |
|        |<-(4)--- 保護リソース -------| リソース |   |     認可      |
|クライアント|                         | サーバー  |   |    サーバー    |
|        |--(5)--- アクセストークン -->|          |   |               |
|        |                            |          |   |               |
|        |<-(6)-- 無効トークンエラー --|          |   |               |
|        |                            +----------+   |               |
|        |                                           |               |
|        |--(7)----- リフレッシュトークン ----------->|               |
|        |                                           |               |
|        |<-(8)-------- アクセストークン -------------|               |
+--------+        & 任意のリフレッシュトークン        +---------------+
図 2: 期限切れの アクセストークンの更新

図 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. アクセストークン

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

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

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

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

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

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

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

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

認可サーバーは、権限のない主体が 有効なアクセストークンを生成する目的で、アクセストークンを 生成、変更、または推測できないようにしなければなりません。

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

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

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

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

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

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

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

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

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

1.4.2. Bearer トークン

Bearer トークンは、そのトークンを所持する任意の主体 (「bearer」)が、他の任意の所持者と同じ方法で そのトークンを使用できるという特性を持つセキュリティトークンです。 Bearer トークンを使用する際、bearer が暗号鍵素材の所持を 証明する必要はありません(proof-of-possession)。

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

アクセストークンの漏えいを防ぐため、 クライアントとリソースサーバーの間の通信は、 1.5節 で説明されている 機密性および完全性の保護を使用しなければなりません。

Bearer トークンの特定の構造や形式に関する要件はありません。 Bearer トークンが認可情報への参照である場合、そのような参照は、 十分に長い暗号学的にランダムな文字列を使用するなど、攻撃者が推測することが 実行不可能でなければなりません。Bearer トークンが 認可情報をトークン自体に格納するエンコードメカニズムを使用する場合、 アクセストークンはトークンの変更を防止するのに十分な 完全性保護を使用しなければなりません。アクセストークンのエンコードおよび 署名メカニズムの一例は 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] など、 アクセストークンを送信者に制約するメカニズムを使用すべきです。 盗まれたまたは漏えいしたアクセストークンの悪用を防ぐため、 4.10.1節 of [RFC9700] を参照してください。

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

1.5. 通信セキュリティ

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

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

実装は、自身のセキュリティ要件を満たす追加のトランスポート層 セキュリティメカニズムをサポートしてもかまいません。

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

1.6. HTTP リダイレクト

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

1.7. 相互運用性

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

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

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

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

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

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

この公開時点で既知の拡張の一覧については、 付録 D を参照してください。

1.7.1. 値のサイズ

この仕様では、 client_id、認可コード、アクセストークン、リフレッシュトークン、 その他ほとんどのプロトコルパラメーターの最大長を定義していません。これらの値の長さは、 それらを発行する主体が選択する実装方法に依存するためです。 実際には、実装は独自の制限を設けており、 受信側実装の制限を超える値があると リクエストは失敗します。

実装は、受信した値が特定の長さに 収まると想定してはなりません。値を発行する主体は、その長さを 文書化し、それを運ぶ構成要素の制限を 考慮すべきです。特に、認可コードなど リダイレクトで返される値は URI クエリ文字列で運ばれ、 HTTP 実装では一般にリクエスト行および 個々のヘッダーフィールドの長さが制限されます(3節 of [RFC9112] および 5.4節 of [RFC9110])。 実装は、リクエストが 3節 of [RFC9112] で推奨される 8000オクテットのリクエスト行長以内に収まるのに十分な長さの パラメーター値をサポートすべきです。特にリソース サーバーは、アクセストークンの長さに小さな制限を設けるべきではありません。 [RFC9068] で定義されているような 構造化形式のトークンは、通常1キロバイトを超えるためです。

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 で制限されています。 たとえば、OAuth 2.1 ではリダイレクト URI の厳密な文字列一致が要求されます。

OAuth 2.0 との相違点の詳細については 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) 表記を使用します。さらに、規則 URI-reference は "Uniform Resource Identifier (URI): Generic Syntax" [RFC3986] から取り込まれています。

特定のセキュリティ関連用語は、 [RFC4949] で定義されている意味で理解されます。 これらの用語には、 "attack"、"authentication"、"authorization"、"certificate"、 "confidentiality"、"credential"、"encryption"、"identity"、"sign"、 "signature"、"trust"、"validate"、"verify" などがありますが、 これらに限定されません。

"content" という用語は、6.4節 of [RFC9110] で説明されているとおりに解釈されます。

"user agent" という用語は、3.5節 of [RFC9110] で説明されているとおりに解釈されます。

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

2. クライアント登録

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

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

クライアント登録には次を含めなければなりません。

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

2.1. クライアントタイプ

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

「confidential」:

AS に対するクレデンシャルを持つクライアントは、 「confidential クライアント」とされます。

「public」:

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

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

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

認可サーバーがクライアントまたはそのクライアントを 提供・運用する主体の身元を検証するかどうか、およびどのように検証するかは この仕様の範囲外です。 認可サーバーは、クライアントにより機密性の高いリソースや操作へのアクセス (Client Credentials グラントタイプなど)を許可するかどうか、およびユーザーに 同意を求める頻度を決定するとき、クライアントの身元に対する確信度を 考慮すべきです。

認可サーバーが特定の クライアントタイプをサポートしなければならないという要件はありません。

単一の client_id を複数のタイプの クライアントとして扱うべきではありません。

この仕様は、次のクライアントプロファイルを想定して設計されています。

「Web アプリケーション」:

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

「ブラウザベースアプリケーション」:

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

「ネイティブアプリケーション」:

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

2.2. クライアント識別子

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

クライアント識別子は不透明な文字列であり、その長さは 1.7.1節 で説明されているように この仕様では定義されていません。

認可サーバーが、認可サーバー以外の主体によって 発行されたクライアント識別子を持つクライアントをサポートする場合、 認可サーバーは 7.4節 で説明されているような、クライアントによるリソース所有者のなりすましを 防止するための予防措置を講じるべきです。

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

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

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

リダイレクト URI は、 4.3節 of [RFC3986] で定義されている絶対 URI でなければなりません。 リダイレクト URI にはクエリ文字列コンポーネント (付録 C.1)を含めてもかまいませんが、 追加のクエリパラメーターを追加する際には保持しなければなりません。 リダイレクト URI にフラグメントコンポーネントを含めてはなりません。

2.3.1. 登録 要件

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

認可サーバーは、クライアントが複数の リダイレクト URI を登録することを許可してもかまいません。

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

私的利用 URI スキームに基づくリダイレクト URI の場合、 認可サーバーは、 クライアントが逆ドメイン名ベースのスキームを使用するという 8.4.3節 の要件を適用すべきです。 少なくとも、ピリオド文字(.)を含まない 私的利用 URI スキームは拒否すべきです。

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

クライアントは、7.13節 で説明されているような、 クエリパラメーターから取得した任意の URI へユーザーのブラウザを転送する URL (「オープンリダイレクター」)を公開してはなりません。 オープンリダイレクターは、認可コードやアクセストークンの 外部流出を可能にする可能性があります。

必要な場合、クライアントはリクエストごとにリダイレクト URI を 変える代わりに、state リクエストパラメーターを使用して リクエストごとのカスタマイズを実現してもかまいません。

リダイレクト URI の登録を必須にしない場合、 攻撃者は 7.13節 で説明されているように、認可エンドポイントをオープンリダイレクターとして 使用できます。

2.3.2. 複数のリダイレクト URI

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

2.3.3. CSRF 攻撃の防止

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

2.3.4. Mix-Up 攻撃の防止

OAuth クライアントが1つの認可 サーバーとのみ対話できる場合、Mix-Up 防御は不要です。一方、 OAuth クライアントが2つ以上の認可サーバーと対話する場合、 クライアントは Mix-Up 攻撃を防止しなければなりません。 Mix-Up 攻撃を防止するため、クライアントは、それぞれのリクエストを送信した 発行者からのリダイレクトレスポンスのみを、かつその認可リクエストを開始した 同じユーザーエージェントからのものとして処理しなければなりません。

Mix-Up 攻撃に対する2つの異なる防御の詳細な説明については 7.15節 を参照してください。

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

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

2.3.6. エンドポイントのコンテンツ

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

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

2.4. クライアント認証

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

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

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

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

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

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

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

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

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

クライアントシークレットを保持する confidential クライアントを サポートするため、認可サーバーは、クライアントが 次のパラメーターを使用してリクエスト本文のコンテンツに クライアントクレデンシャルを含めることをサポートしなければなりません。

"client_id":

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

"client_secret":

必須。クライアントシークレット。

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

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

たとえば、コンテンツパラメーターを使用して アクセストークンを更新するリクエスト(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 認証スキームをサポートしてもかまいません。

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

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

たとえば、次のようになります(表示目的のみで追加の改行を含みます)。

Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

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

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

2.4.2. その他の 認証方式

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

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

2.5. 未登録クライアント

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

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

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

さらに、1つのクライアントエンドポイントを使用します。

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

3.1. 認可エンドポイント

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

クライアントが認可エンドポイントの URL を取得する方法は この仕様の範囲外ですが、 URL は通常、サービス文書または認可サーバーの メタデータ文書 [RFC8414] に記載されます。

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

認可サーバーは認可エンドポイントで HTTP GET メソッド 9.3.1節 of [RFC9110] の使用を サポートしなければならず、 POST メソッド(9.3.3節 of [RFC9110])もサポートしてもかまいません。

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

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

ユーザークレデンシャルを含む可能性のあるリクエストをリダイレクトする 認可サーバーは、それらのユーザークレデンシャルを誤って転送しないように しなければなりません(詳細については 7.5.4節 を参照してください)。

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

グラントタイプは、認可エンドポイントで必要なパラメーターを定義します。 この仕様では "Authorization Code Grant" (4.1節)を定義し、 リクエストに含める基本的なパラメーター一覧も含みます。 Pushed Authorization Requests([RFC9126])などの拡張は、 認可エンドポイントへのリクエストで使用する異なるパラメーター集合を 定義します。

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

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

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

トークンエンドポイント URL にフラグメントコンポーネントを含めてはならず、 クエリ文字列コンポーネント(付録 C.1)を含めてもかまいません。

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

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

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

ブラウザベースアプリケーション (たとえば、補助的なバックエンドサーバーへアクセスせず、 クライアント側 JavaScript のみで動作するアプリケーション)をサポートしたい認可サーバーは、 レスポンスをアプリケーションから可視にするために必要な CORS [WHATWG.CORS] ヘッダーをトークンエンドポイントが サポートしていることを保証する必要があります。 認可サーバーがアプリケーションに対して、メタデータ URL、動的クライアント登録、 失効、イントロスペクション、ディスカバリー、ユーザー情報エンドポイントなど 追加のエンドポイントを提供する場合、これらのエンドポイントもブラウザベース アプリケーションからアクセスされる可能性があり、アクセスを許可するために CORS ヘッダーを定義する必要があります。 詳細については [I-D.ietf-oauth-browser-based-apps] を参照してください。

3.2.1. クライアント 認証

confidential クライアントは、トークンエンドポイントへ リクエストするとき、 2.4節 で説明されているように、 認可サーバーで認証しなければなりません。

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

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

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

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

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

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

"grant_type":

必須。クライアントが特定のトークンリクエストで使用する グラントタイプの識別子です。 この仕様では、値 authorization_code、 refresh_token、client_credentials を定義します。 グラントタイプによって、トークンリクエストで必要またはサポートされる 追加のパラメーターが決まります。それらのグラントタイプの 詳細は以下で定義されます。

"client_id":

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

confidential クライアントは、3.2.1節 で説明されているように、 認可サーバーで認証しなければなりません。

たとえば、クライアントは次の 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

認可サーバーは次を行わなければなりません。

  • confidential クライアント (またはその他の認証要件を持つクライアント)に クライアント認証を要求する。

  • クライアント認証が含まれている場合は クライアントを認証する。

さらにグラントタイプ固有の処理規則が適用され、 各グラントタイプとともに規定されています。

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

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

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

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

"access_token":

必須。認可サーバーが発行したアクセストークン。

"token_type":

必須。1.4節 で説明されている 発行されたアクセストークンのタイプです。値は 大文字と小文字を区別しません。

"expires_in":

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

"scope":

クライアントが要求したスコープと同一の場合は推奨。 それ以外の場合は必須。1.4.1節 で説明されているアクセストークンのスコープ。

"refresh_token":

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

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

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

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

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

たとえば次のようになります。

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"
}

クライアントは、レスポンス内の認識できない値の名前を 無視しなければなりません。認可 サーバーから受信するトークンおよびその他の値の長さは、 1.7.1節 で説明されているように未定義です。

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

認可サーバーは、特に指定がない限り、 HTTP 400 (Bad Request) ステータスコードで応答し、 レスポンスに次のパラメーターを含めます。

"error":

必須。次の中から選ばれる単一の ASCII [USASCII] エラーコード。

"invalid_request":

リクエストに必要なパラメーターが欠けている、 サポートされていないパラメーター値 (グラントタイプを除く)を含んでいる、 パラメーターが重複している、複数のクレデンシャルを含んでいる、 クライアントを認証するために複数のメカニズムを使用している、 認可リクエストで code_challenge が送信されていないにもかかわらず code_verifier を含んでいる、 またはその他の理由で不正な形式です。

"invalid_client":

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

"invalid_grant":

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

"unauthorized_client":

認証されたクライアントには、 この認可グラントタイプを使用する権限がありません。

"unsupported_grant_type":

認可グラントタイプが 認可サーバーでサポートされていません。

"invalid_scope":

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

error パラメーターの値には、 集合 %x20-21 / %x23-5B / %x5D-7E の外側の文字を 含めてはなりません。

"error_description":

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

"error_uri":

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

パラメーターは、付録 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 ブラウザ)でフローを開始でき、認可サーバーから自身へリダイレクトして戻せる必要があります。

 +----------+
 | リソース |
 |   所有者  |
 +----------+
       ^
       |
       |
 +-----|----+          クライアント識別子       +---------------+
 | .---+---------(1)-- & リダイレクト URI ---->|               |
 | |   |    |                                 |               |
 | |   '---------(2)-- ユーザーが認証 -------->|               |
 | | ユーザー |                                |      認可      |
 | |エージェント|                               |    サーバー    |
 | |        |                                 |               |
 | |    .--------(3)---- 認可コード ----------<|               |
 +-|----|---+                                 +---------------+
   |    |                                         ^      v
   |    |                                         |      |
   ^    v                                         |      |
 +---------+                                      |      |
 |         |>---(4)------ 認可コード -------------'      |
 |クライアント|          & リダイレクト URI               |
 |         |                                             |
 |         |<---(5)---- アクセストークン -----------------'
 +---------+       (任意のリフレッシュトークン付き)
図 3: 認可コードフロー

図 3 に示すフローには、次の手順が含まれます。

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

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

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

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

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

4.1.1. 認可 リクエスト

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

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

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

"response_type":

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

拡張レスポンスタイプには、空白で区切られた (%x20) 値のリストを含めてもかまいません。この場合、値の順序は重要ではありません (たとえば、レスポンスタイプ a b は b a と同じです)。 このような複合レスポンスタイプの意味は、それぞれの仕様で定義されます。

一部の拡張レスポンスタイプは [OpenID.Connect] で定義されています。

認可リクエストに response_type パラメーターがない場合、 またはレスポンスタイプを理解できない場合、認可サーバーは 4.1.2.1節 で説明されているエラーレスポンスを返さなければなりません。

"client_id":

必須。2.2節 で説明されているクライアント識別子。

"code_challenge":

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

"code_challenge_method":

必須。値 S256、または将来の拡張で定義される値。

"redirect_uri":

このクライアントに登録されているリダイレクト URI が1つだけの場合は 任意。 このクライアントに複数のリダイレクト URI が登録されている場合は必須。 2.3.2節 を参照してください。

"scope":

任意。1.4.1節 で説明されている アクセス要求のスコープ。

"state":

任意。リクエストとコールバックの間で 状態を維持するためにクライアントが使用する不透明な値。 認可サーバーは、ユーザーエージェントをクライアントへ リダイレクトして戻す際にこの値を含めます。この値は 認可リクエスト URI のクエリコンポーネントで運ばれ、 クライアントへのリダイレクトでも再び運ばれるため、実際の長さは 認可サーバー、ユーザーエージェント、およびクライアントが受け入れる URI と HTTP ヘッダーフィールドの長さによって制限されます。 1.7.1節 を参照してください。

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 を公開しないコードチャレンジ方式を使用しなければなりません。 そうしない場合、認可リクエストを読み取れる攻撃者 ([RFC9700] の攻撃者 A4 を参照)は、 このメカニズムによって提供されるセキュリティを 破ることができます。現在、S256 がそのような唯一の方式です。

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

次にクライアントは、有効な変換方式でコードベリファイアを 変換することにより、コードベリファイアから導出した code_challenge を作成します。

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

この仕様で定義する変換は S256 のみです。将来の拡張で 追加の変換方式が定義される場合があります。

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 拡張から 採用されています。[RFC7636] で定義された plain 変換方式は、 この仕様では削除され、明示的に禁止されています。詳細については 7.5.2節 を参照してください。

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

クライアントは code_challenge および code_verifier を使用しなければならず、 認可サーバーは 7.5.1節 で説明されている条件を除き、それらの使用を強制しなければなりません。 この場合でも、上記のとおり code_challenge と code_verifier を使用し、その使用を強制することが 引き続き推奨されます。

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

クライアントは 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 が存在する場合、それがクライアント登録 (2節) で事前に確立された登録済みリダイレクト URI のいずれかと一致することを確認して、 検証しなければなりません。 2つの URI を比較する際、認可サーバーは それらが等しいことを確認しなければなりません。詳細については 6.2.1節 of [RFC3986] の単純文字列比較を参照してください。 唯一の例外は localhost URI を使用するネイティブアプリです。この場合、認可 サーバーは 8.4.2節 で説明されているように、可変ポート番号を許可しなければなりません。

リクエストが有効である場合、 認可サーバーはリソース所有者を認証し、 認可の決定を取得します(リソース所有者に尋ねるか、 その他の手段で承認を確立します)。

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

4.1.2. 認可 レスポンス

リソース所有者がアクセス要求を許可した場合、認可 サーバーは認可コードを発行し、拡張によって別途規定されていない限り、 付録 C.1 で説明されているクエリ文字列シリアル化を使用して、 リダイレクト URI のクエリコンポーネントに次のパラメーターを 追加することによりクライアントへ届けます。

"code":

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

"state":

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

"iss":

必須。認可サーバーの発行者識別子。 クライアントが複数の認可サーバーと対話する場合、 Mix-Up 攻撃を防止するために使用できます。 クライアントが Mix-Up 攻撃を防止するためにこれを使用する方法の 詳細については 7.15節 および [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

クライアントは、認識できないレスポンスパラメーターを無視しなければなりません。 認可コード文字列の長さは、 1.7.1節 で説明されているように、この仕様では未定義です。

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

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

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

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

リダイレクト URI の欠落、無効、または 不一致のためにリクエストが失敗した場合、あるいはクライアント識別子が欠落または無効な場合、 認可サーバーはユーザーエージェントを 無効なリダイレクト URI へリダイレクトしてはならず、 たとえばブラウザでユーザーにメッセージを表示するなどして、 リソース所有者にエラーを通知すべきです。 エラーレスポンスをユーザーエージェントへ直接返す場合、 認可サーバーは HTTP 400 (Bad Request) ステータスコードを使用すべきです。 トークンエンドポイントのクライアント認証 エラーに使用される HTTP 401 (Unauthorized) ステータスコードは、 認可エンドポイントのリクエストエラーには適用されません。

認可サーバーは、エラーレスポンスをクライアントへ リダイレクトする前に、クライアント識別子とリダイレクト URI を検証しなければなりません。両方が検証されたら、 認可サーバーは以下で定義するエラーコードを使用して リクエストエラーをリダイレクトします。

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

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

リソース所有者がアクセス要求を拒否した場合、または クライアント識別子とリダイレクト URI の検証後に リクエストが失敗した場合、認可サーバーはユーザーエージェントを リダイレクト URI へリダイレクトし、 付録 C.1 で説明されているようにリダイレクト URI のクエリコンポーネントへ 次のパラメーターを追加することでクライアントに通知します。

"error":

必須。次の中から選ばれる 単一の ASCII [USASCII] エラーコード。

"invalid_request":

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

"unauthorized_client":

クライアントには、この方式を使用して 認可コードを要求する権限がありません。

"access_denied":

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

"unsupported_response_type":

認可サーバーは、 この方式を使用した 認可コードの取得をサポートしていません。

"invalid_scope":

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

"server_error":

認可サーバーで、 リクエストの処理を妨げる予期しない 状況が発生しました。 (HTTP リダイレクトでは HTTP 500 Internal Server Error ステータスコードをクライアントへ返せないため、 このエラーコードが必要です。)

"temporarily_unavailable":

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

error パラメーターの値には、 集合 %x20-21 / %x23-5B / %x5D-7E の外側の文字を 含めてはなりません。

"error_description":

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

"error_uri":

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

"state":

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

"iss":

必須。認可サーバーの 発行者識別子。詳細については、上記の 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. トークンエンドポイント 拡張

認可グラントタイプは、トークンエンドポイントで grant_type の値 authorization_code によって識別されます。

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

"code":

必須。認可サーバーから受信した 認可コード。

"code_verifier":

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

"client_id":

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

認可サーバーは、特定の認可コードについて アクセストークンを1回だけ返さなければなりません。

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

たとえば、クライアントは次の 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

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

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

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

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

  • code_verifier が存在する場合、 受信した code_verifier からコードチャレンジを計算し、 クライアントが指定した code_challenge_method 方式に従って 最初に変換したうえで、以前に関連付けた code_challenge と比較することにより、 code_verifier を検証する。および

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

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

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

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

クライアントクレデンシャルグラントタイプは、confidential クライアントのみが使用しなければなりません。

     +---------+                                  +---------------+
     |         |                                  |               |
     |         |>--(1)---- クライアント認証 ------>|      認可     |
     |クライアント|                                |    サーバー    |
     |         |<--(2)--- アクセストークン -------<|               |
     |         |                                  |               |
     +---------+                                  +---------------+
図 4: クライアントクレデンシャルグラント

図 4 に示す クライアントクレデンシャルグラントの使用には、次の手順が含まれます。

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

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

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

クライアントクレデンシャルグラントタイプは、トークン エンドポイントで grant_type の値 client_credentials によって識別されます。

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

"scope":

任意。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

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

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

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

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

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

認可サーバーは、権限のない主体が 有効なリフレッシュトークンを生成する目的で、リフレッシュトークンを 生成、変更、または推測できないようにしなければなりません。

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

リフレッシュトークングラントタイプは、トークンエンドポイントで grant_type の値 refresh_token によって識別されます。

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

"refresh_token":

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

"scope":

任意。1.4.1節 で説明されている アクセス要求のスコープ。要求するスコープには、 リソース所有者が元々付与していないスコープを 含めてはならず、省略した場合は リソース所有者が元々付与したスコープと同一として扱われます。

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

たとえば、クライアントはトランスポート層セキュリティを使用して 次の 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

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

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

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

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

認可サーバーは、public クライアントについて、 悪意ある主体によるリフレッシュトークンのリプレイを検出するため、 次のいずれかの方式を使用しなければなりません。

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

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

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

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

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

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

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

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

認可サーバーは、次のような セキュリティイベントが発生した場合に、リフレッシュトークンを自動的に取り消してもかまいません。

  • パスワードの変更

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

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

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

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

5. リソースリクエスト

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

5.1. Bearer トークンリクエスト

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

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

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 ヘッダーフィールドの構文は、 2節 of [RFC2617] で定義されている Basic スキームの使用法に従います。 Basic と同様に、これは 1.2節 of [RFC2617] で定義されている 一般構文には準拠しませんが、HTTP 1.1 Authentication [RFC7235] の一般的な認証フレームワークとは 互換性があることに注意してください。ただし、既存のデプロイメントを反映するため、 そこで示されている推奨プラクティスには従いません。 Bearer クレデンシャルの構文は次のとおりです。

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

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

11.1節 of [RFC9110] で説明されているように、 文字列 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 パラメーターを使用して リクエストコンテンツにアクセストークンを追加します。 次のすべての条件を満たさない限り、クライアントはこの方法を使用してはなりません。

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

  • コンテンツが、URL 現行標準 [WHATWG.URL] で定義されている application/x-www-form-urlencoded コンテンツタイプの エンコード要件に従っている。

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

  • リクエストでエンコードされるコンテンツが すべて ASCII [USASCII] 文字で構成されている。

  • HTTP リクエストメソッドが、コンテンツについて 定義された意味論を持つメソッドである。特に、これは GET メソッドを使用してはならないことを意味します。

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

たとえば、クライアントはトランスポート層セキュリティを使用して 次の 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 リクエストヘッダーフィールドへ アクセスできないアプリケーションコンテキストを除き、 使用すべきではありません。リソースサーバーはこの方法をサポートしてもかまいません。

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

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

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

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

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

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

5.3. エラーレスポンス

リソースアクセスリクエストが失敗した場合、リソースサーバーは クライアントにエラーを通知すべきです。エラーレスポンスの詳細は、 5.3.2節 の Bearer トークンの説明など、 特定のトークンタイプによって決まります。

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

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

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

"realm":

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

"scope":

scope 属性は 1.4.1節 で定義されています。 scope 属性は、要求されたリソースへアクセスするために アクセストークンに必要なスコープを示す、大文字と小文字を区別する スコープ値の空白区切りリストです。scope 値は実装によって 定義され、中央集約されたレジストリはありません。許可される値は 認可サーバーによって定義されます。scope 値の順序は 重要ではありません。場合によっては、保護されたリソースを 利用するのに十分なアクセススコープを持つ新しいアクセストークンを 要求するときに scope 値が使用されます。 scope 属性の使用は任意です。 scope 属性は複数回出現してはなりません。 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 属性を含めるべきです。パラメーター値は 5.3.2節 で説明されています。

"error_description":

リソースサーバーは、 エンドユーザーに表示することを意図しない、人間が読める 開発者向けの説明を提供するために error_description 属性を含めてもかまいません。

"error_uri":

リソースサーバーは、 エラーを説明する人間が読める Web ページを識別する 絶対 URI を持つ error_uri 属性を 含めてもかまいません。

error、error_description、および error_uri 属性は複数回 出現してはなりません。

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

5.3.2. エラーコード

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

"invalid_request":

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

"invalid_token":

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

"insufficient_scope":

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

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

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

たとえば次のようになります。

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 レジストリに登録する (11.1節 of [RFC6749] の手順に従う)か、 一意の絶対 URI をその名前として使用します。

6.1.1. 登録済み アクセストークンタイプ

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

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

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

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

新しい認証スキームは、この仕様での使用法と同様の方法で エラー情報を返すために、 error_description および error_uri パラメーターの使用も 規定することを選択してもかまいません。

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

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

6.1.2. ベンダー固有のアクセストークンタイプ

URI 名を利用するタイプは、一般的には適用できず、 使用されるリソースサーバーの実装詳細に 固有である、ベンダー固有の実装に限定すべきです。

その他のすべてのタイプは登録しなければなりません。

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

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

パラメーター名は param-name ABNF に準拠しなければならず、 パラメーター値の構文は明確に定義されていなければなりません (たとえば、ABNF を使用するか、既存のパラメーター構文を参照します)。

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

一般的には適用できず、使用される認可サーバーの 実装詳細に固有である、未登録のベンダー固有パラメーター拡張は、 他の登録済み値と競合する可能性が低いベンダー固有の プレフィックス(たとえば 'companyname_' で始める)を使用すべきです。

6.3. 新しい 認可グラントタイプの定義

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

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

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

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. 追加の エラーコードの定義

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

拡張エラーコードは、それと組み合わせて使用される拡張が 登録済みアクセストークンタイプ、登録済みエンドポイントパラメーター、または 拡張グラントタイプである場合、登録しなければなりません (11.4節 of [RFC6749] の手順に従います)。 未登録の拡張で使用されるエラーコードは 登録してもかまいません。

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

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

7. セキュリティに関する考慮事項

柔軟で拡張可能なフレームワークであるため、OAuth のセキュリティに関する 考慮事項は多くの要因に依存します。以下の節では、 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. アクセス トークン情報の漏えい

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

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

Cookie はデフォルトでは平文で送信されるため、そこに 含まれる情報はすべて漏えいの危険にさらされます。 Bearer トークンを平文で送信される可能性のある Cookie に保存してはなりません。 Cookie に関するセキュリティ上の考慮事項については [RFC6265] の7節および8節を参照してください。

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

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

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

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

7.1.2. 脅威の緩和

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

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

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

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

1.5節 では、 アクセストークンの漏えいを防止し、 クライアント、リソースサーバー、および認可サーバー間の通信に 機密性と完全性を提供するための情報を示しています。

7.1.3. 推奨事項の 要約

7.1.3.1. Bearer トークンを保護する

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

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

クライアントは、保護されたリソースへリクエストするとき、 TLS 証明書チェーンを検証しなければなりません。 これを行わないと、DNS ハイジャック攻撃によってトークンを盗まれ、 意図しないアクセスを取得される可能性があります。

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

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

7.1.3.4. Bearer トークンを HTTP Cookie に保存しない

実装は、平文で送信される可能性のある Cookie(これは Cookie のデフォルトの送信方式です)内に Bearer トークンを保存してはなりません。Bearer トークンを Cookie に 保存する実装は、クロスサイトリクエストフォージェリに対する 予防措置を講じなければなりません。

7.1.3.5. 短命な Bearer トークンを発行する

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

7.1.3.6. スコープが 制限された Bearer トークンを発行する

認可サーバーは、オーディエンス制限を含み、 意図されたリソースサーバーまたはリソースサーバー群に 使用範囲を限定した Bearer トークンを発行すべきです。

7.1.3.7. ページ URL で Bearer トークンを渡さない

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

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

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

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

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

7.2. クライアント認証

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

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

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

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

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

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

認可サーバーは、クライアントを認証するか、 繰り返しのリクエストが元のクライアントからのものであって なりすまし者からのものではないことを保証するその他の措置に依存しない限り、 繰り返される認可リクエストを(リソース所有者による能動的な操作なしに) 自動的に処理すべきではありません。

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

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

宣言済み https スキームリダイレクトなどの措置を、 認可サーバーが身元証明として受け入れてもかまいません。 一部のオペレーティングシステムは、必要に応じて受け入れることのできる 代替のプラットフォーム固有の身元確認機能を提供する場合があります。

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

クライアントは、必要最小限のスコープを持つアクセストークンを 要求すべきです。認可サーバーは、要求されたスコープをどのように 承認するかを決定する際にクライアントの身元を考慮すべきであり、 要求されたものより少ないスコープを持つアクセストークンを 発行してもかまいません。

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

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

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

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

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

7.5. 認可コードの セキュリティに関する考慮事項

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

認可コードインジェクションとは、クライアントが 正当な認可サーバーからの認可コードではなく、攻撃者からの認可コードを 自身のリダイレクト URI で受信する攻撃です。保護措置がなければ、 クライアントには攻撃が発生したことを知る手段がありません。 認可コードインジェクションにより、攻撃者が被害者のアカウントへの アクセスを取得する場合もあれば、被害者が誤って攻撃者のアカウントへの アクセスを取得する場合もあります。

7.5.1.1. 対策

クライアントへの認可コードの インジェクションを防ぐため、 以下の両方の基準を満たす場合を除き、クライアントは code_challenge および code_verifier を使用する必要があり、認可サーバーは それらの使用を強制しなければなりません。

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

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

この場合でも、 code_challenge と code_verifier を使用し、 その使用を強制することが推奨されます。

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

クライアントが OpenID Connect の nonce パラメーターを検証することに依存する場合、 認可サーバーには、クライアントが実際に 認可コードインジェクション攻撃から自身を保護していることを 確認する手段がありません。攻撃者がクライアントへ認可コードを インジェクションできた場合、クライアントはその注入された認可コードを 交換してトークンを取得し、その後 nonce を検証して 一致しないことを確認した時点で初めて ID トークンを拒否します。 これに対して、認可サーバーが code_challenge および code_verifier パラメーターを 強制すると、認可サーバーが認可コードインジェクション攻撃を 事前に認識し、そもそもトークンを一切発行しないようにできるため、 より高いセキュリティ効果が得られます。

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

7.5.2. PKCE "plain" コードチャレンジ方式

[RFC7636] で定義されている plain コードチャレンジ方式は、OAuth 2.1 では明示的に禁止されています。 plain 方式は、コードベリファイアが認可リクエスト内で 平文で送信されるため、認可リクエストを読み取れる攻撃者 ([RFC9700] の攻撃者 A4) による認可コードの傍受に対して何の保護も提供しません。

plain モードをサポートする歴史的な根拠 (暗号学的ハッシュ機能を持たないデバイス)は、 証明書検証のために SHA-256 のサポートを要求する OAuth 2.1 の TLS 1.2+ 要件によって陳腐化しています。 OAuth 2.1 を実装できるデバイスは必然的に SHA-256 をサポートします。

plain コードチャレンジ方式をサポートする認可サーバーは、 検証不可能なダウングレード攻撃ベクトルを生み出します。これは、サーバーが 正当な制約付きクライアントと、制約付きであると主張する 攻撃者によって改変されたリクエストを区別できないためです。

S256 をサポートできない既存クライアントを持つデプロイメントは、 レガシーな認可方式のサポートを終了する前に、 有効期間を延長したリフレッシュトークンを発行すべきです。 リフレッシュトークングラント(4.3節)は PKCE を必要としないためです。

7.5.3. 認可コードの 再利用

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

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

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

7.5.4. HTTP 307 リダイレクト

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

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

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

これにより、機密性の高いクレデンシャルがクライアントへ漏えいします。 クライアントが悪意あるものであれば、そのクレデンシャルを使用して AS でユーザーになりすますことができます。

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

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

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

中間者攻撃に関連するリスクは、 認可エンドポイントおよびトークンエンドポイントとの通信に [RFC9846] などのチャネルセキュリティメカニズムの 使用を必須とすることで緩和されます。 詳細については 1.5節 を 参照してください。

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

認可サーバーは、攻撃者がアクセストークン、 認可コード、リフレッシュトークン、リソース所有者の パスワード、およびクライアントクレデンシャルを推測できないようにしなければなりません。

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

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

7.8. フィッシング攻撃

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

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

フィッシング攻撃のリスクを緩和する方法の詳細については、 1.5節 を参照してください。

7.10. クロスサイトリクエスト フォージェリ

攻撃者は、被害者のデバイス上にある正当なクライアントの リダイレクト URI にリクエストを注入しようとする可能性があります。 たとえば、クライアントに攻撃者の制御下にあるリソースへアクセスさせることができます。 これは Cross-Site Request Forgery (CSRF) と呼ばれる攻撃の 一形態です。

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

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

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

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

したがって AS は、[RFC8414] に従った AS メタデータ、または サポートを保証または確認するためのデプロイメント固有の方法によって、 サポートするコードチャレンジ方式を検出できる手段を提供しなければなりません。

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

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

攻撃者はこの攻撃ベクトルを使用して、ユーザーの認証 クレデンシャルを取得したり、クライアントに付与されるアクセスのスコープを変更したり、 ユーザーのリソースへアクセスしたりする可能性があります。

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

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

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

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] で説明されているものを含む その他の手法と組み合わせるべきです。そのような場合でも、 追加の対策を引き続き講じるべきです。

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

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

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

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

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

AS またはクライアントがオープンリダイレクターを持つ場合、 次の攻撃が発生する可能性があります。

7.13.1. オープン リダイレクターとしてのクライアント

クライアントはオープンリダイレクターを公開してはなりません。 攻撃者はオープンリダイレクターを使用してクライアントを指す URL を作成し、 4.1.1節 of [RFC9700] で説明されているように、それを利用して認可コードを 流出させる可能性があります。 別の悪用例として、クライアントを指しているように見える URL を作成できます。 これにより、ユーザーがその URL を信頼してブラウザでアクセスするよう 騙される可能性があります。これはフィッシングに悪用できます。

オープンリダイレクトを防止するため、クライアントは、 対象 URL が許可リストに含まれている場合、またはリクエストの オリジンと完全性を認証できる場合にのみリダイレクトすべきです。 オープンリダイレクトへの対策は OWASP [owasp_redir] で説明されています。

7.13.2. オープンリダイレクターとしての 認可サーバー

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

4.1.2.1節 では、 client_id と redirect_uri の組み合わせが無効な場合に、 認可サーバーがユーザーエージェントを自動的にリダイレクトしてはならないと 規定することで、すでにオープンリダイレクトを防止しています。

ただし、攻撃者は正しく登録された リダイレクト URI を使用してフィッシング攻撃を実行することもできます。 たとえば、攻撃者は動的クライアント登録 [RFC7591] を介してクライアントを登録し、 次のいずれかの攻撃を実行できます。

  1. たとえば無効なスコープ値を使用することで、 意図的に誤った認可リクエストを送信し、認可サーバーに ユーザーエージェントを自身のフィッシングサイトへリダイレクトさせます。

  2. 攻撃者が制御する client_id と redirect_uri を使用して、 意図的に有効な認可リクエストを送信します。ユーザーが認証した後、 認可サーバーはユーザーにリクエストへの同意を求めます。 ユーザーがリクエストの問題に気付いて拒否した場合でも、認可 サーバーはユーザーエージェントをフィッシングサイトへリダイレクトします。 この場合、ユーザーが取った操作にかかわらず、 ユーザーエージェントはフィッシングサイトへリダイレクトされます。

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

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

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

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

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

詳細については 17.2節 of [RFC9110] を参照してください。

7.15. 認可サーバー Mix-Up の緩和

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

OAuth クライアントが1つの認可サーバーとのみ対話できる場合、 Mix-Up 防御は必要ありません。一方、OAuth クライアントが2つ以上の 認可サーバーと対話するシナリオでは、クライアントは Mix-Up 攻撃を 防止しなければなりません。以下では2つの異なる方法について説明します。

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

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

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

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

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

この発行者識別子をクライアントへ伝達する方法には いくつかあります。

  • 発行者情報はレスポンスパラメーター iss を介して伝達されます (4.1.2節 を参照)。

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

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

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

7.15.2. 異なるリダイレクト URI による Mix-Up 防御

この防御では、クライアントは対話する発行者ごとに 異なるリダイレクト URI を使用しなければなりません。

クライアントは、発行者用の固有のリダイレクト URI と 認可レスポンスを受信した URI を比較することにより、 認可レスポンスが正しい発行者から受信されたことを 確認しなければなりません。一致しない場合、クライアントは フローを中止しなければなりません。

この防御は既存の OAuth 機能を利用しますが、 クライアントが多数の異なる発行者を使用するために1回だけ登録する シナリオ(一部のオープンバンキング方式など)では使用できません。 また、クライアント登録と密接に統合されているため、 自動的にデプロイすることがより困難です。

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

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

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

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

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

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

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

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

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

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

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

複数のユーザーへ配布されるアプリの一部として 静的に含まれる秘密は、機密性のある秘密ではありません。 あるユーザーが自身のコピーを調べて共有秘密を知ることができるためです。 このため、認可サーバーは、共有秘密を使用したネイティブアプリクライアントの クライアント認証を要求してはなりません。 これは、client_id リクエストパラメーターですでに提供されている クライアント識別以上の価値を持たないためです。

ネイティブアプリクライアントに静的に含まれる共有秘密を なお要求する認可サーバーは、そのクライアントを public クライアント(2.1節 で定義)として 扱い、その秘密をクライアントの身元の証明として 受け入れてはなりません。追加の措置がなければ、 このようなクライアントはクライアントのなりすましの影響を受けます (7.3.1節 を参照)。

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

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

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 認可リクエストを実行するために、 外部ユーザーエージェントを使用しなければなりません。これは、 ブラウザで認可リクエストを開き (8.3節 で詳述)、 認可レスポンスをネイティブアプリへ戻す リダイレクト URI(8.4節 で定義)を 使用することで実現します。

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

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

ネイティブアプリの認可リクエストにおける リダイレクト URI の役割は、Web ベースの認可リクエストの場合と似ています。 認可レスポンスを OAuth クライアントのサーバーへ返す代わりに、 ネイティブアプリが使用するリダイレクト URI はレスポンスを アプリへ返します。さまざまなプラットフォームで 認可レスポンスをネイティブアプリへ返す 複数のリダイレクト URI の選択肢が 8.4節 に記載されています。 アプリが URI を受信し、そのパラメーターを検査できる 任意のリダイレクト URI を使用できます。

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

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

一部のプラットフォームは「アプリ内ブラウザタブ」と呼ばれる ブラウザ機能をサポートしています。これは、アプリを切り替えることなく アプリのコンテキスト内にブラウザのタブを表示でき、 共有された認証状態やセキュリティコンテキストといった ブラウザの主要な利点を維持できます。 サポートされているプラットフォームでは、使いやすさの理由から、 アプリが認可リクエストにアプリ内ブラウザタブを使用することが 推奨されます。

8.4. ネイティブアプリでの 認可レスポンスの受信

ネイティブアプリがブラウザから認可レスポンスを受信するために 使用できるリダイレクト URI には複数の選択肢があり、 利用可能性とユーザー体験はプラットフォームによって異なります。

8.4.1. 宣言された "https" スキーム URI リダイレクト

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

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

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

リダイレクト URI だけでは public なネイティブ アプリクライアントと confidential Web クライアントを区別するのに十分ではないため、 8.1.1節 では、 サーバーがクライアントタイプを判断して 適切に処理できるよう、クライアント登録時に クライアントタイプを記録することが必須とされています。

アプリが宣言した https スキームのリダイレクト URI は、 宛先アプリの身元がオペレーティングシステムによって 認可サーバーに保証されるという点で、 その他のネイティブアプリのリダイレクト方式より利点があります。 このため、可能な場合、ネイティブアプリは他の選択肢より この方式を使用すべきです。

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

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

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

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

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

ランダムに割り当てられたポートを使用する IPv6 ループバックインターフェイスのリダイレクト例を次に示します。

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

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

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

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

8.4.3. 私的利用 URI スキームリダイレクト

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

私的利用 URI スキームをサポートする多くの環境では、 あるスキームを占有し、他の主体が別のアプリケーションの スキームを使用することを防止するメカニズムがありません。 そのため、私的利用 URI スキームを使用するクライアントは、 リダイレクト URI に対する潜在的な攻撃の影響を受けます。 したがって、この選択肢は、前述したより安全な選択肢が 利用できない場合にのみ使用すべきです。

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

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

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

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

3.2節 of [RFC3986] の要件に従うと、私的利用 URI スキームリダイレクトには 命名機関が存在しないため、スキームコンポーネントの後には 単一のスラッシュ(/)だけが現れます。 私的利用 URI スキームを利用する完全なリダイレクト URI の例は次のとおりです。

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

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

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

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

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

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

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

通常のアドレスバーやブラウザが備える可視の証明書検証機能がない 埋め込みユーザーエージェントにユーザーがクレデンシャルを入力することを 奨励すると、ユーザーは正当なサイトにサインインしているかどうかを 判断できなくなります。実際に正当なサイトであったとしても、 サイトを事前に検証せずにクレデンシャルを入力してよいという習慣を ユーザーに身に付けさせてしまいます。

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

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

認可リクエストを開始するネイティブアプリは、 ユーザーインターフェイスを大きく制御できるため、 偽の外部ユーザーエージェント、すなわち 外部ユーザーエージェントのように見せかけた埋め込みユーザーエージェントを 提示できる可能性があります。

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

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

アプリ内ブラウザタブを使用する際のセキュリティを 特に懸念するユーザーは、追加の措置として、 アプリ内ブラウザタブからリクエストを完全なブラウザで開き、 そこで認可を完了することもできます。 アプリ内ブラウザタブパターンのほとんどの実装は、 このような機能を提供しています。

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

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

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

8.5.4. ネイティブアプリでのループバック リダイレクトに関する考慮事項

ループバックインターフェイスのリダイレクト URI は http スキーム(すなわち TLS なし)を 使用してもかまいません。HTTP リクエストがデバイスの外へ 出ることがないため、ループバックインターフェイスの リダイレクト URI ではこれは許容されます。

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

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

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

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

ブラウザベースアプリは Web ブラウザ内で動作するクライアントで、 通常は JavaScript で記述され、「シングルページアプリ」とも呼ばれます。 この種類のアプリには、ネイティブアプリと類似した 特有のセキュリティ上の考慮事項があります。

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 グラントの削除

OAuth 2.0 Implicit グラントは、 [RFC9700] で非推奨とされたため、OAuth 2.1 から省略されています。

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

response_type=token の削除は、 認可エンドポイントから他のアーティファクトを返すその他の拡張 レスポンスタイプには影響しません。たとえば、[OpenID.Connect] で定義されている response_type=id_token です。

10.2. トークンリクエストの リダイレクト URI パラメーター

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

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

OAuth 2.0 と OAuth 2.1 の両方のクライアントをサポートしたい 認可サーバーの後方互換性のため、認可サーバーはクライアントが トークンリクエスト(4.1.3節)で redirect_uri パラメーターを送信することを許可しなければならず、 [RFC6749] で説明されているとおりにそのパラメーターを適用しなければなりません。認可サーバーは リクエスト内の 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 認証: Basic および Digest アクセス認証", RFC 2617, DOI 10.17487/RFC2617, , <https://www.rfc-editor.org/info/rfc2617>.
[RFC3629]
Yergeau, F., "UTF-8、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): 汎用構文", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC4949]
Shirey, R., "インターネットセキュリティ 用語集、第2版", FYI 36, RFC 4949, DOI 10.17487/RFC4949, , <https://www.rfc-editor.org/info/rfc4949>.
[RFC5234]
Crocker, D., Ed. and P. Overell, "構文仕様のための拡張 BNF: 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 トークンの使用", RFC 6750, DOI 10.17487/RFC6750, , <https://www.rfc-editor.org/info/rfc6750>.
[RFC7235]
Fielding, R., Ed. and J. Reschke, Ed., "ハイパーテキスト転送プロトコル (HTTP/1.1): 認証", RFC 7235, DOI 10.17487/RFC7235, , <https://www.rfc-editor.org/info/rfc7235>.
[RFC7521]
Campbell, B., Mortimore, C., Jones, M., and Y. Goland, "OAuth 2.0 クライアント認証および 認可グラントのためのアサーションフレームワーク", RFC 7521, DOI 10.17487/RFC7521, , <https://www.rfc-editor.org/info/rfc7521>.
[RFC7523]
Jones, M., Campbell, B., and C. Mortimore, "OAuth 2.0 クライアント認証および 認可グラントのための JSON Web Token (JWT) プロファイル", 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", BCP 212, RFC 8252, DOI 10.17487/RFC8252, , <https://www.rfc-editor.org/info/rfc8252>.
[RFC8259]
Bray, T., Ed., "JavaScript Object Notation (JSON) データ交換形式", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP セマンティクス", 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 キャッシュ", 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 認可サーバーの発行者 識別", 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 セキュリティのベストカレントプラクティス", BCP 240, RFC 9700, DOI 10.17487/RFC9700, , <https://www.rfc-editor.org/info/rfc9700>.
[RFC9846]
Rescorla, E., "Transport Layer Security (TLS) プロトコル バージョン 1.3", RFC 9846, DOI 10.17487/RFC9846, , <https://www.rfc-editor.org/info/rfc9846>.
[USASCII]
Institute, A. N. S., "符号化文字 集合 -- 7ビット米国標準情報交換符号、ANSI X3.4", .
[W3C.REC-xml-20081126]
Bray, T., Paoli, J., Sperberg-McQueen, C. M., Maler, E., and F. Yergeau, "拡張可能マークアップ言語", , <https://www.w3.org/TR/REC-xml/REC-xml-20081126.xml>.
[WHATWG.CORS]
WHATWG, "Fetch 現行標準: CORS プロトコル", , <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, "JWT を使用した OAuth 2 state パラメーター内の claim のエンコード", 作業中, インターネットドラフト, 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 アテステーションベースのクライアント認証", 作業中, インターネットドラフト, draft-ietf-oauth-attestation-based-client-auth-10, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-attestation-based-client-auth-10>.
[I-D.ietf-oauth-browser-based-apps]
Parecki, A., De Ryck, P., and D. Waite, "ブラウザベース アプリケーション向け OAuth 2.0", 作業中, インターネットドラフト, draft-ietf-oauth-browser-based-apps-27, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps-27>.
[I-D.ietf-oauth-client-id-metadata-document]
Parecki, A. and E. Smith, "OAuth Client ID メタデータ文書", 作業中, インターネットドラフト, draft-ietf-oauth-client-id-metadata-document-02, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-02>.
[I-D.ietf-oauth-rfc7523bis]
Jones, M. B., Campbell, B., Mortimore, C., and F. Skokan, "OAuth 2.0 JSON Web Token (JWT) クライアント認証および アサーションベース認可グラントの更新", 作業中, インターネットドラフト, draft-ietf-oauth-rfc7523bis-11, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-rfc7523bis-11>.
[NIST800-63]
Burr, W., Dodson, D., Newton, E., Perlner, R., Polk, T., Gupta, S., and E. Nabbus, "NIST Special Publication 800-63-1、情報セキュリティ", , <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: インターネット上のマルチメディアリソースへの認可済みアクセスのための業界標準", , <https://www.svta.org/product/online-multimedia-authorization-protocol/>.
[OpenID.Connect]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "正誤表セット2を組み込んだ OpenID Connect Core 1.0", , <https://openid.net/specs/openid-connect-core-1_0.html>.
[OpenID.Discovery]
Sakimura, N., Bradley, J., Jones, M., and E. Jay, "正誤表セット2を組み込んだ OpenID Connect Discovery 1.0", , <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 - 検証されていないリダイレクトと 転送", , <https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html>.
[RFC6265]
Barth, A., "HTTP 状態管理 メカニズム", 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 脅威モデルとセキュリティに関する考慮事項", 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 トークン失効", 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 動的クライアント 登録プロトコル", 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 動的クライアント登録管理プロトコル", RFC 7592, DOI 10.17487/RFC7592, , <https://www.rfc-editor.org/info/rfc7592>.
[RFC7636]
Sakimura, N., Ed., Bradley, J., and N. Agarwal, "OAuth public クライアントによる Proof Key for Code Exchange", RFC 7636, DOI 10.17487/RFC7636, , <https://www.rfc-editor.org/info/rfc7636>.
[RFC7662]
Richer, J., Ed., "OAuth 2.0 トークン イントロスペクション", RFC 7662, DOI 10.17487/RFC7662, , <https://www.rfc-editor.org/info/rfc7662>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 認可 サーバーメタデータ", 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 デバイス認可グラント", 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 クライアント認証 および証明書に結び付けられたアクセストークン", RFC 8705, DOI 10.17487/RFC8705, , <https://www.rfc-editor.org/info/rfc8705>.
[RFC8707]
Campbell, B., Bradley, J., and H. Tschofenig, "OAuth 2.0 のためのリソース インジケーター", RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.
[RFC9068]
Bertocci, V., "OAuth 2.0 アクセストークン向け JSON Web Token (JWT) プロファイル", RFC 9068, DOI 10.17487/RFC9068, , <https://www.rfc-editor.org/info/rfc9068>.
[RFC9112]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, , <https://www.rfc-editor.org/info/rfc9112>.
[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 認証チャレンジプロトコル", 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 仕様", W3C REC REC-html401-19991224, W3C REC-html401-19991224, , <https://www.w3.org/TR/1999/REC-html401-19991224/>.

付録 A. 拡張 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 要素は 2.4.1節 で定義されています。

client-id     = *VSCHAR

A.2. "client_secret" 構文

client_secret 要素は 2.4.1節 で定義されています。

client-secret = *VSCHAR

A.3. "response_type" 構文

response_type 要素は 4.1.1節 および 6.4節 で定義されています。

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

A.4. "scope" 構文

scope 要素は 1.4.1節 で定義されています。

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

A.5. "state" 構文

state 要素は 4.1.1節、4.1.2節、および 4.1.2.1節 で定義されています。

 state      = 1*VSCHAR

A.6. "redirect_uri" 構文

redirect_uri 要素は 4.1.1節 および 4.1.3節 で定義されています。

 redirect-uri      = URI-reference

A.7. "error" 構文

error 要素は 4.1.2.1節、3.2.4節、 および 5.3節 で定義されています。

 error             = 1*NQSCHAR

A.8. "error_description" 構文

error_description 要素は 4.1.2.1節、 3.2.4節、および 5.3節 で定義されています。

 error-description = 1*NQSCHAR

A.9. "error_uri" 構文

error_uri 要素は 4.1.2.1節、3.2.4節、 および 5.3節 で定義されています。

 error-uri         = URI-reference

A.10. "grant_type" 構文

grant_type 要素は 3.2.2節 で定義されています。

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

A.11. "code" 構文

code 要素は 4.1.3節 で定義されています。

 code       = 1*VSCHAR

A.12. "access_token" 構文

access_token 要素は 3.2.3節 で定義されています。

 access-token = 1*VSCHAR

A.13. "token_type" 構文

token_type 要素は 3.2.3節 および 6.1節 で定義されています。

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

A.14. "expires_in" 構文

expires_in 要素は 3.2.3節 で定義されています。

 expires-in = 1*DIGIT

A.15. "refresh_token" 構文

refresh_token 要素は 3.2.3節 および 4.3節 で定義されています。

 refresh-token = 1*VSCHAR

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

新しいエンドポイントパラメーターの構文は 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

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

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

このメディア タイプを使用してコンテンツを生成する際にこの欠点へ対処するため、名前と値はまず UTF-8 文字エンコーディング方式 [RFC3629] を使用して エンコードしなければなりません。その結果得られるオクテット列は、 [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

付録 C. シリアル化

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

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

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

C.2. フォームエンコード シリアル化

パラメーターとその値は、付録 B で定義されている application/x-www-form-urlencoded 形式を使用して、HTTP リクエストのエンティティ本文にパラメーター名と値を追加することでフォームシリアル化されます。 フォームシリアル化は通常 HTTP POST リクエストで使用されます。

C.3. JSON シリアル化

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

付録 D. 拡張

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

付録 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, Goutam Adwant, 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, and Daniel Fett)に感謝します。

付録 F. 文書履歴

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

-16

-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