jwt-auth プラグインは、JSON Web トークン(JWT)に基づく認証と承認に使用されます。このプラグインを使用すると、HTTP リクエストの URL パラメーター、ヘッダー、または Cookie から JWT を解析し、JWT を検証できます。JWT 認証の手動構成に加えて、jwt-auth プラグインを使用することもできます。プラグインは、呼び出し元の識別機能を提供し、異なる呼び出し元に対して異なる JWT 認証情報を構成できます。このトピックでは、jwt-auth プラグインを構成する方法について説明します。
プラグインの種類
認証と承認のためのプラグイン。
トークンサイズの制限
HTTP リクエストヘッダーには上限があります。ほとんどの場合、すべてのヘッダーの合計サイズは 60 KB を超えることはできません。サイズの制限は、サーバーとクライアントの構成によって異なります。JWT トークンの合計サイズが指定された制限を超えると、リクエストが失敗する可能性があります。
リクエストの失敗を防ぐために、JWT トークンの合計サイズがサーバーリクエストヘッダーの上限を超えないようにしてください。
フィールド
認証構成
名前 | データ型 | 必須 | デフォルト値 | 説明 |
consumers | オブジェクトの配列 | はい | - | サービスの呼び出し元。このフィールドは、リクエストを認証するために使用されます。 |
global_auth | 文字列の配列 | いいえ(インスタンスレベルの構成にのみ必要) | - | global_auth を true に設定すると、認証メカニズムはグローバルに有効になります。 global_auth を false に設定すると、認証メカニズムは、構成したドメイン名とルートに対してのみ有効になります。 global_auth が構成されていない場合、認証メカニズムは、ドメイン名とルートが構成されていない場合にのみグローバルに有効になります。 |
次の表は、consumers フィールドの構成項目について説明しています。
名前 | データ型 | 必須 | デフォルト値 | 説明 |
name | 文字列 | はい | - | コンシューマーの名前。 |
jwks | 文字列 | いいえ(jwks または remote_jwks を構成する必要があります。) | - | JWK は、暗号鍵を表す JSON 文字列です。JSON Web Key Set(JWKS)は、JWT の署名を検証するために使用される公開鍵または対称鍵のセットです。 |
remote_jwks | オブジェクト | いいえ(jwks または remote_jwks を構成する必要があります。) | {"uri":"http://127.0.0.1/keys","service":"test.static","port":"80","ttl":30000,"timeout":3000} | このフィールドは、指定されたサービスの指定された Uniform Resource Identifier(URI)から JWKS を定期的にプルするために使用されます。 jwks フィールドと remote_jwks フィールドの両方を構成した場合、remote_jwks フィールドに基づいてプルされた JWKS が優先されます。 |
issuer | 文字列 | いいえ | - | JWT 発行者。このフィールドの値がペイロードの iss フィールドの値と同じであることを確認する必要があります。 |
claims | オブジェクト | いいえ | - | このフィールドのキーと値は、ペイロードのキーと値に対応しています。このフィールドを使用して、複数のフィールドの値がペイロードの関連フィールドの値と同じであるかどうかを確認できます。たとえば、aud: mobile-site を構成した場合、ペイロードの aud フィールドの値は mobile-site である必要があります。 |
claims_to_headers | オブジェクトの配列 | いいえ | - | JWT ペイロードから抽出されたヘッダーフィールド。指定されたリクエストヘッダーのフィールドを構成し、リクエストをバックエンドサービスに転送できます。 |
from_headers | オブジェクトの配列 | いいえ | [{"name":"Authorization","value_prefix":"Bearer"}] | JWT を抽出できるリクエストヘッダー。 |
from_params | 文字列の配列 | いいえ | access_token | JWT を抽出できる URL パラメーター。 |
from_cookies | 文字列の配列 | いいえ | - | JWT を抽出できる Cookie。 |
clock_skew_seconds | 数値 | いいえ | 60 | JWT の exp フィールドと iat フィールドが検証されるときに許容されるクロックスキュー。単位:秒。 |
keep_token | ブール値 | いいえ | true | リクエストがバックエンドサービスに転送されるときに、リクエストで JWT を保持するかどうかを指定します。 |
デフォルト値は、from_headers、from_params、および from_cookies のいずれも構成されていない場合にのみ使用されます。
次の表は、
from_headersフィールドの構成項目について説明しています。名前
データ型
必須
デフォルト値
説明
name
文字列
はい
-
JWT を抽出できるリクエストヘッダー。
value_prefix
文字列
はい
-
リクエストヘッダーから削除する必要がある値のプレフィックス。プレフィックスが削除された後、値の残りの部分が JWT として使用されます。
次の表は、
claims_to_headersフィールドの構成項目について説明しています。名前
データ型
必須
デフォルト値
説明
claim
文字列
はい
-
JWT ペイロードのフィールド。値は文字列または符号なし整数である必要があります。
header
文字列
はい
-
ペイロードから抽出されたフィールド値が構成されているリクエストヘッダー。このヘッダーを持つリクエストは、バックエンドサービスに転送されます。
override
ブール値
いいえ
true
この構成項目を true に設定すると、同じ名前のリクエストヘッダーが上書きされます。
この構成項目を false に設定すると、同じ名前のリクエストヘッダーが追加されます。
次の表は、
remote_jwks フィールドの構成項目について説明しています。名前
データ型
必須
デフォルト値
説明
uri
文字列
はい
-
リクエスト URL。
service
文字列
はい
-
Kubernetes サービスの例:foo.default.svc.cluster.local。
Nacos サービスの例:foo.DEFAULT-GROUP.public.nacos。
test という名前の DNS サービスの場合、この構成項目を test.dns に設定します。
test という名前の静的 IP サービスの場合、この構成項目を test.static に設定します。
port
ブール値
はい
-
サービスポート。
timeout
ブール値
いいえ
3000
サービスリクエストのタイムアウト期間。単位:ミリ秒。
ttl
ブール値
いいえ
30000
Time to Live(TTL)期間。単位:ミリ秒。
承認構成(オプション)
名前 | データ型 | 必須 | デフォルト値 | 説明 |
allow | 文字列の配列 | いいえ(インスタンスレベル以外の構成に必要) | - | このフィールドは、ルートやドメイン名などの詳細な粒度でのみ構成できます。一致条件を満たすリクエストに対して、アクセスを許可するコンシューマーを構成できます。これにより、きめ細かい権限制御が実装されます。 |
承認構成と認証構成は、1 つのルールで共存できません。
認証および承認されたリクエストの場合、
X-Mse-Consumerフィールドがリクエストヘッダーに追加され、呼び出し元の名前が識別されます。
構成例
グローバル認証とルートレベルの承認を構成する
このセクションでは、ゲートウェイの特定のルートまたはドメイン名に対して JWT 認証と承認を有効にする方法の例を示します。
JWT が複数の JWKS と一致する場合、最初に一致したコンシューマーが構成順序に基づいてヒットします。
インスタンスレベルで次のプラグイン構成を適用します。
consumers:
- name: consumer1
issuer: abcd
jwks: |
{
"keys": [
{
"kty": "oct",
"kid": "123",
"k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
"alg": "HS256"
}
]
}
- name: consumer2
issuer: abc
jwks: |
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid": "123",
"alg": "RS256",
"n": "i0B67f1jggT9QJlZ_8QL9QQ56LfurrqDhpuu8BxtVcfxrYmaXaCtqTn7OfCuca7cGHdrJIjq99rz890NmYFZuvhaZ-LMt2iyiSb9LZJAeJmHf7ecguXS_-4x3hvbsrgUDi9tlg7xxbqGYcrco3anmalAFxsbswtu2PAXLtTnUo6aYwZsWA6ksq4FL3-anPNL5oZUgIp3HGyhhLTLdlQcC83jzxbguOim-0OEz-N4fniTYRivK7MlibHKrJfO3xa_6whBS07HW4Ydc37ZN3Rx9Ov3ZyV0idFblU519nUdqp_inXj1eEpynlxH60Ys_aTU2POGZh_25KXGdF_ZC_MSRw"
}
]
}route-a ルートと route-b ルートに次のプラグイン構成を適用します。
allow:
- consumer1*.example.com ドメイン名と test.com ドメイン名に次のプラグイン構成を適用します。
allow:
- consumer2この例では、
route-aルートとroute-bルートは、ゲートウェイルートの作成時に指定されたルートです。クライアントリクエストがいずれかのルートと一致する場合、nameがconsumer1である呼び出し元はゲートウェイへのアクセスを許可されます。他の呼び出し元はゲートウェイにアクセスできません。この例では、
*.example.comドメイン名とtest.comドメイン名は、リクエスト内のドメイン名と照合するために使用されます。クライアントリクエストがいずれかのドメイン名と一致する場合、nameがconsumer2である呼び出し元はゲートウェイへのアクセスを許可されます。他の呼び出し元はゲートウェイにアクセスできません。
上記の構成では、次のリクエストからのアクセスが許可されます。この例では、route-a が一致します。
URL パラメーターで JWT を構成します。
curl 'http://xxx.hello.com/test?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEy****.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczOD****.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'HTTP リクエストヘッダーで JWT を構成します。
curl http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
認証と承認が通過した後、X-Mse-Consumer フィールドがリクエストのヘッダーに追加され、呼び出し元が識別されます。この例では、このフィールドの値は consumer1 です。
次のリクエストは拒否されます。
リクエストで JWT が提供されておらず、HTTP ステータスコード 401 が返されます。
curl http://xxx.hello.com/testリクエスト内の JWT と一致する呼び出し元にアクセス許可がなく、HTTP ステータスコード 403 が返されます。
# consumer1 という名前のコンシューマーは、*.example.com の許可リストにありません。 curl 'http://xxx.example.com/test' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
インスタンスレベルでゲートウェイの認証を有効にし、特定のルートの認証を無効にする
インスタンスレベルで次のプラグイン構成を適用します。
global_auth: true
consumers:
- name: consumer1
issuer: abcd
jwks: |
{
"keys": [
{
"kty": "oct",
"kid": "123",
"k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
"alg": "HS256"
}
]
}
- name: consumer2
issuer: abc
jwks: |
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid": "123",
"alg": "RS256",
"n": "i0B67f1jggT9QJlZ_8QL9QQ56LfurrqDhpuu8BxtVcfxrYmaXaCtqTn7OfCuca7cGHdrJIjq99rz890NmYFZuvhaZ-LMt2iyiSb9LZJAeJmHf7ecguXS_-4x3hvbsrgUDi9tlg7xxbqGYcrco3anmalAFxsbswtu2PAXLtTnUo6aYwZsWA6ksq4FL3-anPNL5oZUgIp3HGyhhLTLdlQcC83jzxbguOim-0OEz-N4fniTYRivK7MlibHKrJfO3xa_6whBS07HW4Ydc37ZN3Rx9Ov3ZyV0idFblU519nUdqp_inXj1eEpynlxH60Ys_aTU2POGZh_25KXGdF_ZC_MSRw"
}
]
}route-b ルートに次のプラグイン構成を適用します。
_disable_: trueこの例では、route-b ルートは、ゲートウェイルートの作成時に指定されたルートです。_disable_ が true に設定されていて、ルートが一致する場合、プラグイン機能は無効になります。この場合、ルートには JWT ベースの認証は不要であり、すべてのユーザーがルートにアクセスできます。
グローバル構成で global_auth が true に設定されていて、route-b が一致しない場合、すべてのリクエストに対して認証が有効になります。この場合、JWT ベースの認証が必要であり、consumer1 と consumer2 の両方がゲートウェイにアクセスできます。
ドメイン名の認証を有効にし、特定のルートの認証を無効にする
インスタンスレベルで次のプラグイン構成を適用します。
consumers:
- name: consumer1
issuer: abcd
jwks: |
{
"keys": [
{
"kty": "oct",
"kid": "123",
"k": "hM0k3AbXBPpKOGg__Ql2Obcq7s60myWDpbHXzgKUQdYo7YCRp0gUqkCnbGSvZ2rGEl4YFkKqIqW7mTHdj-bcqXpNr-NOznEyMpVPOIlqG_NWVC3dydBgcsIZIdD-MR2AQceEaxriPA_VmiUCwfwL2Bhs6_i7eolXoY11EapLQtutz0BV6ZxQQ4dYUmct--7PLNb4BWJyQeWu0QfbIthnvhYllyl2dgeLTEJT58wzFz5HeNMNz8ohY5K0XaKAe5cepryqoXLhA-V-O1OjSG8lCNdKS09OY6O0fkyweKEtuDfien5tHHSsHXoAxYEHPFcSRL4bFPLZ0orTt1_4zpyfew",
"alg": "HS256"
}
]
}
- name: consumer2
issuer: abc
jwks: |
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid": "123",
"alg": "RS256",
"n": "i0B67f1jggT9QJlZ_8QL9QQ56LfurrqDhpuu8BxtVcfxrYmaXaCtqTn7OfCuca7cGHdrJIjq99rz890NmYFZuvhaZ-LMt2iyiSb9LZJAeJmHf7ecguXS_-4x3hvbsrgUDi9tlg7xxbqGYcrco3anmalAFxsbswtu2PAXLtTnUo6aYwZsWA6ksq4FL3-anPNL5oZUgIp3HGyhhLTLdlQcC83jzxbguOim-0OEz-N4fniTYRivK7MlibHKrJfO3xa_6whBS07HW4Ydc37ZN3Rx9Ov3ZyV0idFblU519nUdqp_inXj1eEpynlxH60Ys_aTU2POGZh_25KXGdF_ZC_MSRw"
}
]
}route-b ルートに次のプラグイン構成を適用します。
_disable_: true*.example.com ドメイン名に次のプラグイン構成を適用します。
allow:
- consumer1
- consumer2この例では、route-b ルートは、ゲートウェイルートの作成時に指定されたルートです。_disable_ が true に設定されていて、ルートが一致する場合、プラグイン機能は無効になります。この場合、ルートには JWT ベースの認証は不要であり、すべてのユーザーがルートにアクセスできます。
この例では、*.example.com ドメイン名は、リクエスト内のドメイン名と照合するために使用されます。ドメイン名が一致する場合、name が consumer1 または consumer2 である呼び出し元はゲートウェイへのアクセスを許可されます。他の呼び出し元はゲートウェイにアクセスできません。
ルールは順番に適用されます。ルールに基づいてルートまたはドメイン名が一致する場合、ルールの構成が使用され、他のルールはスキップされます。ルートベースの一致は、ドメイン名ベースの一致よりも優先されます。構成されたドメイン名に対して認証を有効にし、ドメイン名の下の特定のルートに対して認証を無効にすることができます。
HTTP ステータスコード
HTTP ステータスコード | エラーメッセージ | 理由 |
401 | JWT がありません | リクエストヘッダーに JWT が提供されていません。 |
401 | JWT の期限が切れました | JWT の期限が切れました。 |
401 | JWT 検証に失敗しました | iss フィールドの不一致などのシナリオで JWT ペイロード検証に失敗しました。 |
403 | アクセスが拒否されました | コンシューマーは現在のルートにアクセスする権限がありません。 |