JWS 和 JWT 政策總覽

本頁適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

本主題提供 JWT (JSON Web Token) 和 JWS (JSON Web Signature) 的一般資訊,以及 Apigee 代理程式開發人員可能感興趣的 Apigee JWS/JWT 政策。

簡介

JWS 和 JWT 通常用於在連線應用程式之間共用宣告或斷言。JWS/JWT 政策可讓 Apigee API Proxy 執行以下操作:

在後兩種情況下,政策也會設定流程變數。這可讓 Apigee 流程中的後續政策檢查 JWT 或 JWS 中的宣告,並根據這些宣告做出決策,或將該資訊傳播至後端服務。

使用 VerifyJWS 或 VerifyJWT 政策時,系統會拒絕無效的 JWS/JWT,並導致錯誤狀態。同樣地,使用 DecodeJWS 或 DecodeJWT 政策時,格式錯誤的 JWS/JWT 會導致錯誤狀態。

影片

觀看短片,快速瞭解 JWT。雖然這部影片專門說明如何產生 JWT,但許多概念與 JWS 相同。

這部短片可讓您進一步瞭解 JWT 結構。

用途

您可以使用 JWS/JWT 政策執行下列作業:

  • 在 Apigee Proxy 的 Proxy 或目標端點端產生新的 JWS/JWT。舉例來說,您可以建立代理要求流程,產生 JWS/JWT 並傳回至用戶端。或者,您可以設計 Proxy,讓 Proxy 在目標要求流程中產生 JWS/JWT,並將其附加至傳送至目標的請求。接著,您可以使用 JWS/JWT 和憑證附加資訊,讓後端服務套用進一步的安全性處理程序。
  • 從傳入用戶端要求、目標服務回應、服務呼叫政策回應或其他來源取得的 JWS/JWT,驗證並擷取相關宣告。對於已簽署的 JWS/JWT,無論 JWS/JWT 是由 Apigee 或第三方產生,Apigee 都會使用 RSA、ECDSA 或 HMAC 演算法驗證簽名。如果是已加密的 JWT,Apigee 會使用任何支援的 JWA 加密演算法之一 (請參閱 IETF RFC 7518) 解密 JWT。
  • 解碼 JWS/JWT。在驗證已簽署的 JWS/JWT 或解密已加密的 JWT 之前,如果必須先知道 JWS/JWT 中的憑證 (JWT) 或標頭 (JWS/JWT) 的值,那麼解碼功能最適合與驗證 JWS/JWT 政策搭配使用。

JWS/JWT 的組成部分

已簽署的 JWS/JWT 會將資訊編碼為三個以點號分隔的部分:

Header.Payload.Signature
  • 「產生 JWS/JWT」政策會建立這三個部分。
  • 「驗證 JWS/JWT」政策會檢查這三個部分。
  • DecodeJWS 政策只會檢查標頭。DecodeJWT 政策只會檢查標頭和酬載。

JWS 也支援分離表單,可省略 JWS 中的酬載:

Header..Signature

在使用已分離的 JWS 時,酬載會與 JWS 分開傳送。您可以使用「驗證 JWS」政策的 <DetachedContent> 元素,指定原始未編碼的 JWS 酬載。接著,驗證 JWS 政策會使用 JWS 中的標頭和簽名,以及 <DetachedContent> 元素指定的酬載,驗證 JWS。

加密的 JWT 會將資訊編碼為五個以點號分隔的部分:

Header.Key.InitializationVector.Payload.AuthenticationTag

GenerateJWT 和 VerifyJWT 政策會建立或檢查所有這些部分。DecodeJWT 只能檢查未加密的標頭。

如要進一步瞭解權杖及其編碼方式,以及如何簽署或加密,請參閱相關標準文件:

JWS 和 JWT 的差異

您可以使用 JWT 或 JWS,在已連結的應用程式之間共用宣告或斷言。這兩者的主要差異在於酬載的表示方式:

  • JWT
    • 酬載一律為 JSON 物件。
    • 酬載一律會附加至 JWT。
    • 憑證的 typ 標頭一律設為 JWT
    • 酬載可以是已簽署或已加密的內容。
  • JWS
    • 酬載可以使用任何格式表示,例如 JSON 物件、位元組串流、位元組串流等。
    • 酬載不必附加至 JWS。
    • 標頭和酬載一律會簽署。JWS 不支援加密。

由於 JWT 格式一律會使用 JSON 物件來代表酬載,因此 Apigee GenerateJWT 和 VerifyJWT 政策已內建支援,可處理常見的已註冊憑證名稱,例如 audisssub 等。也就是說,您可以使用 GenerateJWT 政策的元素,在酬載中設定這些宣告,並使用 VerifyJWT 政策的元素驗證其值。詳情請參閱 JWT 規格的「已註冊的宣稱名稱」一節。

除了支援特定的已註冊宣告名稱外,GenerateJWT 政策也直接支援在 JWT 的酬載或標頭中,新增具有任意名稱的宣告。每個聲明都是簡單的名稱/值組合,其中的值可以是 numberbooleanstringmaparray 類型。

使用 GenerateJWS 時,您會提供代表酬載的內容變數。由於 JWS 可使用任何資料表示法做為酬載,因此 JWS 中沒有「酬載宣告」的概念,而 GenerateJWS 政策也不支援在酬載中新增任意名稱的宣告。您可以使用 GenerateJWS 政策,將具有任意名稱的權利要求新增至 JWS 的標頭。此外,JWS 政策支援分離酬載,其中 JWS 會略過酬載。您可以使用分離的酬載,分別傳送 JWS 和酬載。使用分離的酬載可以節省空間,尤其是大型酬載,而且這也是多項安全標準的要求。

簽署與加密

Apigee 可以產生已簽署或已加密的 JWT。如果酬載不必保密,但需要向讀者提供完整性和不可否認性保證,請選擇已簽署的 JWT。已簽署的 JWT 可讓讀者確保自 JWT 簽署後,酬載並未變更,且 JWT 是由私密金鑰持有人簽署。如果酬載應為機密資料,請選擇加密的 JWT。加密的 JWT 可為酬載提供機密性,因為只有適當的金鑰持有者才能解密。

您可以同時使用已加密和已簽署的 JWT,尤其是當已加密 JWT 使用非對稱式密碼編譯演算法 (RSA、ECDSA) 時。在這種情況下,由於加密金鑰是公開的,因此無法判斷 JWT 產生者的身分。如要解決這個問題,請結合簽署和加密功能。常見的模式如下:

  • 簽署酬載以產生 JWS 或已簽署的 JWT。
  • 將已簽署的結果加密,產生加密的 JWT。

使用這種方法在加密 JWT 中嵌入已簽署的酬載,可同時提供不可否認性和保密性保證。Apigee 政策可產生、解碼及驗證這類組合。

簽名演算法

針對已簽署的 JWT,JWS/JWT 驗證和 JWS/JWT 產生政策支援 RSA、RSASSA-PSS、ECDSA 和 HMAC 演算法,使用位元強度 256、384 或 512 的 SHA2 總和檢查碼。無論用來簽署 JWS/JWT 的演算法為何,DecodeJWS 和 DecodeJWT 政策都會運作。

HMAC 演算法

HMAC 演算法會使用共用密鑰 (稱為密鑰) 建立簽名 (也稱為簽署 JWS/JWT) 和驗證簽名。

密鑰的最小長度取決於演算法的位元強度:

  • HS256:金鑰長度下限為 32 位元組
  • HS384:48 個位元組的最低金鑰長度
  • HS512:金鑰長度下限為 64 個位元組

RSA 演算法

RSA 演算法會使用公開/私密金鑰組來產生加密簽名。JWA 規格使用 RS256、RS384 和 RS512 別名代表這些選項。使用 RSA 簽名時,簽署方會使用 RSA 私密金鑰簽署 JWS/JWT,驗證方則會使用相符的 RSA 公開金鑰驗證 JWS/JWT 上的簽名。鍵盤上沒有大小限制。

RSASSA-PSS 演算法

RSASSA-PSS 演算法是 RSA 演算法的更新版本,使用 PS256、PS384 和 PS512 別名。與 RS* 變體一樣,RSASSA-PSS 會使用 RSA 公開/私密金鑰組來產生加密簽名。金鑰的格式、機制和大小限制與 RS* 演算法相同。

ECDSA 演算法

橢圓曲線數位簽章演算法 (ECDSA) 演算法組合是橢圓曲線密碼編譯演算法,採用 P-256、P-384 或 P-521 曲線。使用 ECDSA 演算法時,演算法會決定您必須指定的公開金鑰和私密金鑰類型:

演算法 曲線 重要規定
ES256 P-256 使用 P-256 曲線 (也稱為 secp256r1prime256v1) 產生的金鑰
ES384 P-384 使用 P-384 曲線 (也稱為 secp384r1) 產生的金鑰
ES512 P-521 使用 P-521 曲線 (也稱為 secp521r1) 產生的金鑰

加密演算法

使用 GenerateJWT 和 VerifyJWT 處理加密 JWT 時,政策支援下列演算法:

  • dir
  • RSA-OAEP-256
  • A128KW、A192KW、A256KW
  • A128GCMKW、A192GCMKW、A256GCMKW
  • PBES2-HS256+A128KW、PBES2-HS384+A192KW、PBES2-HS512+A256KW
  • ECDH-ES、ECDH-ES+A128KW、ECDH-ES+A192KW、ECDH-ES+A256KW

鍵和鍵表示法

JOSE 標準涵蓋 JWS、已簽署及加密的 JWT 等,說明如何使用加密編譯金鑰簽署或加密資訊。任何加密編譯作業的基本元素包括演算法和金鑰。不同的演算法需要不同的金鑰類型,在某些情況下還需要不同的金鑰大小。

對稱式演算法 (例如用於簽署的 HS* 系列,或用於加密的 A128KW 演算法) 需要對稱式或共用金鑰:同一個金鑰用於簽署和驗證,或同一個金鑰用於加密和解密。非對稱演算法 (例如用於簽署的 RS*、PS* 和 ES* 演算法,或用於加密的 ECDH* 演算法) 會使用金鑰組 - 有公開金鑰和私密金鑰,且兩者必須配對。在簽署時,簽署者會使用私密金鑰簽署,任何一方都可以使用公開金鑰驗證簽名。在加密時,加密器會使用公開金鑰進行加密,而解密器會使用私密金鑰進行解密。如同名稱所示,公開金鑰可供公開分享,且不必保密。

將加密編譯金鑰序列化為文字格式的方法有很多種。Apigee 政策接受以各種形式序列化的金鑰:PEM 編碼表單、JWKS 表單,或共用金鑰的 UTF-8 編碼或 base64 編碼表單。

PEM 格式

對於公開金鑰或私密金鑰,通常會使用 PEM 編碼,這項編碼定義請參閱 IETF RFC 7468。以下是 PEM 格式私密金鑰的範例:

-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgVcB/UNPxalR9zDYAjQIf
jojUDiQuGnSJrFEEzZPT/92hRANCAASc7UJtgnF/abqWM60T3XNJEzBv5ez9TdwK
H0M6xpM2q+53wmsN/eYLdgtjgBd3DBmHtPilCkiFICXyaA8z9LkJ
-----END PRIVATE KEY-----

公開金鑰或加密私密金鑰也有類似的 PEM 格式。

JWKS 格式

JSON Web 金鑰 (JWK) 是代表單一加密金鑰的 JSON 資料結構。JSON Web Key Set (JWKS) 是代表一組 JWK 的 JSON 結構。JWK 和 JWKS 的說明請參閱 RFC7517。請參閱 附錄 A 中的 JWKS 範例。JSON Web 金鑰組範例

JWKS 的用意是讓任何一方都能以標準格式呈現一組金鑰。其中一個重要用途是透過以 JWKS 格式提供資料的 HTTP 端點,以標準方式分享公開金鑰。當產生已簽署 JWS 或 JWT 的公司或系統 (例如身分提供者) 發布公開金鑰時,任何可讀取公開金鑰的系統或應用程式,都可以驗證簽署方產生的簽名。反之,任何系統或應用程式若想加密資料,且該資料應僅供特定一方或公司讀取,則可擷取該方或公司所屬的公開金鑰,並為此目的產生加密的 JWT。

RFC7517 說明每個金鑰類型 (例如 RSAEC) 的 JWKS 金鑰元素。以下元素一律應包含在內:

  • kty:金鑰類型,例如 RSAEC
  • kid:金鑰 ID。這個值可以是任意不重複的字串值,單一鍵組內不應有重複值。如果傳入的 JWT 包含在 JWKS 組合中的金鑰 ID,則 VerifyJWS 或 VerifyJWT 政策會使用正確的公開金鑰驗證 JWS/JWT 簽名。

以下是選用元素和其值的範例:

  • alg:金鑰演算法。必須與 JWS/JWT 中的簽署演算法相符。
  • use:金鑰的預定用途。一般值為「sig」(用於簽署和驗證) 或「enc」(用於加密和解密)。

下列 JWKS (原本是從 https://www.googleapis.com/oauth2/v3/certs 擷取,但現在已過時) 包含必要的元素和值,可供 Apigee 使用:

{
     "keys":[
        {
           "kty":"RSA",
           "alg":"RS256",
           "use":"sig",
           "kid":"ca04df587b5a7cead80abee9ea8dcf7586a78e01",
           "n":"iXn-WmrwLLBa-QDiToBozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt7-V7KDjCq0_Nkd-X9rMRV5LKgCa0_F8YgI30QS3bUm9orFryrdOc65PUIVFVxIwMZuGDY1hj6HEJVWIr0CZdcgNIll06BasclckkUK4O-Eh7MaQrqb646ghFlG3zlgk9b2duHbDOq3s39ICPinRQWC6NqTYfqg7E8GN_NLY9srUCc_MswuUfMJ2cKT6edrhLuIwIj_74YGkpOwilr2VswKsvJ7dcoiJxheKYvKDKtZFkbKrWETTJSGX2Xeh0DFB0lqbKLVvqkM2lFU2Qx1OgtTnrw",
           "e":"AQAB"
        },
        {
            "kty":"EC",
            "alg":"ES256",
            "use":"enc",
            "kid":"k05TUSt7-V7KDjCq0_N"
            "crv":"P-256",
            "x":"Xej56MungXuFZwmk_xccvsMpCtXmqhvEEMCmHyAmKF0",
            "y":"Bozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt",
        }
     ]
  }
  

指定 JWS 和 JWT 政策的鍵

無論您是要產生或驗證 JWS 或 JWT,都必須提供金鑰,以便在加密編譯作業中使用。

產生已簽署的 JWT 時,您需要提供可產生簽名的金鑰。

  • 如果是使用非對稱金鑰的 RS*、PS* 或 ES* 簽署演算法,您必須提供私密金鑰才能產生簽名。
  • 如果是 HS* 演算法,您必須提供在產生簽章時會用到的對稱金鑰。

驗證已簽署的 JWS/JWT 時,您需要提供可驗證簽名的金鑰。

  • 如果是 RS*、PS* 或 ES* 簽署演算法,您必須提供與私密金鑰相關聯的公開金鑰,該私密金鑰原本用於簽署權杖。
  • 如果是 HS* 演算法,您必須提供與用於簽署 JWS 或 JWT 相同的對稱式金鑰。

您可以透過兩種方式為 JWS 和 JWT 政策提供金鑰:

  • 直接提供索引鍵值 (通常是透過內容變數),或
  • 透過 kid 和 JWKS 間接提供金鑰。您可以直接指定 JWKS,也可以間接指定 JWKS,方法是透過 Apigee 可擷取 JWKS 的 HTTP 網址。

JWKS 網址選項通常只用於公開金鑰來源,可與非對稱演算法搭配使用,因為 JWKS 網址通常是公開的。

以下範例說明如何在各種情況下直接提供鍵。

  • 產生使用 HS256 演算法簽署的 JWT。在這種情況下,所需的金鑰為對稱式金鑰。這項政策會提供含有 base64url 編碼密鑰的內容變數。

    <GenerateJWT name='gen-138'>
      <Algorithm>HS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <SecretKey encoding='base64url'>
        <Value ref='private.secretkey'/>
        <Id ref='variable-containing-desired-keyid'/>
      </SecretKey>
      . . .
      <OutputVariable>output_variable_name</OutputVariable>
    </GenerateJWT>
  • 驗證使用 HS256 演算法簽署的 JWT。在這種情況下,必要的金鑰是對稱式金鑰。如上例所示,這項政策會提供含有 base64url 編碼密鑰的內容變數。

    <VerifyJWT name='verify-138'>
      <Algorithm>HS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <SecretKey encoding='base64url'>
        <Value ref='private.secretkey'/>
      </SecretKey>
      . . .
      <OutputVariable>output_variable_name</OutputVariable>
    </VerifyJWT>
  • 驗證已使用 PS256 演算法簽署的 JWT。在這種情況下,所需金鑰為公開 RSA 金鑰。這項政策會提供包含 PEM 編碼公開金鑰的內容變數。

    <VerifyJWT name='JWT-001'>
      <Algorithm>PS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <Value ref='variable-containing-pem-encoded-public-key'/>
      </PublicKey>
      . . .
    </VerifyJWT>
  • 產生使用 PS256 演算法簽署的 JWT。在這種情況下,所需的金鑰為 RSA 私密金鑰。這個政策會提供含有 PEM 編碼私密金鑰的內容變數。

    <GenerateJWT name='JWT-002'>
      <Algorithm>PS256</Algorithm>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PrivateKey>
        <Value ref='private.variable-containing-pem-encoded-private-key'/>
      </PrivateKey>
       . . .
    </GenerateJWT>

驗證 JWS 或已簽署的 JWT 時,將 JWKS 設為金鑰來源

當系統或應用程式產生 JWS/JWT 時,通常會在 JWS/JWT 標頭中插入金鑰 ID (kid 宣告)。這個金鑰會告知 JWS/JWT 的任何讀者,需要哪個金鑰才能驗證已簽署的 JWS/JWT,或解密已加密的 JWT。

舉例來說,假設發證機構使用私密金鑰簽署 JWT,「Key ID」會標示必須用來驗證 JWT 的對應公開金鑰。公開金鑰清單通常會在一些知名端點提供,例如 Google 身分端點Firebase 驗證端點。其他供應商會有自己的公開端點,可以 JWKS 格式發布金鑰。

使用 Apigee 驗證 JWS 或已簽署的 JWT,並透過 JWKS 端點共用公開金鑰時,您可以選擇下列做法:

  • 選項 1:在政策設定中,在 <PublicKey/JWKS> 元素中指定 JWKS 端點 URI。舉例來說,針對 VerifyJWT 政策:

    <VerifyJWT name="JWT-Verify-RS256">
      <Algorithm>RS256</Algorithm>
      <Source>json.jwt</Source>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
          <JWKS uri="https://www.googleapis.com/oauth2/v3/certs"/>
      </PublicKey>
      . . .
    </VerifyJWT>

    在這種情況下,Apigee 會:

    1. 檢查 JWS/JWT 標頭,找出 RS256 等簽署演算法 (alg),並在演算法與政策中設定的演算法不相符時拒絕傳入的 JWT。
    2. 從指定的 JWKS 端點或內部快取 (如果這個 JWKS 端點曾經使用過) 中,擷取含有 ID 的金鑰清單。
    3. 檢查 JWS/JWT 標頭,找出金鑰 ID (kid)。如果入站 JWT 的標頭中未包含鍵 ID (kid),則無法將 kid 對應至驗證金鑰,Apigee 就會擲回錯誤。
    4. 從 JWKS 中擷取 JWS/JWT 標頭中所註記的金鑰 ID 對應的 JWK。如果沒有該鍵 ID 的索引鍵,就擲回錯誤。
    5. 請確認 JWK 的演算法與政策設定中指定的演算法相符。如果演算法不相符,則拒絕驗證並擲回錯誤。
    6. 使用該公開金鑰驗證 JWS/JWT 上的簽名。如果簽名無法驗證,則拒絕驗證並擲回錯誤。
  • 選項 2:在政策設定中,指定在 <PublicKey/JWKS> 元素中保留 JWKS 端點 URI 的變數。

    舉例來說,針對 VerifyJWT 政策:

    <VerifyJWT name="JWT-Verify-RS256">
      <Algorithm>RS256</Algorithm>
      <Source>json.jwt</Source>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <JWKS uriRef="variable-containing-a-uri"/>
      </PublicKey>
      . . .
    </VerifyJWT>

    在這種情況下,Apigee 會執行與上述相同的步驟,但 Apigee 會從 uriRef 屬性參照的變數中指定的 uri 擷取 JWKS,而非從硬式編碼的 URI 擷取。快取功能仍會套用。

  • 選項 3:在政策設定中,指定在 <PublicKey/JWKS> 元素中保留硬式編碼 JWKS 資料的變數。

    舉例來說,針對 VerifyJWT 政策:

    <VerifyJWT name="JWT-Verify-RS256">
      <Algorithm>RS256</Algorithm>
      <Source>json.jwt</Source>
      <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
      <PublicKey>
        <JWKS ref="variable-that-holds-a-jwks"/>
      </PublicKey>
      . . .
    </VerifyJWT>

    在這種情況下,Apigee 會執行與上述相同的步驟,但 Apigee 會從您在 ref 屬性中指定的內容變數,而非 URI 中擷取 JWKS。通常您會從 ServiceCallout、KVM 或與 Proxy 相關聯的屬性檔案載入這個內容變數。

產生加密 JWT 時,使用 JWKS 做為金鑰來源

透過非對稱演算法 (RSA-OAEP-256 或任何 ECDH-* 變體) 產生加密 JWT 時,您會使用公開金鑰進行加密。您可以選擇提供 GenerateJWT 政策的金鑰

一般做法是在政策設定中,在 <PublicKey/JWKS> 元素中指定 JWKS 端點 URI。例如:

<GenerateJWT name="GJWT-1">
  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <PublicKey>
    <JWKS uri='https://www.example.com/.well-known/jwks.json'/>
    <Id ref='variable-containing-desired-keyid'/>
  </PublicKey>
    . . .
</GenerateJWT>

在這種情況下,Apigee 會:

  1. 根據政策設定,組合 JWT 的未編碼酬載和標頭。
  2. 從指定的 JWKS 端點或內部快取 (如果這個 JWKS 端點曾經使用過) 中,擷取含有 ID 的金鑰清單。目前快取的 TTL 為 5 分鐘。
  3. 從 JWKS 中擷取 PublicKey/Id 元素中註記的金鑰 ID 所對應的 JWK。如果沒有該鍵 ID 的索引鍵,就擲回錯誤。
  4. 請確認 JWK 的演算法與政策設定中指定的演算法相符。如果演算法不相符,則擲回錯誤。
  5. 產生用來做為內容加密金鑰的隨機序列。
  6. 使用所選公開金鑰加密內容加密金鑰。
  7. 使用內容加密金鑰加密酬載。
  8. 最後,將所有部分組合成序列化加密的 JWT。

另一種做法是使用 uriRef 屬性指定儲存 JWKS 端點 URI 的變數。例如:

<GenerateJWT name="GJWT-1">
  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <PublicKey>
    <JWKS uriRef='variable-containing-jwks-uri'/>
    <Id ref='variable-containing-desired-keyid'/>
  </PublicKey>
  . . .
</GenerateJWT>

在這種情況下,Apigee 會執行與上述相同的步驟,但 Apigee 會從 uriRef 屬性參照的變數中指定的 URI 擷取 JWKS,而非從硬式編碼的 URI 擷取。如果這個 JWKS 端點曾經使用過,Apigee 會從內部快取讀取 JWKS。