jwt-auth プラグインは、JSON Web トークン (JWT) に基づく認証および権限付与を提供します。HTTP リクエストの URL パラメーター、リクエストヘッダー、または Cookie から JWT を解析し、トークンを検証してアクセスを許可または拒否します。JWT 認証および権限付与とは異なり、jwt-auth プラグインは呼び出し元を識別できるため、異なる呼び出し元ごとに異なる JWT 認証情報を構成できます。
構成フィールド
認証構成
|
名前 |
データ型 |
必須 |
デフォルト値 |
説明 |
|
consumers |
オブジェクトの配列 |
必須 |
- |
リクエスト認証用のサービスコンシューマー。 |
|
global_auth |
文字列の配列 |
任意(インスタンスレベルの構成のみ) |
- |
インスタンスレベルでのみ構成可能です。true に設定すると、認証がグローバルに適用されます。false に設定すると、構成されたドメイン名およびルートに対してのみ認証が適用されます。構成されていない場合、ドメイン名またはルートの構成が存在しないときにのみ認証がグローバルに適用され、既存ユーザーとの互換性が確保されます。 |
次の表は、consumers 内の各項目のフィールドについて説明しています。
|
名前 |
データ型 |
必須 |
デフォルト値 |
説明 |
|
name |
文字列 |
必須 |
- |
コンシューマーの名前。 |
|
jwks |
文字列 |
任意。jwks または remote_jwks のいずれかが必須です。 |
- |
JSON Web Key (JWK) で指定された JSON 形式の文字列。これは、JWT 署名の検証に使用される公開鍵または対称キーを含む JSON Web キーセットです。 |
|
remote_jwks |
オブジェクト |
任意。jwks と remote_jwks のいずれか一方を選択してください。 |
{"uri":"http://127.0.0.1/keys","service":"test.static","port":"80","ttl":30000,"timeout":3000} |
指定されたサービスの指定された URI から定期的に JWKS をプルします。jwks と remote_jwks の両方が構成されている場合、このフィールドによってプルされた JWKS が優先されます。 説明
remote_jwks によって返される JWKS のサイズは 1 MB 未満である必要があります。サイズがこの制限を超えてエラーが発生した場合は、DingTalk グループ 88010006189 に参加するか、チケットを送信してサポートを依頼してください。 |
|
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 |
指定された URL パラメーターから JWT を抽出します。 |
|
from_cookies |
文字列の配列 |
任意 |
- |
指定された Cookie から JWT を抽出します。 |
|
clock_skew_seconds |
数値 |
任意 |
60 |
JWT の exp および iat フィールドを検証する際に許容される時計のずれ(秒単位)。 |
|
keep_token |
bool |
任意 |
true |
リクエストをバックエンドに転送する際に JWT を保持するかどうか。 |
デフォルト値は、from_headers、from_params、および from_cookies が構成されていない場合にのみ使用されます。
-
次の表は、
from_headers内の各項目のフィールドについて説明しています。名前
データ型
必須
デフォルト値
説明
name
文字列
必須
-
JWT を抽出するリクエストヘッダー。
value_prefix
文字列
必須
-
ヘッダー値から削除するプレフィックス。残りの部分が JWT として扱われます。
-
次の表は、
claims_to_headers内の各項目のフィールドについて説明しています。名前
データ型
必須
デフォルト値
説明
claim
文字列
必須
-
JWT ペイロード内の指定されたフィールド。値は文字列または符号なし整数である必要があります。
header
文字列
必須
-
ペイロードからのフィールド値をこのリクエストヘッダーに設定し、バックエンドに転送します。
override
bool
任意
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
bool
必須
-
サービスポート。
timeout
bool
任意
3000
サービスリクエストのタイムアウト(ミリ秒単位)。
ttl
bool
任意
30000
キャッシュの持続時間(ミリ秒単位)。
-
権限付与構成(任意)
|
名前 |
データ型 |
必須 |
デフォルト値 |
説明 |
|
allow |
文字列の配列 |
任意(インスタンスレベルの構成では使用不可) |
- |
ルートやドメイン名などの詳細なルールでのみ構成可能です。マッチング条件を満たすリクエストに対してリソースへのアクセスを許可するコンシューマーを指定し、きめ細かなアクセス制御を実現します。 |
-
権限付与構成と認証構成は、同一のルール内で同時に使用できません。
-
認証および権限付与を通過したリクエストには、呼び出し元の名前を識別するための
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はゲートウェイルート作成時に指定したルート名です。これらのルートにマッチするリクエストに対しては、consumer1という名前の呼び出し元のみがアクセスを許可されます。他の呼び出し元はアクセスが拒否されます。 -
この例では、
*.example.comおよびtest.comはリクエストのドメイン名とのマッチングに使用されます。ドメイン名がマッチする場合、consumer2という名前の呼び出し元のみがアクセスを許可されます。他の呼び出し元はアクセスが拒否されます。
リクエスト例
この構成に基づき、次のリクエストが許可されます。これらの例では、リクエストが route-a ルートにマッチすると仮定しています。
-
URL パラメーターに JWT を設定します。
curl 'http://xxx.hello.com/test?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEy****.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4' -
HTTP リクエストヘッダーに JWT を設定します。
curl http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
結果の検証
認証が成功すると、呼び出し元の名前を含む X-Mse-Consumer ヘッダーがリクエストに追加されます。この例では、その値は consumer1 です。
次のリクエストは拒否されます。
-
リクエストが JWT を提供していないため、401 エラーが返されます。
-
提供された JWT によってマッチした呼び出し元がアクセス権限を持っていないため、403 エラーが返されます。
ゲートウェイインスタンスレベルで有効化し、特定のルートで無効化
インスタンスレベルでプラグインを次のように構成します。
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 認証は実行されず、すべてのユーザーがアクセスを許可されます。
リクエストが route-b ルートにマッチしない場合、グローバル構成で global_auth が true に設定されているため、すべてのリクエストに対して 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 はリクエストのドメイン名とのマッチングに使用されます。ドメイン名がマッチする場合、consumer1 または consumer2 という名前の呼び出し元がアクセスを許可されます。他の呼び出し元はアクセスが拒否されます。
構成ルールは順番にマッチングされます。ルールがマッチすると、その構成が実行され、それ以降のルールは評価されません。ルートマッチングはドメイン名マッチングよりも優先度が高いため、ドメイン名に対してプラグインを有効化しつつ、そのドメイン名下の特定のルートに対しては無効化できます。
関連エラーコード
|
HTTP ステータスコード |
エラーメッセージ |
原因 |
|
401 |
Jwt missing |
リクエストヘッダーに JWT が含まれていません。 |
|
401 |
Jwt expired |
JWT の有効期限が切れています。 |
|
401 |
Jwt verification fails |
JWT ペイロードの検証に失敗しました。たとえば、iss が一致しません。 |
|
403 |
Access Denied |
現在のルートへのアクセス権限がありません。 |