OAuth 2.1で推奨されるDPoPの仕組みと動作確認

API連携やアプリ開発において、アクセス・トークンの漏洩リスクは常に大きな課題です。従来のBearerトークンでは、万が一トークンが盗まれてしまうと悪用を防ぐのが難しいという側面がありました。
この課題を解決するのが、OAuth 2.1でも重要な要素となっているDPoPです。クライアントが持つ鍵ペアを使ってリクエストに署名することで、送受信中のトークンを保護します。
今回は、なぜ今OAuth 2.1が必要とされているのか、そしてDPoPによってどのように安全性が確保されるのかをご紹介します。

今回はOAuthの基本概念や基礎的な仕組みについては言及しません、以下の記事で詳しく解説されいるので参考にしていただければと思います。

・【連載】世界一わかりみの深いOAuth入門 〜 その1:OAuthってなに?

・何も知らない人向けにふんわりOAuthについて解説する:超初心者向け

なぜ今「OAuth 2.1」が必要とされるのか?

2012年に「OAuth 2.0」の仕様が策定されてから長い年月が経ちました。
現在、Webアプリやモバイルアプリの開発環境は大きく変化しており、それに伴いアクセストークンの保護や認可の仕組みにもアップデートが求められています。

1. OAuth 2.0策定当時の想定と現代の変化

OAuth 2.0が作られた2012年当時は、Webアプリケーションといえばサーバーサイドで処理が完結する構造が主流でした。

  • ブラウザ側で複雑な処理を行うシングルページアプリケーション(SPA)
  • 現在のようにネイティブ動作する数多くのスマートフォンアプリ

当時は、上記のようなクライアント環境がこれほど急速に普及・多様化することは想定されていませんでした。

2. OAuth 2.0におけるセキュリティ上の課題

アプリの利用環境が多様化した結果、以下のような課題が発生するようになりました。

 仕様の曖昧さと新たな攻撃手法

仕様の曖昧な部分や想定外のユースケースを狙った、様々な脆弱性や攻撃手法(リダイレクトURIの悪用やトークン奪取など)の出現

 乱立するベストプラクティス(BCP / RFC)

セキュリティを担保するため、後追いで数多くのセキュリティベストプラクティス文書(BCPや追加RFC)が個別に追加され、その結果、仕様やドキュメントが分散し、「開発者が安全な最新仕様を正しく理解して実装する」ことが困難に

3. OAuth 2.1の目的:セキュリティ新標準への統合

こうした課題を解決するために作られたのが OAuth 2.1 です。

OAuth 2.1の目的は、個別に乱立してしまったベストプラクティスを1つの仕様に統合し、「開発者がデフォルトで安全に実装できる新標準」として再定義することにあります。

過去の仕様から危険な仕組み(Implicit FlowやPassword Grantなど)を削ぎ落とし、PKCE や DPoP といった最新の安全な標準を組み込むことで、迷わずセキュアな認証・認可機能を組み込める環境を整えています。

OAuth 2.0からOAuth 2.1への主要な変更点

OAuth 2.1では、セキュリティ向上と実装のシンプル化を目的として、OAuth 2.0で使われていた危険なフローの廃止やルールの厳格化が行われています。

1. PKCEがすべてのクライアントで必須化

OAuth 2.0: モバイルアプリなど一部のパブリッククライアント向け推奨
OAuth 2.1: すべてのクライアントで必須化

認可コード横取り攻撃を防ぐ拡張機能「PKCE(Proof Key for Code Exchange)」が、Webサーバー等のコンフィデンシャルクライアントを含むすべての環境で必須となりました。

2. Implicit Flowの廃止

OAuth 2.0: ブラウザ等で直接トークンを受け取るフローが存在
OAuth 2.1: 仕様から完全に廃止

アクセストークンがURLフラグメント経由で露出し、アクセスログやブラウザ履歴から漏洩するリスクが高かったため廃止されました。代わりに「PKCEを組み合わせた認可コードフロー」を使用します。

3. Password Grantの廃止

OAuth 2.0: ユーザーのID/パスワードをクライアントが直接受け取る方式が存在
OAuth 2.1: 仕様から完全に廃止

クライアントアプリに直接パスワードを渡す必要があり、「サードパーティに資格情報を預けない」というOAuth本来の目的に反するため非推奨・廃止となりました。

4. リダイレクトURIの完全一致チェック義務化

OAuth 2.0: 前方一致やワイルドカードによる検証も許容
OAuth 2.1: 完全一致の検証を義務化

曖昧なURI検証を利用したオープンリダイレクト脆弱性や、認可コード奪取の攻撃を防ぐため、事前に登録されたリダイレクトURIと完全に一致するか確認することが必須となりました。

5. DPoP(Demonstrating Proof-of-Possession)等の推奨

OAuth 2.0: トークンは基本 Bearer(持っている人なら誰でも使える)
OAuth 2.1: DPoPなどの送信者拘束(Sender-Constrained)メカニズムを推奨

従来のBearerトークンでは、通信経路で盗まれた場合に第三者に悪用される危険がありました。DPoPを利用することで「トークンとクライアントの公開鍵」を結びつけ、安全性を大幅に向上させることができます。DPoPの詳細は後程解説します。

6.URLクエリ文字列でのBearerトークン送信を禁止

OAuth 2.0(RFC 6750)では許可されていた「URLのクエリパラメータ(`?access_token=xxx`)にアクセス・トークンを載せて送信する手法」が完全に禁止されました。ブラウザ履歴やサーバーアクセスログからのトークン漏洩を回避するため、リクエストヘッダー(`Authorization: Bearer …`)等での送受信に限定されます。

7.リフレッシュトークンの保護強化(ローテーション必須化等)

パブリッククライアント(SPAやモバイルアプリなど)でリフレッシュトークンを扱う場合、利用ごとに新しいリフレッシュトークンを発行・刷新する「RefreshToken Rotation」または「送信者拘束(Sender-Constrained)」を適用することが義務付けられました。

DPoP(Demonstrating Proof-of-Possession)の動作シーケンス解説

DPoPは、アクセストークンを発行されたクライアント自身しか使えないように「送信者拘束(Sender-Constrained)」を行う仕組みです。
ここでは、DPoPを利用したログインからAPI呼び出しまでの全体の流れを、こちらのシーケンス図で解説します。

🔑 事前準備:鍵ペアの生成

アプリ利用開始時、クライアント側で鍵ペア(公開鍵 / 秘密鍵)を生成しておきます。この秘密鍵を用いて以降のリクエスト(DPoP Proof)に署名を行います。

フェーズ 1:認可コードの取得(ステップ 1〜5)

1. 認可リクエスト: ユーザーがアプリの利用を開始すると、クライアントは認可サーバーへ認可リクエストを送信します。
2. ログイン・同意: 認可サーバーがログイン画面を表示し、ユーザーは認証・認可の同意を行います。
3. 認可コード返却: 認可サーバーからクライアントへ「認可コード」が返却されます。

フェーズ 2:DPoP Proofの生成とトークン取得(ステップ 6〜7)

6:DPoP Proof 1 (JWT) の作成とトークンリクエスト: クライアントは、自身の公開鍵・ペイロード・秘密鍵を用いて署名した「DPoP Proof 1 (JWT)」を作成します。
取得した認可コードと一緒に「DPoP Proof 1」を添えて認可サーバーへトークンリクエストを送信します。
7:認可サーバーでの検証とアクセストークン発行: 認可サーバーは以下の検証を行った上でアクセストークンを返却します。

① DPoP Proofから公開鍵を取得
② DPoP Proofの署名を検証
③ アクセストークン内に公開鍵(のハッシュ値等)を埋め込んで返却

フェーズ 3:リソースサーバーへのAPIリクエスト(ステップ 8〜9)

8:DPoP Proof 2 (JWT) の作成とAPI呼び出し: APIを呼び出す際、クライアントは新たに「DPoP Proof 2 (JWT)」を作成します。
アクセストークンと「DPoP Proof 2」の両方を指定して、リソースサーバーへAPIリクエストを送信します。
9:リソースサーバーでの検証とレスポンス返却: リソースサーバーは以下の通りトークンとリクエストの妥当性を確認し、問題がなければレスポンスを返します。

① DPoP Proofから公開鍵を取得
② DPoP Proofの署名を検証
③ アクセストークン内の公開鍵と、Proofの公開鍵が一致することを確認

💡 なぜこれで安全になるのか?

万が一アクセストークンが第三者に盗まれたとしても、攻撃者はクライアントの「秘密鍵」を持っていないため、有効なDPoP Proofを作成できません。そのため、リソースサーバー側で検証エラーとなり、不正利用を防ぐことができます。

まとめ

今回は、OAuth 2.1が必要とされる背景と主要な変更点、そしてDPoPの動作シーケンスについて解説しました。

記事のポイントを振り返ると以下の通りです。

  • OAuth 2.1の狙い: 乱立していたセキュリティベストプラクティスを統合し、開発者が「最初から迷わず安全に実装できる」標準仕様を確立すること。
  • 不要・危険な仕様の排除: PKCEの必須化やImplicit Flow / Password Grantの廃止など、現代のクライアント環境に合わせた厳格化。
  • DPoPによる強力な保護: クライアントの鍵ペアでリクエストごとに署名(DPoP Proof)を行うことで送信者拘束を実現し、アクセストークン単体の漏洩による不正利用を防止。

Webやモバイルを問わず、フロントエンドでトークンを扱うアーキテクチャが一般化している今、アクセストークンの保護はこれまで以上に重要視されています。
従来のBearerトークンから脱却し、OAuth 2.1やDPoPを取り入れたより堅牢な認証・認可基盤の設計・実装をぜひ検討してみてください。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。
エンジニア募集中!

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です