7. Protected Resource Access (保護されたリソースへのアクセス)
7. Protected Resource Access (保護されたリソースへのアクセス)
DPoP で保護されたリソースへのリクエストには、第 4 節で説明した DPoP 証明と、第 7.1 節で説明したアクセストークンの両方が含まれている必要があります。DPoP 証明には、関連するアクセストークンの有効なハッシュ値を含む ath クレームが含まれていなければなりません。
このようにトークン値を証明にバインドすることで、あるリクエストの証明が、異なるリクエストで複数の異なるアクセストークン値とともに使用されるのを防ぎます。たとえば、クライアントが 2 人の異なるリソース所有者にバインドされたトークン AT1 と AT2 を保持しており、認可サーバーとの対話に同じ鍵を使用している場合、これらのトークンが交換される可能性があります。ath フィールドによるバインディングがない場合、AT1 に適用されたキャプチャされた署名が AT2 とともにリプレイされ、意図されたリクエストの権限とアクセスが変更される可能性があります。同じクライアントとリソース所有者の組み合わせ内でローテーションされるアクセストークンの場合、ローテーションされたトークン値には新しい証明の計算が必要になるため、そのような置換防止は依然として有効です。このバインディングはまた、アクセストークンとともに使用されることを意図した証明がアクセストークンなしでは使用できないこと、およびその逆も保証します。
リソースサーバーは、提示されたトークン値のハッシュを計算し、それが ath フィールドのハッシュ値と同じであることを確認する必要があります(第 4.3 節を参照)。ath フィールド値は DPoP 証明の署名によってカバーされるため、それを含めることで、アクセストークン値は署名の生成に使用された鍵の所有者にバインドされます。
ath フィールドだけでは DPoP 証明のリプレイを防ぐことはできず、証明が提示されたリクエストへのバインディングも提供しないことに注意してください。証明のチェック時間枠と、htm や htu などの含まれるメッセージパラメータは依然として重要です。
7.1. DPoP 認証スキーム
DPoP バインドされたアクセストークンは、[RFC9110] セクション 11.6.2 に従い、認証スキーム DPoP の Authorization リクエストヘッダーフィールドを使用して送信されます。DPoP スキームの Authorization ヘッダーフィールドの構文は、クレームに対して [RFC9110] セクション 11.2 で定義されている token68 構文を使用します。便宜上、以下に再掲します。DPoP 認証スキームのクレームの ABNF 表記構文は以下のとおりです。
token68 = 1*( ALPHA / DIGIT /
"-" / "." / "_" / "~" / "+" / "/" ) *"="
credentials = "DPoP" 1*SP token68
図 12: DPoP 認証スキーム ABNF
このようなアクセストークンの場合、リソースサーバーは、HTTP リクエストの DPoP ヘッダーフィールドでも DPoP 証明を受信していること、DPoP 証明を第 4.3 節のルールに従ってチェックすること、および DPoP 証明の公開鍵がアクセストークンがバインドされている公開鍵と一致することを第 6 節に従ってチェックしなければなりません (MUST)。
すべてのチェックが成功しない限り、リソースサーバーはリソースへのアクセスを許可してはなりません (MUST NOT)。
図 13 は、DPoP バインドアクセストークンを Authorization ヘッダーに、DPoP 証明を DPoP ヘッダーに持つ、保護されたリソースへのリクエストの例を示しています。この例では、[RFC8792] に従って "\" を使用して行を折り返しています。図 14 は、その DPoP 証明のデコードされた内容を示しています。JWT ヘッダーとペイロードの JSON は表示されていますが、署名部分は省略されています。通常どおり、書式設定と読みやすさのために、改行とインデントが含まれています。
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIj\
oiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0Z\
WRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOCwiYXRoIjoiZlVIeU8ycjJaM0RaNTNF\
c05yV0JiMHhXWG9hTnk1OUlpS0NBcWtzbVFFbyJ9.2oW9RP35yRqzhrtNP86L-Ey71E\
OptxRimPPToA1plemAgR6pxHF8y6-yqyVnmcw6Fy1dqd-jfxSYoMxhAJpLjA
図 13: DPoP で保護されたリソースリクエスト
{
"typ":"dpop+jwt",
"alg":"ES256",
"jwk": {
"kty":"EC",
"x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
"y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
"crv":"P-256"
}
}
.
{
"jti":"e1j3V_bKic8-LAEB",
"htm":"GET",
"htu":"https://resource.example.org/protectedresource",
"iat":1562262618,
"ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo"
}
図 14: 図 13 の DPoP 証明 JWT のデコードされた内容
DPoP 認証を必要とする保護空間内の保護されたリソースへのリクエストを受信した際に、リクエストに有効な資格情報が含まれていないか、アクセスに不十分なアクセストークンが含まれている場合、サーバーはクライアントに対して DPoP 認証情報の提供を求めるチャレンジを含むレスポンスを返すことができます。このチャレンジは、401(Unauthorized)レスポンスステータスコード([RFC9110] セクション 15.5.2)と WWW-Authenticate ヘッダーフィールド([RFC9110] セクション 11.6.1)を使用して送信されます。サーバーは、他の条件への応答として WWW-Authenticate ヘッダーを含めることもできます。
これらのチャレンジにおいて:
- スキーム名は DPoP です。
- 保護範囲を示すために、[RFC9110] セクション 11.5 で説明されているように、認証パラメータ realm を含めることができます。
- [RFC6750] セクション 3 で定義されている scope 認証パラメータを含めることができます。
- リクエストにアクセストークンが含まれていたが認証に失敗した場合、リクエストが拒否された理由を示すために error パラメータ([RFC6750] セクション 3)を含めるべきです (SHOULD)。[RFC6750] セクション 3.1 で説明されている error パラメータ値、および拡張機能によって定義された適切な値が適用可能です。値 use_dpop_nonce は、第 9 節で説明されているように、後続のリクエストの DPoP 証明にノンスが必要であることを通知するために使用できます。また、invalid_dpop_proof は、第 4.3 節の基準に従って DPoP 証明自体が無効であると見なされたことを示すために使用されます。
- エンドユーザーへの表示を意図していない、開発者向けの人間が読める説明を提供するために、error パラメータとともに error_description パラメータ([RFC6750] セクション 3)を含めることができます。
- DPoP 証明 JWT に使用できる JWS アルゴリズムをクライアントに示すために、algs パラメータを含めるべきです。このパラメータの値は、スペース区切りの JWS alg (Algorithm) ヘッダー値のリストです([RFC7515] セクション 4.1.1)。
- その他の認証パラメータを使用することができ、不明なパラメータは受信側によって無視されなければなりません。
図 15 は、認証なしでの保護されたリソースへのリクエストに対するレスポンスを示しています。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP algs="ES256 PS256"
図 15: 認証なしの保護されたリソースリクエストに対する HTTP 401 レスポンス
図 16 は、アクセストークンの DPoP バインディング確認が失敗したため拒否された、保護されたリソースリクエストへのレスポンスを示しています。図 16 では、[RFC8792] に従って "\" を使用して行を折り返しています。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: DPoP error="invalid_token", \
error_description="Invalid DPoP key binding", algs="ES256"
図 16: 無効なトークンを含む保護されたリソースリクエストに対する HTTP 401 レスポンス
Cross-Origin Resource Sharing (CORS) [WHATWG.Fetch] を使用するブラウザベースのクライアントアプリケーションは、デフォルトで CORS セーフリストレスポンス HTTP ヘッダーにしかアクセスできないことに注意してください。アプリケーションが WWW-Authenticate HTTP レスポンスヘッダー値を取得して使用できるようにするには、サーバーは Access-Control-Expose-Headers レスポンスヘッダーリスト値に WWW-Authenticate を含めることで、アプリケーションが利用できるようにする必要があります。
この認証スキームは、オリジンサーバー認証専用です。したがって、この認証スキームは、Proxy-Authenticate または Proxy-Authorization ヘッダーフィールドとともに使用してはなりません (MUST NOT)。
この認証スキームの Authorization ヘッダーフィールド構文は、[RFC6750] セクション 2.1 で定義されている Bearer スキームの使用法に従っていることに注意してください。これは [RFC9110] の推奨される資格情報構文ではありませんが、その中の一般的な認証フレームワークと互換性があり、Bearer スキームとの整合性と親しみやすさのために使用されています。
7.2. Bearer 認証スキームとの互換性
DPoP スキームと Bearer スキームの両方をサポートする保護されたリソースは、DPoP バインドされたアクセストークンのダウングレード使用を防ぐために、Bearer トークンの評価手順を更新する必要があります。具体的には、そのような保護されたリソースは、Bearer トークン([RFC6750] に準拠)として受信した DPoP バインドアクセストークンを拒否しなければなりません (MUST)。
[RFC9110] のセクション 11.6.1 では、保護されたリソースが 401 (Unauthorized) レスポンスの WWW-Authenticate ヘッダーフィールドを介して複数の認証スキーム(つまり、Bearer と DPoP)のサポートを示すことができます。
[RFC6750] のみをサポートし、DPoP を認識しない保護されたリソースは、DPoP バインドされたアクセストークンを Bearer トークンとして受け入れる可能性が最も高いです(JWT [RFC7519] は認識されないクレームを無視するとしており、Introspection [RFC7662] は他のパラメータが存在する可能性があるが、その存在に対する機能要件はないとしており、[RFC6750] は有効性に関連するアクセストークンの内容について実質的に沈黙しています)。したがって、クライアントは、保護されたリソースからの WWW-Authenticate: Bearer チャレンジを受信したとき(または、事前に保護されたリソースの機能についての知識がある場合は、いつでも)、Bearer スキームを使用して DPoP バインドされたアクセストークンを送信する可能性があります。これにより、保護されたリソースの DPoP サポートへの段階的なアップグレード、または保護されたリソースのトークンタイプサポートが混在する長期的な展開のロジスティクスが簡素化される可能性があります。
Bearer スキームと DPoP スキームの両方をサポートする保護されたリソースが複数の WWW-Authenticate チャレンジで応答することを選択した場合、どのチャレンジが実際のエラー情報を伝達すべきかに注意する必要があります。以下のルールに従うことが推奨されます。
-
リクエストに認証情報が含まれていない場合、[RFC6750] セクション 3.1(図 17)で説明されているように、チャレンジにエラーコードやその他のエラー情報を含めるべきではありません。
-
認証を試みたメカニズムが明確に確立できる場合、対応するチャレンジを使用してエラー情報を伝達すべきです(図 18)。
-
それ以外の場合、Bearer チャレンジと DPoP チャレンジの両方を使用してエラー情報を伝達することができます(図 19)。
以下の例では、[RFC8792] に従って "\" を使用して行を折り返しています。
GET /protectedresource HTTP/1.1
Host: resource.example.org
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer, DPoP algs="ES256 PS256"
図 17: 認証なしの保護されたリソースリクエストに対する HTTP 401 レスポンス
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: Bearer INVALID_TOKEN
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", \
error_description="Invalid token", DPoP algs="ES256 PS256"
図 18: 無効な認証による保護されたリソースリクエストに対する HTTP 401 レスポンス
GET /protectedresource HTTP/1.1
Host: resource.example.org
Authorization: Bearer Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
Authorization: DPoP Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU
HTTP/1.1 400 Bad Request
WWW-Authenticate: Bearer error="invalid_request", \
error_description="Multiple methods used to include access token", \
DPoP algs="ES256 PS256", error="invalid_request", \
error_description="Multiple methods used to include access token"
図 19: 曖昧な認証による保護されたリソースリクエストに対する HTTP 400 レスポンス
7.3. クライアントに関する考慮事項
DPoP 証明を含む認可リクエストは、べき等 (idempotent) でない可能性があります(サーバーによる jti, iat, および nonce クレームの強制に依存します)。そのため以前はべき等であった保護されたリソースへのリクエストが、もはやそうではなくなる可能性があります。通常は一時的な HTTP エラーとして理解されるレスポンスに対するべき等なリクエストを再試行する場合でも、クライアントは一意の DPoP 証明を生成することが推奨されます。
頻繁にネットワークエラーが発生するクライアントは、より厳格なノンス検証を実装しているサーバーと対話する際に、追加の課題に直面する可能性があります。