RFC 7519 準拠の JSON Web トークン(JWT)は、API Gateway がリクエストを認証するために使用する便利な方法です。API Gateway は、ユーザーの公開 JSON Web キー(JWK)をホストし、これらの JWK を使用してリクエスト内の JWT に署名および認証を行います。その後、API Gateway はクレーム パラメーターをバックエンドパラメーターとしてバックエンドサービスに転送します。これにより、バックエンドアプリケーションの開発が簡素化されます。このトピックでは、JWT 認証プラグインを構成する方法について説明します。JWT と認証プロセスの詳細については、「JWT ベースの認証」をご参照ください。
は、 と同じ機能を提供し、以下の利点があります。
追加の
認証 API 操作を構成する必要はありません。JWTは、複数の方法で生成および配布できます。API Gateway は、公開 JWKを使用したJWTの認証のみを担当します。kidが指定されていないJWKがサポートされています。複数の
JWKを構成できます。リクエストの
ヘッダーまたはクエリパラメーターからトークン情報を読み取ることができます。JWT 認証プラグインを使用することで、リクエストの Cookie ヘッダーからトークンを読み取ることもできます。
Authorization bearer {token}などの Authorization ヘッダーでJWTを送信する場合、parameterを Authorization に、parameterLocationを header に設定することで、トークン情報を正しく読み取ることができます。preventJtiReplayを true に設定すると、jtiクレームベースのリプレイ防止チェックがサポートされます。bypassEmptyTokenを true に設定すると、トークンを含まないリクエストを検証なしでバックエンドサービスに転送できます。ignoreExpirationCheckを true に設定すると、トークンのexp設定の検証をスキップできます。
JWT 認証プラグインを構成し、OpenID Connect 機能が構成されているAPI にバインドすると、JWT 認証プラグインがOpenID Connect 機能の代わりに有効になります。
1. JWK を取得する
RFC 7517 に準拠した JWK を使用して、JWT に署名し、認証します。JWT 認証プラグイン を構成する場合、有効な JWK を手動で、または mkjwk.org などのオンライン JWK ジェネレーター を使用して生成する必要があります。次の例は、有効な JWK を示しています。JWK の例では、秘密鍵を使用してトークンに署名し、公開鍵は JWT 認証プラグイン で署名を認証するように構成されています。
{
"kty": "RSA",
"e": "AQAB",
"kid": "O9fpdhrViq2zaaaBEWZITz",
"use": "sig",
"alg": "RS256",
"n": "qSVxcknOm0uCq5vGsOmaorPDzHUubBmZZ4UXj-9do7w9X1uKFXAnqfto4TepSNuYU2bA_-tzSLAGBsR-BqvT6w9SjxakeiyQpVmexxnDw5WZwpWenUAcYrfSPEoNU-0hAQwFYgqZwJQMN8ptxkd0170PFauwACOx4Hfr-9FPGy8NCoIO4MfLXzJ3mJ7xqgIZp3NIOGXz-GIAbCf13ii7kSStpYqN3L_zzpvXUAos1FJ9IPXRV84tIZpFVh2lmRh0h8ImK-vI42dwlD_hOIzayL1Xno2R0T-d5AwTSdnep7g-Fwu8-sj4cCRWq3bd61Zs2QOJ8iustH0vSRMYdP5oYQ"
} 上記の JWK は JSON 形式です。YAML 形式で JWT 認証プラグインを構成する場合は、YAML 形式の JWK を使用する必要があります。
JWT 認証プラグインでは、公開鍵のみを構成する必要があります。秘密鍵は安全に保管してください。次の表に、JWT 認証プラグインでサポートされている署名アルゴリズムを示します。
署名アルゴリズム | サポートされている |
SHA-2 を使用した RSASSA-PKCS1-V1_5 | RS256、RS384、RS512 |
SHA-2 を使用した楕円曲線(ECDSA) | ES256、ES384、ES512 |
SHA-2 を使用した HMAC | HS256、HS384、HS512 |
HS256、HS384、または HS512 タイプのキーを構成する場合、キー値は base64url エンコードされます。署名が有効でない場合は、キーがトークンの生成に使用されたキーと同じ形式であるかどうかを確認してください。
2. 構成
JSON 形式または YAML 形式で JWT 認証プラグインを構成できます。これらの 2 つの形式は同じスキーマを使用しているためです。yaml to json ツールを使用して、プラグイン構成の形式を変換できます。次の例は、YAML 形式のプラグイン構成テンプレートを示しています。
---
parameter: X-Token # JWT が読み取られるパラメーター。API パラメーターに対応します。
parameterLocation: header # JWT が読み取られる場所。有効な値: query および header。バインドされた API のリクエストモードがマップ(不明なパラメーターを除外)またはマップ(不明なパラメーターをパススルー)に設定されている場合、このパラメーターはオプションです。バインドされた API のリクエストモードがパススルーに設定されている場合、このパラメーターは必須です。
preventJtiReplay: false # jti のリプレイ防止チェックを有効にするかどうかを制御します。デフォルト値: false。
bypassEmptyToken: false # トークンを含まないリクエストを検証なしでバックエンドサービスに転送するかどうかを制御します。
ignoreExpirationCheck: false # exp 設定の検証を無視するかどうかを制御します。
orAppAuth: false # デフォルト値は false です。Alibaba Cloud アプリ認証と JWT 認証の両方が必要です。値が true の場合、一方の認証が合格すれば、もう一方の認証方法は不要です。
claimParameters: # クレームからパラメーターへの変換。API Gateway は JWT クレームをバックエンドパラメーターにマップします。
- claimName: aud # JWT クレームの名前。公開または非公開にすることができます。
parameterName: X-Aud # JWT クレームがマップされるバックエンドパラメーターの名前。
location: header # JWT クレームがマップされるバックエンドパラメーターの場所。有効な値: query、header、path、および formData。
- claimName: userId # JWT クレームの名前。公開または非公開にすることができます。
parameterName: userId # JWT クレームがマップされるバックエンドパラメーターの名前。
location: query # JWT クレームがマップされるバックエンドパラメーターの場所。有効な値: query、header、path、および formData。
#
# JWK の公開鍵
jwk:
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5vGsOmaorPDzHUubBmZZ4UXj-9do7w9X1uKFXAnqfto4TepSNuYU2bA_-tzSLAGBsR-BqvT6w9SjxakeiyQpVmexxnDw5WZwpWenUAcYrfSPEoNU-0hAQwFYgqZwJQMN8ptxkd0170PFauwACOx4Hfr-9FPGy8NCoIO4MfLXzJ3mJ7xqgIZp3NIOGXz-GIAbCf13ii7kSStpYqN3L_zzpvXUAos1FJ9IPXRV84tIZpFVh2lmRh0h8ImK-vI42dwlD_hOIzayL1Xno2R0T-d5AwTSdnep7g-Fwu8-sj4cCRWq3bd61Zs2QOJ8iustH0vSRMYdP5oYQ
#
# 複数の JWK を構成し、jwk フィールドと一緒に使用できます。
# 複数の JWK が構成されている場合、kid は必須です。JWT に kid が含まれていない場合、kid の整合性チェックは失敗します。
jwks:
- kid: O9fpdhrViq2zaaaBEWZITz # JWK が 1 つだけ構成されている場合、kid はオプションです。JWT に kid が含まれている場合、API Gateway は kid の整合性をチェックします。
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5v....
- kid: 10fpdhrViq2zaaaBEWZITz # JWK が 1 つだけ構成されている場合、kid はオプションです。JWT に kid が含まれている場合、API Gateway は kid の整合性をチェックします。
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5v... JWT 認証プラグインは、parameterおよびparameterLocationの設定に基づいて JWT を取得します。たとえば、parameterが X-Token に設定され、parameterLocationが header に設定されている場合、JWT はX-Tokenヘッダーから読み取られます。API で構成されたパラメーターが
parameterで指定されたパラメーターと同じ名前の場合、parameterLocationを指定しないでください。指定すると、API の呼び出し時にエラーが報告されます。Authorization bearer {token}などの Authorization ヘッダーでトークンを送信する場合、parameterを Authorization に、parameterLocationを header に設定することで、トークン情報を正しく読み取ることができます。preventJtiReplayが true に設定されている場合、JWT 認証プラグインはclaims内のjtiを使用してリプレイ防止チェックを実行します。bypassEmptyTokenが true に設定されていて、リクエストにトークンが含まれていない場合、API Gateway はチェックをスキップし、リクエストをバックエンドサービスに直接転送します。ignoreExpirationCheckが true に設定されている場合、API Gateway はexp設定の検証をスキップします。それ以外の場合、API Gateway はトークンの有効期限が切れているかどうかを確認します。API Gateway がトークン内の
claimsをバックエンドサービスに転送する必要がある場合、tokenParametersを設定して、転送するパラメーターを次のように構成できます:claimName: トークン内のクレームの名前。parameterName: バックエンドサービスに転送されるパラメーターの名前。location: バックエンドサービスに転送されるパラメーターの場所。有効な値:header、query、path、およびformData。このパラメーターが
pathに設定されている場合、バックエンドパスには/path/{userId}など、同じ名前のパラメーターが含まれている必要があります。このパラメーターが
formDataに設定されている場合、バックエンドサービスで受信したリクエストの本文はタイプである必要があります。
jwkフィールドには 1 つのキーのみを構成できます。jwksフィールドには複数のキーを構成することもできます。kidが指定されていないキーは 1 つだけ構成できます。kidが指定されたキーは複数構成できます。kidは一意である必要があります。
2. 構成
JWT 認証プラグインは、
parameterおよびparameterTokenの設定に基づいてトークンを取得します。リクエストにトークンが含まれていない場合でも、API Gateway がバックエンドサービスにリクエストを転送する必要がある場合は、bypassEmptyTokenを true に設定します。複数のキーを設定する場合、次の原則に従ってください。
署名と認証のために、トークン内の
kidの値と同じ ID を持つキーを優先的に選択します。kidが指定されていない場合は、1 つのキーのみを設定できます。トークン内のkidの値と同じ ID を持つキーが存在しない場合は、kidが指定されていないキーを署名と認証に使用します。設定されているすべてのキーに
kid設定が指定されており、リクエスト内のトークンにkidが含まれていないか、kidに一致するキーがない場合は、A403JKエラーが報告されます。
トークンに
iat、nbf、およびexpが含まれている場合、JWT 認証プラグインはそれらの時間形式の有効性を検証します。時間の単位は秒です。デフォルトでは、API Gateway は
expの設定を検証します。検証をスキップする場合は、ignoreExpirationCheckを true に設定します。tokenParametersは、トークンのclaimsから必要なパラメータを抽出するように設定されています。これらのパラメータはバックエンドサービスに転送されます。
4. JWT 認証プラグインのプラグインデータセットを構成する
4.1 JWT 認証プラグインデータセットを作成する
API Gateway コンソール にログオンします。左側のナビゲーションウィンドウで、[API の管理] > [プラグイン] を選択します。
[プラグインリスト] ページで、[プラグインデータセット] タブをクリックします。
右上隅にある [データセットの作成] をクリックします。表示されるダイアログボックスで、データセットの名前を指定し、[タイプ] パラメーターに [JWT_JWK_LIST] を選択して、[確認] をクリックします。
作成したデータセットをクリックします。データセットの詳細ページで、右上隅にある [データセットエントリの作成] をクリックします。[データ値] に JWT 認証プラグインでサポートされている JWK を設定し、[有効期間] に公開鍵の有効期間を設定します。
重要複数の JWK を構成する場合は、異なる KID を使用する必要があります。JWK データ値の順序は、次の例に従って構成する必要があります。
kty: RSA e: AQAB use: sig kid: N3h666 alg: RS256 n: qfzaxmlnl...
4.2 例
---
parameter: X-Token # JWT が読み取られるパラメーター。API リクエストのパラメーターに対応します。
parameterLocation: header # JWT が読み取られる場所。有効な値:query および header。バインドされた API のリクエストモードがリクエストパラメーターマッピング(不明なパラメーターをフィルタリング)またはリクエストパラメーターマッピング(不明なパラメーターをパススルー)に設定されている場合、このパラメーターはオプションです。バインドされた API のリクエストモードがリクエストパラメーターパススルーに設定されている場合、このパラメーターは必須です。
claimParameters: # パラメーターに変換されるクレーム。API Gateway は JWT クレームをバックエンドパラメーターにマッピングします。
- claimName: aud # JWT クレームの名前。公開または非公開にすることができます。
parameterName: X-Aud # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: header # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値:query、header、path、および formData。
- claimName: userId # JWT クレームの名前。公開または非公開にすることができます。
parameterName: userId # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: query # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値:query、header、path、および formData。
preventJtiReplay: false # jti のリプレイ防止チェックを有効にするかどうかを制御します。デフォルト値:false。
ignoreExpirationCheck: true # exp 設定の検証を無視するかどうかを制御します。
jwkListDataSet: cb4f000b6b8244329ac25XXXc8a4f9d6 # データセット ID。データセットが有効にならない場合は、インスタンスをスペックアップするためにチケットを送信してください。
5. 例
5.1 単一の JWK を構成する
---
parameter: X-Token # JWT が読み取られるパラメーター。API リクエストのパラメーターに対応します。
parameterLocation: header # JWT が読み取られる場所。有効な値:query および header。バインドされた API のリクエストモードがリクエストパラメーターマッピング(不明なパラメーターをフィルタリング)またはリクエストパラメーターマッピング(不明なパラメーターをパススルー)に設定されている場合、このパラメーターはオプションです。バインドされた API のリクエストモードがリクエストパラメータパススルーに設定されている場合、このパラメータは必須です。
claimParameters: # パラメーターに変換されるクレーム。API Gateway は JWT クレームをバックエンドパラメーターにマッピングします。
- claimName: aud # JWT クレームの名前。公開または非公開にすることができます。
parameterName: X-Aud # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: header # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値:query、header、path、および formData。
- claimName: userId # JWT クレームの名前。公開または非公開にすることができます。
parameterName: userId # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: query # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値:query、header、path、および formData。
preventJtiReplay: false # jti のリプレイ防止チェックを有効にするかどうかを制御します。デフォルト値:false。
#
# JWK の公開鍵
jwk:
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5vGsOmaorPDzHUubBmZZ4UXj-9do7w9X1uKFXAnqfto4TepSNuYU2bA_-tzSLAGBsR-BqvT6w9SjxakeiyQpVmexxnDw5WZwpWenUAcYrfSPEoNU-0hAQwFYgqZwJQMN8ptxkd0170PFauwACOx4Hfr-9FPGy8NCoIO4MfLXzJ3mJ7xqgIZp3NIOGXz-GIAbCf13ii7kSStpYqN3L_zzpvXUAos1FJ9IPXRV84tIZpFVh2lmRh0h8ImK-vI42dwlD_hOIzayL1Xno2R0T-d5AwTSdnep7g-Fwu8-sj4cCRWq3bd61Zs2QOJ8iustH0vSRMYdP5oYQ
5.2 複数の JWK を構成する
---
parameter: Authorization # トークンを取得するパラメーター。
parameterLocation: header # トークンを取得する場所。
claimParameters: # パラメーターに変換されるクレーム。API Gateway は JWT クレームをバックエンドパラメーターにマッピングします。
- claimName: aud # JWT クレームの名前。公開または非公開にすることができます。
parameterName: X-Aud # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: header # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値:query、header、path、formData。
- claimName: userId # JWT クレームの名前。公開または非公開にすることができます。
parameterName: userId # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: query # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値:query、header、path、formData。
preventJtiReplay: true # jti のリプレイ防止チェックを有効にするかどうかを制御します。デフォルト値:false。
jwks:
- kid: O9fpdhrViq2zaaaBEWZITz # kid は異なる JWK に対して異なる値に設定する必要があります。
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5v....
- kid: 10fpdhrViq2zaaaBEWZITz # kid は異なる JWK に対して異なる値に設定する必要があります。
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5v...5.3. リクエストの Cookie のフィールドからトークンを読み取る
---
parameter: cookie # JWT の読み取り元となるパラメーター。API リクエストのパラメーターに対応します。
parameterLocation: header # JWT の読み取り元となる場所。有効な値: query および header。バインドされた API のリクエストモードがリクエストパラメーターマッピング (不明なパラメーターをフィルタリング) またはリクエストパラメーターマッピング (不明なパラメーターをパススルー) に設定されている場合、このパラメーターはオプションです。バインドされた API のリクエストモードがリクエストパラメーターパススルーに設定されている場合、このパラメーターは必須です。
parameterSection: token # たとえば、cookie パラメーターの値は username=tom ; token=abcsef です。
claimParameters: # パラメーターに変換されるクレーム。API Gateway は JWT クレームをバックエンドパラメーターにマッピングします。
- claimName: aud # JWT クレームの名前。パブリックまたはプライベートを指定できます。
parameterName: X-Aud # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: header # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値: query、header、path、および formData。
- claimName: userId # JWT クレームの名前。パブリックまたはプライベートを指定できます。
parameterName: userId # JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: query # JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値: query、header、path、および formData。
preventJtiReplay: true # jti のリプレイ防止チェックを有効にするかどうかを制御します。デフォルト値: false。
jwks:
- kid: O9fpdhrViq2zaaaBEWZITz # kid は異なる JWK に対して異なる値に設定する必要があります。
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5v....
- kid: 10fpdhrViq2zaaaBEWZITz # kid は異なる JWK に対して異なる値に設定する必要があります。
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5v...一部の Web シナリオでは、セキュリティを確保するために、ユーザーは Cookie パラメーターの指定されたフィールドにトークンを保存したい場合があります。API Gateway の JWT プラグインを使用すると、Cookie パラメーターのフィールドからトークンを読み取ることができます。 parameterSection パラメーターを使用して、トークンを保存するフィールドを指定できます。次の例では、API Gateway は Cookie ヘッダーからトークンを読み取ることができます。
Cookie: acw_tc=123; token=0QzRCMDBBQUYwRjE1MjYxQzU0QjY4NEM5MTc1NTQ1OUVCOTIzNzA4RDk3MDg5MzlDOTMQTVENDZCRUI1NkYyMEUyO; csrf=073957d8d2823be4f6c0cad23c7645585.4 ブラックリストを構成する
JWT 認証プラグインは、ブラックリストに追加されたものの、正式なトークンを取得しているユーザーから送信されたリクエストをブロックするために、ブラックリストを使用します。このプラグインは、データセット機能と連携して、トークンから復号化されたクレームパラメーターに基づいてリクエストを拒否します。さらに、API Gateway では、拒否されたリクエストに対してカスタムレスポンスを設定できます。次のコードは、JWT 認証プラグインでブラックリストを構成する方法の例を示しています。 block: で始まるパラメーター定義に注意してください。
---
parameter: Authorization // トークンを取得するパラメーター。
parameterLocation: header // トークンを取得する場所。
claimParameters: // パラメーターに変換されるクレーム。API Gateway は JWT クレームをバックエンドパラメーターにマッピングします。
- claimName: aud // JWT クレームの名前。公開または非公開にすることができます。
parameterName: X-Aud // JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: header // JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値: query、header、path、formData。
- claimName: userId // JWT クレームの名前。公開または非公開にすることができます。
parameterName: userId // JWT クレームがマッピングされるバックエンドパラメーターの名前。
location: query // JWT クレームがマッピングされるバックエンドパラメーターの場所。有効な値: query、header、path、formData。
blockClaimParameterName: userId // ブラックリストロジックが実装されている場合に判断に使用される条件。このパラメーターの値が blockByDataSet のデータセットに含まれている場合、リクエストはブロックされます。
blockByDataSet: 87 b65008e92541938537b1a4a236eda5 // ブラックリスト。
blockStatusCode: 403 // 拒否されたリクエストに返されるレスポンスの状態コード。
blockResponseHeaders: // 拒否されたリクエストに返されるレスポンスのヘッダー。
Content-Type: application/xml
blockResponseBody: // 拒否されたリクエストに返されるレスポンスの本文。
<Reason>be blocked</Reason>
jwks:
- kid: O9fpdhrViq2zaaaBEWZITz // kid は異なる JWK に対して異なる値に設定する必要があります。
kty: RSA
e: AQAB
use: sig
alg: RS256
n: qSVxcknOm0uCq5v....6. エラーコード
ステータス | コード | メッセージ | 説明 |
400 | I400JR | JWT が必要です | JWT 関連のパラメーターが見つからないために返されるエラーメッセージです。 |
403 | S403JI |
|
|
403 | S403JU | JWT のクレーム |
|
403 | A403JT | 無効な JWT: ${Reason} | リクエストから読み取られた |
400 | I400JD | JWT のデシリアライズに失敗しました: | リクエストから読み取られた |
403 | A403JK | 一致する JWK がありません。 | リクエストに含まれる |
403 | A403JE | JWT の有効期限が | リクエストから読み取られた |
400 | I400JP | 無効な JWT プラグイン設定: ${JWT} |
|
HTTP 応答メッセージに、X-Ca-Error-Code ヘッダーで ErrorCode によって指定された予期しない応答コード (A403JT や I400JD など) が含まれている場合は、jwt.io Web サイトにアクセスして、トークンの有効性と形式を確認できます。
7. 制限
単一プラグインのメタデータは、[50 KB] を超えることはできません。
転送するように最大 [16] 個のパラメーターを設定できます。
claimNameパラメーターとparameterNameパラメーターは、どちらも長さが [32] 文字を超えることはできません。サポートされている正規表現は [A-Za-z0-9-_] のみです。JWK の場合、
algは RS256、RS384、RS512、ES256、ES384、ES512、HS256、HS384、または HS512 に設定できます。