全部產品
Search
文件中心

Microservices Engine:jwt-auth外掛程式

更新時間:Mar 01, 2025

jwt-auth外掛程式實現了基於JWT(JSON Web Tokens)進行認證鑒權的功能,支援從HTTP請求的URL參數、要求標頭、Cookie欄位解析JWT,同時驗證該Token是否有許可權訪問。相較於配置JWT認證鑒權,jwt-auth外掛程式額外提供了調用方身份識別的能力,支援對不同調用方配置不同的JWT憑證。本文介紹如何配置jwt-auth外掛程式。

外掛程式類型

認證鑒權。

Token大小限制

HTTP協議對要求標頭的大小有限制。通常情況下,所有Header的總大小不超過60KB,具體取決於伺服器和用戶端的配置。如果 JWT Token 的大小超過該限制,可能導致請求失敗。

重要

請確保 JWT Token 的總大小不超過伺服器要求標頭的最大限制,以避免請求失敗。

配置欄位

認證配置

名稱

資料類型

填寫要求

預設值

描述

consumers

array of object

必填。

-

佈建服務的調用者,用於對請求進行認證。

global_auth

array of string

選填(**僅執行個體層級配置**)

-

只能在執行個體層級配置,若配置為true,則全域生效認證機制; 若配置為false,則只對做了配置的網域名稱和路由生效認證機制,若不配置則僅當沒有網域名稱和路由配置時全域生效(相容老使用者使用習慣)。

子項consumers中的每一項配置欄位說明如下。

名稱

資料類型

填寫要求

預設值

描述

name

string

必填。

-

配置該consumer的名稱。

jwks

string

選填。jwks和remote_jwks必填一個。

-

JSON Web Key (JWK)指定的JSON格式字串,是由驗證JWT中籤名的公開金鑰(或對稱金鑰)組成的JSON Web Key Set。

remote_jwks

object

選填。jwks和remote_jwks二選一。

{"uri":"http://127.0.0.1/keys","service":"test.static","port":"80","ttl":30000,"timeout":3000}

用於從指定服務的指定URI定時拉取JWKS,和JWKS欄位同時配置時,以此欄位配置拉取的JWKS優先。

issuer

string

選填。

-

JWT的簽發者,用於校正是否和payload中的iss欄位一致。

claims

object

選填。

-

key/value分別對應payload中的key/value,可以用於校正多個欄位是否和payload中一致,例如配置aud: mobile-site,則要求payload中的aud必須是mobile-site。

claims_to_headers

array of object

選填。

-

抽取JWT的payload中指定欄位,設定到指定的要求標頭中,然後轉寄給後端。

from_headers

array of object

選填。

[{"name":"Authorization","value_prefix":"Bearer"}]

從指定的要求標頭中抽取JWT。

from_params

array of string

選填。

access_token

從指定的URL參數中抽取JWT。

from_cookies

array of string

選填。

-

從指定的cookie中抽取JWT。

clock_skew_seconds

number

選填。

60

校正JWT的exp和iat欄位時允許的時鐘位移量,單位為秒。

keep_token

bool

選填。

true

轉寄給後端時是否保留JWT。

說明

只有當from_headersfrom_paramsfrom_cookies均未配置時,才會使用預設值。

  • from_headers中每一項的配置欄位說明如下。

    名稱

    資料類型

    填寫要求

    預設值

    描述

    name

    string

    必填。

    -

    抽取JWT的請求Header。

    value_prefix

    string

    必填。

    -

    對請求Header的value去除此首碼,剩餘部分作為JWT。

  • claims_to_headers中每一項的配置欄位說明如下。

    名稱

    資料類型

    填寫要求

    預設值

    描述

    claim

    string

    必填。

    -

    JWT payload中的指定欄位,要求必須是字串或不帶正負號的整數類型。

    header

    string

    必填。

    -

    從payload取出欄位的值設定到這個要求標頭中,轉寄給後端。

    override

    bool

    選填。

    true

    • true時,存在同名要求標頭會進行覆蓋。

    • false時,追加同名要求標頭。

  • remote_jwks中每一項的配置欄位說明如下。

    名稱

    資料類型

    填寫要求

    預設值

    描述

    uri

    string

    必填。

    -

    請求URL。

    service

    string

    必填。

    -

    • K8s服務填寫樣本: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

array of string

選填(**非執行個體層級配置**)。

-

只能在路由或網域名稱等細粒度規則上配置,對於符合匹配條件的請求,配置允許訪問的 consumer,從而實現細粒度的許可權控制。

重要
  • 在一個規則裡,鑒權配置和認證配置不可同時存在。

  • 對於通過認證鑒權的請求,請求的Header會被添加一個X-Mse-Consumer欄位,用以標識調用者的名稱。

配置樣本

全域配置認證和路由粒度進行鑒權

以下配置將對網關特定路由或網域名稱開啟JWT Auth認證和鑒權。

說明

如果一個JWT能匹配多個jwks,則按照配置順序命中第一個匹配的consumer。

在執行個體層級做如下外掛程式配置:

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-aroute-b兩個路由做如下外掛程式配置:

allow:
- consumer1

*.example.comtest.com兩個網域名稱做如下外掛程式配置:

allow:
- consumer2
說明
  • 此例指定的route-aroute-b即在建立網關路由時填寫的路由名稱,當匹配到這兩個路由時,將允許nameconsumer1的調用者訪問,其他調用者不被允許訪問。

  • 此例指定的*.example.comtest.com用於匹配請求的網域名稱,當發現網域名稱匹配時,將允許nameconsumer2的調用者訪問,其他調用者不被允許訪問。

根據該配置,允許訪問以下請求。假設以下請求會匹配到route-a這條路由。

  • 將JWT設定在URL參數中。

    curl  'http://xxx.hello.com/test?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEy****.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczOD****.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
  • 將JWT設定在HTTP要求標頭中。

    curl  http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'

認證鑒權通過後,請求的Header中會被添加一個X-Mse-Consumer欄位,在此例中其值為consumer1,用以標識調用方的名稱。

下列請求將拒絕訪問。

  • 請求未提供JWT,返回401。

    curl  http://xxx.hello.com/test
  • 根據請求提供的JWT匹配到的調用者無存取權限,返回403。

    # consumer1不在*.example.com的allow列表裡
    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認證,所有人均可訪問。

當沒有匹配到route-b路由時,因為全域配置中global_auth設定為了true,表明對所有請求開啟認證,所以將進行JWT認證,並且允許consumer1consumer2都能訪問。

網域名稱層級開啟,但特定路由關閉

在執行個體層級做如下外掛程式配置:

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用於匹配請求的網域名稱。當發現網域名稱匹配時,將允許nameconsumer1consumer2的調用者訪問,其他調用者不允許訪問。

配置規則順序會依次執行匹配,有任一規則匹配到,就會執行對應配置,不再匹配其他規則。因為這裡配置路由匹配優先順序高於網域名稱,即對當前配置的網域名稱生效,而對網域名稱下的特定路由關閉。

相關錯誤碼

HTTP狀態代碼

出錯資訊

原因說明

401

Jwt missing

要求標頭未提供JWT。

401

Jwt expired

JWT已經到期。

401

Jwt verification fails

JWT payload校正失敗,如iss不匹配。

403

Access Denied

無許可權訪問當前路由。