- クライアントの公開鍵 (
jwk) 。 - メソッド (
htm) と URI (htu) を含む、アクセストークンrequestを参照するpayload。 - クライアントの秘密キーを使用して作成された署名。
- リプレイ防止のための一意の ID (
jti) 。 - API request ごとに含まれる、アクセストークンの base64url エンコードされた SHA-256 ハッシュ (
ath) 。 - 任意: の場合、クライアントアプリケーションが最近 DPoP Proof JWT を生成したことを保証するための
nonceclaim。
一般的な利用例
代表的な DPoP の利用例をいくつか紹介します。- Single Page Applications (SPAs) and mobile applications: 公開クライアントである SPA やモバイルアプリケーションには、バックエンドサーバーのような、 を安全に保存できる信頼された機密環境がありません。そのため、トークン盗難に対して脆弱です。DPoP は、アクセストークンをクライアントアプリケーションの公開キーに結び付けて DPoP Proof JWT を作成することで、このセキュリティ脆弱性に対処します。クライアントアプリケーションは、自身の秘密キーで DPoP Proof JWT に署名し、認可リクエストで送信します。Auth0 Authorization Server は DPoP Proof JWT を検証し、有効であれば、発行するアクセストークンをクライアントの公開キーに結び付けます。
- Third-party API integrations: クライアントアプリケーションと連携した AI エージェントが、ユーザーに代わって DPoP Proof JWT を使用してサードパーティ API を呼び出す場合、 は、そのリクエストが権限のない第三者ではなく AI エージェントから送信されたものであることを、暗号学的に検証できます。
サポートされているアプリケーションのグラントタイプ
Auth0 は、DPoP を使用した送信者拘束向けに、次のアプリケーションのグラントタイプをサポートしています。仕組み
次のシーケンス図は、Auth0 DPoP フローの概要を示しています。
- Auth0 Authorization Server にアクセストークンをリクエストする際、クライアントアプリケーションは一意の暗号鍵ペアを生成し、公開キーを使って対応する秘密キーを保有していることを証明します。
- クライアントアプリケーションは DPoP Proof JWT を生成し、それを Auth0 Authorization Server の /token エンドポイントに送信します。
- Auth0 Authorization Server は DPoP Proof JWT を検証し、有効であればアクセストークンを発行して、クライアントの公開キーに紐付けます。
- Customer API を呼び出す前に、クライアントアプリケーションは新しい DPoP Proof JWT を生成し、トークンに紐付けられた秘密キーを保有していることを証明します。クライアントアプリケーションは、DPoP Proof JWT と sender-constrained アクセストークンをリソースサーバーに送信します。
- リソースサーバーは DPoP Proof JWT を検証し、トークンの正当な所有者、つまり元のクライアントアプリケーションだけが、それを使って保護されたリソースに正常にアクセスできることを確認します。リフレッシュトークンからアクセストークンをリクエストする場合、クライアントアプリケーションは新しい DPoP Proof JWT を生成し、リフレッシュトークンがクライアントの公開キーに紐付けられるようにします。
Auth0 で DPoP を使用してトークンに送信者拘束を適用する
次の図は、Auth0 で DPoP を使用してトークンに送信者拘束を適用するエンドツーエンドのフローを示しています。
- 前提条件
- ステップ 1: クライアントアプリケーションが DPoP キーペアを生成する
- ステップ 2: クライアントアプリケーションが DPoP Proof JWT を作成する
- ステップ 3: クライアントアプリケーションが DPoP にバインドされたトークンを要求する
- ステップ 4: Auth0 Authorization Server が DPoP Proof JWT を検証する
- ステップ 5: クライアントアプリケーションが DPoP にバインドされたトークンと DPoP Proof JWT を使って API を呼び出す
- ステップ 6: DPoP を使用したトークンのリフレッシュを処理する
前提条件
開始する前に、次の点を確認してください。- クライアントアプリケーションとリソースサーバーに対して、送信者拘束を設定していること。
ステップ1: クライアントアプリケーションがDPoPキーペアを生成する
DPoPでは、クライアントアプリケーションは非対称暗号のキーペアを生成する必要があります。Auth0は、ES256キーなどの楕円曲線暗号の使用をサポートしています。このキーペアはクライアントアプリケーションごとに固有のもので、たとえばハードウェアで保護されたキーストアに安全に保管する必要があります。 クライアントアプリケーションは秘密鍵を厳重に保持しつつ、ステップ2で「Proof of Possession」として機能するDPoP Proof JSON Web トークン (JWT) に公開鍵を含めます。ステップ 2: クライアントアプリケーションが DPoP Proof JWT を作成する
Auth0 Authorization Server の/token エンドポイントに DPoP にバインドされたアクセストークンをリクエストする前に、クライアントアプリケーションは DPoP Proof JWT を作成する必要があります。DPoP Proof JWT は、クライアントの秘密キーで署名された JSON Web トークン (JWT) で、「Proof of Possession (所持証明) 」として機能します。
DPoP Proof JWT は、JWT ヘッダーと、トークンリクエストに関連するクレームを含むペイロードで構成されます。
JWTヘッダーのクレーム
JWT ペイロードクレーム
クライアントアプリケーションで DPoP Proof JWT を作成したら、Step 1 で生成した秘密キーを使って DPoP Proof JWT に署名します。
以下のコードサンプルは、クライアントアプリケーションで DPoP Proof JWT を作成して署名する方法を示しています。
ステップ 3: クライアントアプリケーションが DPoP-bound token をリクエストする
クライアントアプリケーションが Auth0 Authorization Server の/token エンドポイントに access token をリクエストする際は、リクエストの HTTP ヘッダーに DPoP Proof JWT を含めます。
- 署名付き DPoP Proof JWT を使用して、DPoP HTTP ヘッダーに値を設定します。
- 署名付き DPoP Proof JWT を含む DPoP HTTP ヘッダーを、
/tokenエンドポイントへのアクセストークンリクエストで送信します。 - Auth0 認可サーバーからのレスポンスを処理します。
パブリッククライアント
シングルページアプリケーション (SPA) やモバイルアプリなどのパブリッククライアントが DPoP にバインドされたアクセストークンをリクエストする場合、client secret やその他のクライアント認証パラメーターは使用できません。この場合、RFC 9449 に従い、Auth0 はクライアントアプリケーションが DPoP Proof JWT を直近で生成したことを確認するため、DPoP HTTP header に 値が含まれていることを求めます。これは想定どおりの動作であり、認可サーバーが DPoP proof の新しさを確認し、その proof を使用できる時間を限定できるようにするためです。
パブリッククライアントが /token request を行う際に、DPoP HTTP header に nonce 値を含めない場合、Auth0 は HTTP 400 コードと、次のようなエラーメッセージを返します。
DPoP-Nonce ヘッダーを含めます。これは、DPoP specification で定義されている標準の「challenge-response」フローに従ったものです。DPoP-Nonce ヘッダーの値を使用して DPoP proof を再生成し (Step 2 と同様) 、その値を含む nonce クレームを追加したうえで、/token エンドポイントへのリクエストを再送信する必要があります。
次のコードサンプルは、パブリッククライアントから nonce クレームを含む /token リクエストを送信し、その後再試行する際のエンドツーエンドのフローを示しています。
ステップ 4: Auth0 Authorization Server が DPoP Proof JWT を検証する
Auth0 Authorization Server はトークンリクエストを受信すると、次の処理を行います。- DPoP Proof JWT、その公開キー、署名を抽出します。
- 提供された公開キーを使用して署名を検証します。
htm、htu、jti,、iatの各クレームを検証します。- 有効であれば、アクセストークンを発行します。Auth0 Authorization Server は、確認用クレーム
cnfをアクセストークンに含めます。cnfクレームには、DPoP Proof JWT から取得した公開キーの thumbprint (ハッシュ) が含まれます。これをアクセストークンに含めることで、Auth0 Authorization Server はそのアクセストークンを特定の公開キーに関連付けます。つまり、アクセストークンを “sender-constrains” します。 - トークンレスポンスでは、
Authorizationヘッダーのtoken_typeをBearerではなくDPoPに設定します。通常、アクセストークンをAuthorizationヘッダーで渡す場合、token_typeはBearerに設定されます。しかし、ここでは DPoP を使用して公開キーに関連付けられたアクセストークンを渡すため、代わりにDPoPに設定されます。 - その後、Auth0 Authorization Server は DPoP sender-constrained アクセストークンをクライアントアプリケーションに発行します。
ステップ 5: クライアントアプリケーションが DPoP-bound token と DPoP Proof JWT を使用して API を呼び出す
DPoP を強制するリソースサーバーに対する API 呼び出しごとに、クライアントアプリケーションは DPoP-bound access token と新しい DPoP Proof JWT の両方を提示する必要があります。 DPoP は、すべての API リクエストで DPoP Proof JWT を必須にすることで、秘密キーを保持するクライアントアプリケーションだけがアクセストークンを使用できるようにします。 新しい API リクエストでは、クライアントアプリケーションは次のことを行います。- 次のクレームを含む新しい DPoP Proof JWT を生成します。
htmクレームは、GETやPOSTなどの API リクエストのHTTPメソッドです。htuクレームは、API リクエストの URI です。athクレームは、ステップ 3 で受け取った DPoP-bound access token の base64url エンコードされた SHA-256 ハッシュです。
- クライアントの秘密キーを使って、新しい DPoP Proof JWT に暗号学的に署名します。
-
DPoP認証スキームを使用して、Authorizationヘッダーに DPoP-bound access token を含めます。
- 新たに生成した DPoP Proof JWT を
DPoPHTTP ヘッダーに含めます:
DPoP HTTPヘッダーには、追加のathクレームを含める必要があります。athクレームは、発行されたアクセストークンのSHA256ハッシュをbase64urlエンコードしたものです。
リソースサーバーは次の処理を行います。
- APIリクエストを受信し、アクセストークン、DPoP Proof JWT、公開キー、署名を抽出します。
jwkヘッダー内の公開キーを使用して、DPoP Proof JWTの署名を検証します。htm、htu、jti、iat、athの各クレームを検証します。- DPoP Proof JWTの
jwkヘッダーで示された公開キーが、アクセストークン内のcnf.jktクレームによってアクセストークンに関連付けられた公開キーと一致することを検証します。
jtiのリプレイ保護の実装はリソースサーバーの責任です。すべてのAuth0 SDKsがデフォルトでjtiのリプレイ保護を強制するわけではありません。/userinfoエンドポイントを呼び出します。
ステップ 6: DPoP を使用してトークンの更新を処理する
DPoP にバインドされたアクセストークンの有効期限が切れた場合は、新しいアクセストークンを取得するために を使用できます。リフレッシュトークンのリクエストには、元のトークンリクエストで使用したものと同じキーペアで生成した DPoP Proof JWT が必要です。 以下では、Auth0 における DPoP を使用したリフレッシュトークンのフローについて説明します。 クライアントアプリケーションは次を行います。- Auth0 認可サーバーの
/tokenエンドポイントに、リフレッシュトークンのリクエストを送信します。 - リフレッシュトークンのリクエスト用に DPoP Proof JWT を生成します (ステップ 2 と同様ですが、
htmはPOST、htuは の URI です) 。 DPoPHTTP ヘッダーに DPoP Proof JWT を含めます。
- DPoP Proof JWT を検証し (ステップ 4 と同様) 、新しい DPoP バインドアクセストークンを発行します。
重要な考慮事項
クライアントアプリケーションに DPoP を実装する際は、次の点を考慮してください。- 秘密キーのセキュリティ: DPoP 実装の安全性はクライアントの秘密キーの安全性に依存するため、不正アクセスから保護する必要があります。秘密キーは、ハードウェアに裏打ちされた領域で生成および保管し、エクスポート不可に設定する必要があります。
- リプレイ保護 (
jti** とdpop-nonce):** DPoP Proof JWT のjtiクレームは、/userinfoエンドポイントなどの保護されたリソースに対するリプレイ攻撃の防止に役立ちます。Auth0 Authorization Server はレスポンスでDPoP-NonceHTTP ヘッダーを返し、公開クライアントはリプレイ保護を強化するために、後続の DPoP Proof JWT にこれをnonceクレームとして含める必要があります。 - レート制限: DPoP のチャレンジレスポンスフローでは、最初のリクエストの後にサーバーから提供された nonce を使って再試行が必要になる場合があるため、各やり取りは実質的に Auth0 テナントのレート制限 に対して 2 回のリクエストとしてカウントされます。アプリケーションのリクエスト量がこのオーバーヘッドを考慮していることを確認してください。
- エラー処理:
invalid_dpop_proofやuse_dpop_nonceなど、Auth0 Authorization Server またはリソースサーバーから返される DPoP 固有のエラーを処理するロジックは、お客様側で実装する必要があります。 - クライアントの種類: クライアントシークレットを安全に保管できない Single Page Applications (SPAs) やモバイルアプリなどの公開クライアントには DPoP を使用してください。には、クライアントシークレットを持つバックエンドサービスなどが含まれます。DPoP はセキュリティをさらに強化しますが、これらにはすでに他の sender-constraining の仕組みがあります。
- パフォーマンス: API 呼び出しごとに DPoP Proof JWT を生成して署名すると、わずかなオーバーヘッドが追加されるため、クライアントアプリケーションの暗号処理が効率的であることを確認してください。
- キーのローテーション: セキュリティを強化するために、DPoP のキー ペアをローテーションする strategy を実装してください。同じセッションでは必ず同じキー ペアを使用してください。
- 永続化: セッションを維持し、DPoP-bound access token を再利用する必要があるクライアントアプリケーション (長期間利用される SPA など) では、アプリケーションの再読み込み後も、最初に生成したキー ペアを安全に保存し、再取得できるようにしてください。新しいキー ペアが生成されたり、別のキー ペアが使用されたりすると、DPoP-bound access token は元のペアの公開キーに暗号学的に結び付けられているため無効になります。たとえば、ブラウザーの
IndexedDBやモバイルアプリの安全なストレージにキー ペアを保存できます。