驗證 JWT 政策

本頁適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

政策圖示

結果

驗證已簽署的 JWT,或解密並驗證從用戶端或其他系統收到的加密 JWT。這項政策也會將宣告擷取至內容變數,以便後續政策或條件檢查這些值,做出授權或路由決策。如需詳細介紹,請參閱「JWS 和 JWT 政策總覽」。

這項政策是標準政策,可部署至任何環境類型。如要瞭解政策類型和各環境類型的可用性,請參閱「政策類型」。

執行這項政策時,如果是已簽署的 JWT,Apigee 會使用提供的驗證金鑰驗證 JWT 的簽名。如果是已加密的 JWT,Apigee 會使用解密金鑰解密 JWT。無論是哪種情況,Apigee 都會依據有效期限和「不早於」時間 (如有) 驗證 JWT 是否有效。政策也可以選擇驗證 JWT 中特定憑證附加資訊的值,例如主體、發出者、目標對象,或額外憑證附加資訊的值。

如果 JWT 經過驗證且有效,則 JWT 內含的所有權杖會擷取至內容變數,供後續政策或條件使用,且允許請求繼續執行。如果無法驗證 JWT 簽名,或是 JWT 因其中一個時間戳記而無效,則所有處理作業都會停止,且回應會傳回錯誤。

如要瞭解 JWT 的各個部分,以及如何加密和簽署,請參閱 RFC7519

做法

政策是否驗證已簽署或已加密的 JWT,取決於您用來指定驗證 JWT 的演算法元素:

影片

觀看短片,瞭解如何驗證 JWT 上的簽章。

驗證已簽署的 JWT

本節說明如何驗證已簽署的 JWT。如果是已簽署的 JWT,請使用 <Algorithm> 元素指定簽署金鑰的演算法。

已簽署 JWT 的範例

以下範例說明如何驗證已簽署的 JWT。

HS256 演算法

這個範例政策會驗證使用 HS256 加密演算法 (HMAC) 簽署的 JWT,並使用 SHA-256 核對和。系統會使用名為 jwt 的表單參數,在 Proxy 要求中傳遞 JWT。這個鍵包含在名為 private.secretkey 的變數中。請參閱上方的影片,瞭解完整的示例,包括如何提出政策要求。

政策設定包含 Apigee 解碼及評估 JWT 所需的資訊,例如 JWT 所在位置 (在「Source」元素中指定的流程變數)、必要的簽署演算法、機密金鑰所在位置 (儲存在 Apigee 流程變數中,例如可從 Apigee KVM 擷取),以及一組必要宣告和其值。

<VerifyJWT name="JWT-Verify-HS256">
    <DisplayName>JWT Verify HS256</DisplayName>
    <Algorithm>HS256</Algorithm>
    <Source>request.formparam.jwt</Source>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <SecretKey encoding="base64">
        <Value ref="private.secretkey"/>
    </SecretKey>
    <Subject>monty-pythons-flying-circus</Subject>
    <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
    <Audience>fans</Audience>
    <AdditionalClaims>
        <Claim name="show">And now for something completely different.</Claim>
    </AdditionalClaims>
</VerifyJWT>

這項政策會將輸出內容寫入內容變數,以便 API Proxy 中的後續政策或條件檢查這些值。如需這項政策設定的變數清單,請參閱「流程變數」。

RS256 演算法

這個範例政策會驗證使用 RS256 演算法簽署的 JWT。如要驗證,您必須提供公開金鑰。系統會使用名為 jwt 的表單參數,在 Proxy 要求中傳遞 JWT。公開金鑰包含在名為 public.publickey 的變數中。請參閱上方的影片,瞭解完整的示例,包括如何提出政策要求。

如要進一步瞭解這個範例政策中各個元素的規定和選項,請參閱元素參考資料。

<VerifyJWT name="JWT-Verify-RS256">
    <Algorithm>RS256</Algorithm>
    <Source>request.formparam.jwt</Source>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <PublicKey>
        <Value ref="public.publickey"/>
    </PublicKey>
    <Subject>apigee-seattle-hatrack-montage</Subject>
    <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
    <Audience>urn://c60511c0-12a2-473c-80fd-42528eb65a6a</Audience>
    <AdditionalClaims>
        <Claim name="show">And now for something completely different.</Claim>
    </AdditionalClaims>
</VerifyJWT>

對於上述設定,具有此標頭的 JWT…

{
  "typ" : "JWT",
  "alg" : "RS256"
}

而這個酬載…

{
  "sub" : "apigee-seattle-hatrack-montage",
  "iss" : "urn://apigee-edge-JWT-policy-test",
  "aud" : "urn://c60511c0-12a2-473c-80fd-42528eb65a6a",
  "show": "And now for something completely different."
}

… 會視為有效,前提是簽名可透過提供的公開金鑰驗證。

同樣標頭的 JWT,但附帶此酬載…

{
  "sub" : "monty-pythons-flying-circus",
  "iss" : "urn://apigee-edge-JWT-policy-test",
  "aud" : "urn://c60511c0-12a2-473c-80fd-42528eb65a6a",
  "show": "And now for something completely different."
}

… 會判定為無效,即使可以驗證簽章也一樣,因為 JWT 中包含的「sub」憑證附加資訊與政策設定中指定的「Subject」元素必要值不符。

這項政策會將輸出內容寫入內容變數,以便 API Proxy 中的後續政策或條件檢查這些值。如需這項政策設定的變數清單,請參閱「流程變數」。

上述範例使用 <Algorithm> 元素,因此會驗證已簽署的 JWT。<PrivateKey> 元素會指定用來簽署 JWT 的金鑰。還有其他重要元素。您使用的演算法取決於 <Algorithm> 的值所指定的演算法,詳情請參閱下一節。

設定驗證已簽署 JWT 的關鍵元素

下列元素會指定用於驗證已簽署 JWT 的金鑰:

您使用的元素取決於所選演算法,如以下表所示:

演算法 重要元素
HS*
<SecretKey encoding="base16|hex|base64|base64url">
  <Value ref="private.secretkey"/>
</SecretKey>
RS*、ES*、PS*
<PublicKey>
  <Value ref="rsa_public_key_or_value"/>
</PublicKey>

或:

<PublicKey>
  <Certificate ref="signed_cert_val_ref"/>
</PublicKey>

或:

<PublicKey>
  <JWKS ref="jwks_val_or_ref"/>
</PublicKey>
*如要進一步瞭解金鑰規定,請參閱「關於簽名加密演算法」一文。

驗證已加密的 JWT

本節說明如何驗證已加密的 JWT。對於已加密的 JWT,請使用 <Algorithms> 元素指定簽署金鑰和內容的演算法。

加密 JWT 的範例

以下範例說明如何驗證已加密的 JWT (將 <Type> 設為 Encrypted),其中:

  • 金鑰會使用 RSA-OAEP-256 演算法加密。
  • 內容會使用 A128GCM 演算法加密。
<VerifyJWT name="vjwt-1">
  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>
  <Type>Encrypted</Type> 
  <PrivateKey>
    <Value ref="private.rsa_privatekey"/>
  </PrivateKey>
  <Subject>subject@example.com</Subject>
  <Issuer>urn://apigee</Issuer>
  <AdditionalHeaders>
    <Claim name="moniker">Harvey</Claim>
  </AdditionalHeaders>
  <TimeAllowance>30s</TimeAllowance>
  <Source>input_var</Source>
</VerifyJWT>

上述範例使用 <Algorithms> 元素,因此會驗證已加密的 JWT。<PrivateKey> 元素會指定用於解密 JWT 的金鑰。還有其他重要元素。您使用的演算法取決於 <Algorithms> 的值所指定的演算法,詳情請參閱下一節。

設定驗證已加密 JWT 的關鍵元素

下列元素會指定用於驗證加密 JWT 的金鑰:

您使用的元素取決於所選的金鑰加密演算法,如以下表所示:

演算法 重要元素
RSA-OAEP-256
<PrivateKey>
  <Value ref="private.rsa_privatekey"/>
</PrivateKey>

注意:您指定的變數必須解析為 PEM 編碼形式的 RSA 私密金鑰。

  • ECDH-ES
  • ECDH-ES+A128KW
  • ECDH-ES+A192KW
  • ECDH-ES+A256KW
<PrivateKey>
  <Value ref="private.ec_privatekey"/>
</PrivateKey>

注意:您指定的變數必須解析為 PEM 編碼形式的橢圓曲線私密金鑰。

  • A128KW
  • A192KW
  • A256KW
  • A128GCMKW
  • A192GCMKW
  • A256GCMKW
<SecretKey encoding="base16|hex|base64|base64url">
  <Value ref="private.flow-variable-name-here"/>
</SecretKey>
  • PBES2-HS256+A128KW
  • PBES2-HS384+A192KW
  • PBES2-HS512+A256KW
<PasswordKey>
  <Value ref="private.password-key"/>
  <SaltLength>
  <PBKDF2Iterations>
</PasswordKey>
dir
<DirectKey>
  <Value encoding="base16|hex|base64|base64url" ref="private.directkey"/>
</DirectKey>

如要進一步瞭解關鍵要求,請參閱「關於簽名加密演算法」一文。

元素參照

政策參考資料會說明「驗證 JWT」政策的元素和屬性。

注意:設定會因使用的加密演算法而有所不同。如需特定用途的設定範例,請參閱「範例」。

套用至頂層元素的屬性

<VerifyJWT name="JWT" continueOnError="false" enabled="true" async="false">

以下屬性適用於所有政策父元素。

屬性 說明 預設 在家狀態
名稱 政策的內部名稱。您可以在名稱中使用的字元僅限: A-Z0-9._\-$ %。不過,Apigee UI 會強制執行其他限制,例如自動移除非英數字元的字元。

您可以選擇使用 <displayname></displayname> 元素,在管理 UI 代理程式編輯器中為政策加上不同自然語言的名稱標籤。

不適用 必填
continueOnError 將其設為 false,即可在政策失敗時傳回錯誤。這是大多數政策的預期行為。

將其設為 true,即使政策失敗,流程執行作業仍會繼續。

false 選用
已啟用 設為 true 即可強制執行政策。

將其設為 false 可「關閉」政策。即使政策仍附加至流程,也不會強制執行。

選用
非同步 此屬性已淘汰。 false 已淘汰

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

除了名稱屬性之外,您也可以使用其他自然語言名稱,在管理介面 Proxy 編輯器中標示政策。

預設 如果省略這個元素,系統會使用政策的 name 屬性值。
在家狀態 選用
類型 字串

<Algorithm>

<Algorithm>HS256</Algorithm>

指定用於驗證權杖的加密編譯演算法。使用 <Algorithm> 元素驗證已簽署的 JWT。

RS*/PS*/ES* 演算法會採用公開/密鑰組,而 HS* 演算法則會採用共用密鑰。另請參閱「 關於簽章加密演算法」。

您可以指定多個值,並以半形逗號分隔。例如「HS256, HS512」或「RS256, PS256」。 不過,HS* 演算法和 ES* 演算法都需要特定的鍵類型,因此無法與其他演算法結合。您可以結合 RS* 和 PS* 演算法。

預設 不適用
在家狀態 必填
類型 逗號分隔值字串
有效值 HS256、HS384、HS512、RS256、RS384、RS512、ES256、ES384、ES512、PS256、PS384、PS512

<Algorithms>

<Algorithms>
    <Key>key-algorithm</Key>
    <Content>content-algorithm</Content>
</Algorithm>

使用 <Algorithms> 元素驗證已加密的 JWT。這個元素會指定金鑰加密的加密編譯演算法,也就是在建立加密 JWT 時必須使用的演算法。並可選擇指定內容加密演算法。

預設 不適用
在家狀態 驗證加密 JWT 時必填
類型 複合式園區

<Algorithms> 的子元素

下表概略說明 <Algorithms> 的子元素:

子元素 是否必要 說明
<Key> 必填 指定金鑰的加密演算法。
<Content> 選用 指定內容的加密演算法。

驗證失敗的情況如下:

  • 在加密 JWT 標頭的 alg 屬性中斷言的演算法,與此處 <Key> 元素中指定的金鑰加密演算法不同。
  • 政策指定 <Content> 元素,且在加密 JWT 標頭的 enc 屬性中斷言的演算法,與 <Content> 元素中指定的演算法不同。

舉例來說,如要驗證已加密的 JWT,並檢查金鑰演算法是否為 RSA-OAEP-256,以及內容演算法是否為 A128GCM

  <Algorithms>
    <Key>RSA-OAEP-256</Key>
    <Content>A128GCM</Content>
  </Algorithms>

反之,如要驗證已加密的 JWT,並檢查金鑰演算法是否為 RSA-OAEP-256,且不對內容演算法強制執行限制:

  <Algorithms>
    <Key>RSA-OAEP-256</Key>
  </Algorithms>

金鑰加密演算法

下表列出可用的金鑰加密演算法,以及您必須指定的金鑰類型,才能使用該金鑰加密演算法驗證 JWT。

<Key> 的值 (金鑰加密演算法) 驗證所需的必要元素
dir <DirectKey>
RSA-OAEP-256 <PrivateKey>
  • A128KW
  • A192KW
  • A256KW
  • A128GCMKW
  • A192GCMKW
  • A256GCMKW
<SecretKey>
  • PBES2-HS256+A128KW
  • PBES2-HS384+A192KW
  • PBES2-HS512+A256KW
<PasswordKey>
  • ECDH-ES
  • ECDH-ES+A128KW
  • ECDH-ES+A192KW
  • ECDH-ES+A256KW
<PrivateKey>

請參閱「驗證已加密的 JWT」一文,瞭解金鑰加密演算法為 RSA-OAEP-256 的範例,這樣您就可以使用 <PrivateKey> 元素。

內容加密演算法

VerifyJWT 政策並未要求您指定內容加密演算法。如要指定用於內容加密的演算法,請使用 <Algorithms> 元素的 <Content> 子項

無論金鑰加密演算法為何,下列演算法 (所有對稱和 AES 演算法) 都支援內容加密:

  • A128CBC-HS256
  • A192CBC-HS384
  • A256CBC-HS512
  • A128GCM
  • A192GCM
  • A256GCM

<Audience>

<Audience>audience-here</Audience>

or:

<Audience ref='variable-name-here'/>

政策會驗證 JWT 中的目標對象憑證附加資訊是否與設定中指定的值相符。如果沒有相符項目,政策就會擲回錯誤。這個憑證附加資訊可識別 JWT 的收件者。這是 RFC7519 中提及的註冊宣告之一。

預設 不適用
在家狀態 選用
類型 字串
有效值 用來識別目標對象的流程變數或字串。

<AdditionalClaims/Claim>

<AdditionalClaims>
    <Claim name='claim1'>explicit-value-of-claim-here</Claim>
    <Claim name='claim2' ref='variable-name-here'/>
    <Claim name='claim3' ref='variable-name-here' type='boolean'/>
</AdditionalClaims>

or:

<AdditionalClaims ref='claim_payload'/>

驗證 JWT 酬載是否包含指定的額外憑證附加資訊,且斷言的憑證附加資訊值是否相符。

額外憑證附加資訊使用的名稱並非標準的已註冊 JWT 憑證附加資訊名稱。額外聲明的值可以是字串、數字、布林值、地圖或陣列。圖是一組名稱/值組合。您可以在政策設定中明確指定任何類型的權杖值,也可以間接指定流程變數。

預設 不適用
在家狀態 選用
類型 字串、數字、布林值或地圖
陣列 將其設為 true,表示值是否為類型陣列。預設值:false
有效值 任何要用於額外聲明的值。

<Claim> 元素的屬性如下:

  • name - (必填) 聲明的名稱。
  • ref - (選用) 流程變數的名稱。如果有此值,政策會使用這個變數的值做為宣告。如果您同時指定 ref 屬性和明確的聲明值,則明確值會是預設值,並在參照的流程變數未解析時使用。
  • type - (選用) 下列任一值:字串 (預設)、數字、布林值或地圖
  • array - (選用) 將此屬性設為 true,表示值是否為類型的陣列。預設值:false。

當您加入 <Claim> 元素時,系統會在您設定政策時,將聲明名稱設為靜態。您也可以傳遞 JSON 物件來指定聲明名稱。由於 JSON 物件會以變數的形式傳遞,因此宣稱名稱會在執行階段決定。

例如:

<AdditionalClaims ref='json_claims'/>

其中變數 json_claims 包含以下格式的 JSON 物件:

{
  "sub" : "person@example.com",
  "iss" : "urn://secure-issuer@example.com",
  "non-registered-claim" : {
    "This-is-a-thing" : 817,
    "https://example.com/foobar" : { "p": 42, "q": false }
  }
}

<AdditionalHeaders/Claim>

<AdditionalHeaders>
    <Claim name='claim1'>explicit-value-of-claim-here</Claim>
    <Claim name='claim2' ref='variable-name-here'/>
    <Claim name='claim3' ref='variable-name-here' type='boolean'/>
    <Claim name='claim4' ref='variable-name' type='string' array='true'/>
</AdditionalHeaders>

驗證 JWT 標頭是否包含指定的額外憑證附加資訊名稱/值組,以及斷言的憑證附加資訊值是否相符。

附加憑證使用非標準的已註冊 JWT 憑證名稱。額外聲明的值可以是字串、數字、布林值、地圖或陣列。圖是一組名稱/值組合。您可以在政策設定中明確指定任何類型的權杖值,也可以間接指定流程變數。

預設 不適用
在家狀態 選用
類型

字串 (預設)、數字、布林值或地圖。

如果未指定類型,則預設為 String。

陣列 將其設為 true,表示值是否為類型陣列。預設值:false
有效值 任何要用於額外聲明的值。

<Claim> 元素的屬性如下:

  • name - (必填) 聲明的名稱。
  • ref - (選用) 流程變數的名稱。如果有此值,政策會使用這個變數的值做為宣告。如果您同時指定 ref 屬性和明確的聲明值,則明確值會是預設值,並在參照的流程變數未解析時使用。
  • type - (選用) 下列任一值:字串 (預設)、數字、布林值或地圖
  • array - (選用) 將此屬性設為 true,表示值是否為類型的陣列。預設值:false。

<CustomClaims>

注意:目前,透過使用者介面新增 GenerateJWT 政策時,系統會插入 CustomClaims 元素。這個元素無法運作,因此會遭到忽略。正確的替代元素為 <AdditionalClaims>。我們會更新 UI,以便日後插入正確的元素。

<Id>

<Id>explicit-jti-value-here</Id>
 -or-
<Id ref='variable-name-here'/>
 -or-
<Id/>

驗證 JWT 是否包含特定的 jti 要求。如果文字值和 ref 屬性都為空白,政策就會產生包含隨機 UUID 的 jti。JWT ID (jti) 聲明是 JWT 的專屬 ID。如要進一步瞭解 jti,請參閱 RFC7519

預設 不適用
在家狀態 選用
類型 字串或參照。
有效值 字串或含有 ID 的流程變數名稱。

<IgnoreCriticalHeaders>

<IgnoreCriticalHeaders>true|false</IgnoreCriticalHeaders>

如果您希望政策在 JWT 的 crit 標頭中列出的任何標頭未列於 <KnownHeaders> 元素中時擲回錯誤,請將此屬性設為 false。設為 true 可讓 VerifyJWT 政策忽略 crit 標頭。

將此元素設為 true 的原因之一,是如果您處於測試環境中,且尚未準備好處理缺少標頭的失敗情況,

預設 false
在家狀態 選用
類型 布林值
有效值 是或否

<IgnoreIssuedAt>

<IgnoreIssuedAt>true|false</IgnoreIssuedAt>

如果您希望政策在 JWT 包含指定未來時間的 iat (Issued at) 權利要求時擲回錯誤,請將此屬性設為 false (預設值)。設為 true 可讓政策在驗證期間忽略 iat

預設 false
在家狀態 選用
類型 布林值
有效值 是或否

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

如果您希望政策在無法解析政策中指定的任何參照變數時擲回錯誤,請將此屬性設為 false。將其設為 true,即可將任何無法解析的變數視為空字串 (空值)。

預設 false
在家狀態 選用
類型 布林值
有效值 是或否

<Issuer>

<VerifyJWT name='VJWT-29'>
  ...
  <!-- verify that the iss claim matches a hard-coded value -->
  <Issuer>issuer-string-here</Issuer>

  or:

  <!-- verify that the iss claim matches the value contained in a variable -->
  <Issuer ref='variable-containing-issuer'/>

  or:

  <!-- verify via a variable; fallback to a hard-coded value if the variable is empty -->
  <Issuer ref='variable-containing-issuer'>fallback-value-here</Issuer>

這項政策會驗證 JWT 中的核發者 (iss 憑證附加資訊) 是否與設定元素中指定的字串相符。iss 宣告是 IETF RFC 7519 中提及的註冊宣告之一。

預設 不適用
在家狀態 選用
類型 字串或參照
有效值 不限

<KnownHeaders>

<KnownHeaders>a,b,c</KnownHeaders>

or:

<KnownHeaders ref='variable_containing_headers'/>

「GenerateJWT」政策會使用 <CriticalHeaders> 元素,在 JWT 中填入 crit 標頭。例如:

{
  "typ": "...",
  "alg" : "...",
  "crit" : [ "a", "b", "c" ],
}

VerifyJWT 政策會檢查 JWT 中的 crit 標頭 (如有),並針對每個列出的標頭,檢查 <KnownHeaders> 元素是否也列出該標頭。<KnownHeaders> 元素可包含 crit 中列出的項目的超集。只要 crit 中列出的所有標頭都列在 <KnownHeaders> 元素中即可。任何政策在 crit 中找到的標頭,如果未列於 <KnownHeaders> 中,都會導致 VerifyJWT 政策失敗。

您可以選擇將 <IgnoreCriticalHeaders> 元素設為 true,藉此設定 VerifyJWT 政策,以便忽略 crit 標頭。

預設 不適用
在家狀態 選用
類型 以半形逗號分隔的字串陣列
有效值 陣列或含有陣列的變數名稱。

<MaxLifespan>

  <VerifyJWT name='VJWT-62'>
  ...
  <!-- hard-coded lifespan of 5 minutes -->
  <MaxLifespan>5m</MaxLifespan>

  or:

  <!-- refer to a variable -->
  <MaxLifespan ref='variable-here'/>

  or:

  <!-- attribute telling the policy to use iat rather than nbf -->
  <MaxLifespan useIssueTime='true'>1h</MaxLifespan>

  or:

  <!-- useIssueTime and ref, and hard-coded fallback value. -->
  <MaxLifespan useIssueTime='true' ref='variable-here'>1h</MaxLifespan>
  ...
  

設定 VerifyJWT 政策,檢查權杖的生命週期是否未超過指定的門檻。您可以使用數字後接字元來指定閾值,表示秒數、分鐘數、小時數、天數或週數。以下字元有效:

  • s - 秒
  • m - 分鐘
  • h - 小時
  • d - 天
  • w - 週

例如,您可以指定下列其中一個值:120 秒、10 分鐘、1 小時、7 天、3 週。

這項政策會從到期日值 (exp) 中減去不早於值 (nbf),藉此計算權杖的實際生命週期。如果缺少 expnbf,政策就會擲回錯誤。如果權杖的生命週期超過指定的時間範圍,政策就會擲回錯誤。

您可以將選用屬性 useIssueTime 設為 true,在計算權杖生命週期時使用 iat 值,而非 nbf 值。

您可以選擇是否使用 MaxLifespan 元素。如果使用這個元素,只能使用一次。

<PrivateKey>

使用這個元素指定私密金鑰,可用於驗證使用非對稱演算法加密的 JWT。以下說明可能的子元素。

<Password>

<PrivateKey>
  <Password ref="private.privatekey-password"/>
</PrivateKey>

<PrivateKey> 元素的子項。指定驗證已加密 JWT 時,政策應使用哪個密碼解密私密金鑰 (如有必要)。使用 ref 屬性,在流程變數中傳遞密碼。

預設 不適用
在家狀態 選用
類型 字串
有效值 流程變數參照。

注意:您必須指定流程變數。如果密碼是以純文字指定,Apigee 會將政策設定拒絕為無效。流程變數必須包含「private」前置字元。例如:private.mypassword

<Value>

<PrivateKey>
  <Value ref="private.variable-name-here"/>
</PrivateKey>

<PrivateKey> 元素的子項。指定政策將用來驗證加密 JWT 的 PEM 編碼私密金鑰。使用 ref 屬性,在流程變數中傳遞鍵。

預設 不適用
在家狀態 這是驗證使用非對稱金鑰加密演算法加密的 JWT 所需的值。
類型 字串
有效值 流程變數,其中包含代表 PEM 編碼 RSA 私密金鑰值的字串。

注意:流程變數必須包含「private」前置字串。例如: private.mykey

<PublicKey>

指定用於驗證以非對稱演算法簽署的 JWT 的公開金鑰來源。支援的演算法包括 RS256/RS384/RS512、PS256/PS384/PS512 或 ES256/ES384/ES512。以下說明可能的子元素。

<Certificate>

<PublicKey>
  <Certificate ref="signed_public.cert"/>
</PublicKey>

-or-

<PublicKey>
  <Certificate>
-----BEGIN CERTIFICATE-----
certificate data
-----END CERTIFICATE-----
  </Certificate>
</PublicKey>

<PublicKey> 元素的子項。指定用來做為公開金鑰來源的已簽署憑證。使用 ref 屬性,在流程變數中傳遞已簽署的憑證,或直接指定 PEM 編碼憑證。請務必將憑證資料對齊在左側,如參考範例所示。

預設 不適用
在家狀態 (選用步驟) 如要驗證使用非對稱演算法簽署的 JWT,您必須使用 <Certificate><JWKS><Value> 元素提供公開金鑰。
類型 字串
有效值 流程變數或字串。

<JWKS>

  <PublicKey>
    <JWKS …  > … </JWKS>
  </PublicKey>

<PublicKey> 元素的子項。指定 JWKS 做為公開金鑰來源。這會是按照 IETF RFC 7517 - JSON Web Key (JWK) 所述格式建立的金鑰清單。

如果傳入的 JWT 包含 JWKS 中的金鑰 ID,則政策會使用正確的公開金鑰驗證 JWT 簽名。如要進一步瞭解這項功能,請參閱「 使用 JSON Web Key Set (JWKS) 驗證 JWT」。

如果您從公開網址擷取值,Apigee 會將 JWKS 快取 300 秒。快取過期後,Apigee 會再次擷取 JWKS。

預設 不適用
在家狀態 (選用步驟) 如要驗證使用非對稱演算法簽署的 JWT,您必須使用 <Certificate><JWKS><Value> 元素提供公開金鑰。
類型 字串
有效值

您可以透過下列四種方式指定 JWKS:

  • 以文字形式,做為文字值:

      <PublicKey>
        <JWKS>{
          "keys": [
            {"kty":"RSA","e":"AQAB","kid":"b3918c88","n":"jxdm..."},
            {"kty":"RSA","e":"AQAB","kid":"24f094d4","n":"kWRdbgMQ..."}
          ]
        }
        </JWKS>
      </PublicKey>
  • 間接使用 ref 屬性指定流程變數:

      <PublicKey>
        <JWKS ref="variable-containing-jwks-content"/>
      </PublicKey>

    參照的變數應包含代表 JWKS 的字串。

  • 間接透過靜態 URI 使用 uri 屬性:

      <PublicKey>
        <JWKS uri="uri-that-returns-a-jwks"/>
      </PublicKey>
  • 間接透過動態決定的 uri,並使用 uriRef 屬性:

      <PublicKey>
        <JWKS uriRef="variable-containing-a-uri-that-returns-a-jwks"/>
      </PublicKey>

<Value>

<PublicKey>
  <Value ref="public.publickeyorcert"/>
</PublicKey>

-or-

<PublicKey>
  <Value>
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw2kPrRzcufvUNHvTH/WW
...YOUR PUBLIC KEY MATERIAL HERE....d1lH8MfUyRXmpmnNxJHAC2F73IyN
ZmkDb/DRW5onclGzxQITBFP3S6JXd4LNESJcTp705ec1cQ9Wp2Kl+nKrKyv1E5Xx
DQIDAQAB
-----END PUBLIC KEY-----
  </Value>
</PublicKey>

<PublicKey> 元素的子項。指定要用來驗證已簽署 JWT 簽名的公開金鑰。使用 ref 屬性在流程變數中傳遞金鑰,或直接指定 PEM 編碼金鑰。請務必將公開金鑰對齊在左側,如參考範例所示。

預設 不適用
在家狀態 (選用步驟) 如要驗證使用非對稱演算法簽署的 JWT,您必須使用 <Certificate><JWKS><Value> 元素提供公開金鑰。
類型 字串
有效值 流程變數或字串。

<RequiredClaims>

<VerifyJWT name='VJWT-1'>
  ...
  <!-- Directly specify the names of the claims to require -->
  <RequiredClaims>sub,iss,exp</RequiredClaims>

  -or-

  <!-- Specify the claim names indirectly, via a context variable -->
  <RequiredClaims ref='claims_to_require'/>
  ...
</VerifyJWT>

<RequiredClaims> 元素為選用元素。它會指定以半形逗號分隔的清單,列出驗證 JWT 時,JWT 酬載中必須出現的宣告名稱。這個元素可確保提交的 JWT 包含必要的宣告,但不會驗證宣告內容。如果沒有任何列出的宣告,VerifyJWT 政策會在執行階段擲回錯誤。

預設 不適用
在家狀態 選用
類型 字串
有效值 以半形逗號分隔的聲明名稱清單。

<SecretKey>

<SecretKey encoding="base16|hex|base64|base64url" >
  <Value ref="private.your-variable-name"/>
</SecretKey>
  

SecretKey 元素為選用元素。在驗證使用對稱 (HS*) 演算法的已簽署 JWT,或使用對稱 (AES) 演算法進行金鑰加密的加密 JWT 時,會指定要使用的密鑰。

<SecretKey> 的子項

下表說明 <SecretKey> 的子元素和屬性:

子項 存在必要性 說明
編碼 (屬性) 選用

指定在參照變數中如何編碼金鑰。根據預設,如果沒有 encoding 屬性,系統會將金鑰的編碼視為 UTF-8。有效值為十六進位、base16、base64 或 base64url。編碼值「hex」和「base16」是同義詞。

<SecretKey encoding="hex" >
  <Value ref="private.secretkey"/>
</SecretKey>

在上述範例中,由於編碼為 hex,如果變數 private.secretkey 的內容為 494c6f766541504973,則索引鍵會解碼為一組 9 個位元組,以十六進制表示為 49 4c 6f 76 65 41 50 49 73

值 (元素) 必填

已編碼的密鑰。指定用於驗證酬載的密鑰。使用 ref 屬性,透過變數 (例如 private.secret-key) 間接提供鍵。

<SecretKey>
  <Value ref="private.my-secret-variable"/>
</SecretKey>

Apigee 會強制執行 HS256/HS384/HS512 演算法的最低金鑰強度。HS256 的金鑰長度下限為 32 個位元組,HS384 為 48 個位元組,HS512 為 64 個位元組。使用強度較低的金鑰會導致執行階段錯誤。

<Source>

<Source>jwt-variable</Source>

如果有的話,請指定政策預期在哪個流程變數中找到要驗證的 JWT。

透過這個元素,您可以設定政策,從表單或查詢參數變數或任何其他變數中擷取 JWT。如果有這個元素,政策就不會移除任何可能存在的 Bearer 前置字串。如果變數不存在,或是政策未在指定的變數中找到 JWT,則政策會傳回錯誤。

根據預設,如果沒有 <Source> 元素,政策會透過讀取變數 request.header.authorization 並移除 Bearer 前置字元,擷取 JWT。如果您將 JWT 做為不記名權杖 (含 Bearer 前置字串) 傳遞至授權標頭,請勿在政策設定中指定 <Source> 元素。舉例來說,如果您在授權標頭中傳遞 JWT,則政策設定中不會使用 <Source> 元素,如下所示:

curl -v https://api-endpoint/proxy1_basepath/api1 -H "Authorization: Bearer eyJhbGciOiJ..."
預設 request.header.authorization (如需預設值的相關重要資訊,請參閱上述附註)。
在家狀態 選用
類型 字串
有效值 Apigee 流程變數名稱。

<Subject>

<VerifyJWT name='VJWT-8'>
  ...
  <!-- verify that the sub claim matches a hard-coded value -->
  <Subject>subject-string-here</Subject>

  or:

  <!-- verify that the sub claim matches the value contained in a variable -->
  <Subject ref='variable-containing-subject'/>

  or:

  <!-- verify via a variable; fallback to a hard-coded value if the variable is empty -->
  <Subject ref='variable-containing-subject'>fallback-value-here</Subject>

政策會驗證 JWT 中的主體 (sub 憑證附加資訊) 是否與政策設定中指定的字串相符。sub 宣告是 RFC7519 中所述的註冊宣告之一。

預設 不適用
在家狀態 選用
類型 字串
有效值 任何可用於識別主體的專屬值。

<TimeAllowance>

<VerifyJWT name='VJWT-23'>
  ...
  <!-- configure a hard-coded time allowance of 20 seconds -->
  <TimeAllowance>20s</TimeAllowance>

  or:

  <!-- refer to a variable containing the time allowance -->
  <TimeAllowance ref='variable-containing-time-allowance'/>

  or:

  <!-- refer to a variable; fallback to a hard-coded value if the variable is empty -->
  <TimeAllowance ref='variable-containing-allowance'>30s</TimeAllowance>
  

時間的「寬限期」,用於考量 JWT 發出者和驗證者之間的時鐘偏差。這項規定適用於到期日 (exp 權利要求) 和最早時間 (nbf 權利要求)。舉例來說,如果時間容許值設為 30s,則在已斷言的到期時間後的 30 秒內,過期的 JWT 會視為仍有效。系統會以類似方式評估 not-before-time。

預設 0 秒 (無寬限期)
在家狀態 選用
類型 字串
有效值 時間範圍運算式,或包含運算式的流程變數參照。時間間隔可以使用正整數指定,後面加上一個字元,表示時間單位,如下所示:
  • s = 秒
  • m = 分鐘
  • h = 小時
  • d = 天

<Type>

<Type>type-string-here</Type>

說明政策是驗證已簽署的 JWT 還是已加密的 JWT。<Type> 元素為選用元素。您可以使用它向讀者說明政策是產生已簽署的 JWT 還是已加密的 JWT。

  • 如果 <Type> 元素存在:
    • 如果 <Type> 的值為 Signed,政策會驗證已簽署的 JWT,且必須有 <Algorithm> 元素。
    • 如果 <Type> 的值為 Encrypted,則政策會驗證已加密的 JWT,且必須提供 <Algorithms> 元素。
  • 如果沒有 <Type> 元素:
    • 如果有 <Algorithm> 元素,政策會假設 <Type>Signed
    • 如果有 <Algorithms> 元素,政策會假設 <Type>Encrypted
  • 如果 <Algorithm><Algorithms> 都不存在,設定就會無效。
預設 不適用
在家狀態 選用
類型 字串
有效值 SignedEncrypted

流程變數

成功後,「驗證 JWT」和「解碼 JWT」政策會根據以下模式設定內容變數:

jwt.{policy_name}.{variable_name}

舉例來說,如果政策名稱為 jwt-parse-token,則政策會將 JWT 中指定的主體儲存至名為 jwt.jwt-parse-token.decoded.claim.sub 的內容變數。(為了兼顧回溯相容性,jwt.jwt-parse-token.claim.subject 也會提供這個類別)

變數名稱 說明
claim.audience JWT 目標對象憑證附加資訊。這個值可以是字串,也可以是字串陣列。
claim.expiry 到期日期/時間,自紀元時間起算的毫秒數。
claim.issuedat 權杖核發日期,以自 Epoch 起算的毫秒為單位。
claim.issuer JWT 核發者憑證附加資訊。
claim.notbefore 如果 JWT 包含 nbf 憑證附加資訊,這個變數就會包含該值,以自紀元起算的毫秒為單位。
claim.subject JWT 主體憑證附加資訊。
claim.name 酬載中命名宣告 (標準或額外) 的值。每個酬載中的每個聲明都會設定其中一個。
decoded.claim.name 酬載中命名宣告 (標準或額外) 的 JSON 可解析值。每個酬載中的宣告都會設定一個變數。舉例來說,您可以使用 decoded.claim.iat 擷取 JWT 的核發時間,以自 Epoch 起算的秒數為單位。雖然您也可以使用 claim.name 流程變數,但建議您使用這個變數來存取聲明。
decoded.header.name 酬載中標頭的 JSON 可剖析值。每個酬載標頭都會設定一個變數。您也可以使用 header.name 流程變數,但建議您使用這個變數來存取標頭。
expiry_formatted 到期日/時間,格式為人類可讀的字串。範例: 2017-09-28T21:30:45.000+0000
header.algorithm JWT 使用的簽署演算法。例如 RS256、HS384 等。詳情請參閱「(演算法) 標頭參數」一文。
header.kid 金鑰 ID (如果在產生 JWT 時新增)。如要驗證 JWT,請參閱「JWT 政策總覽」一文中的「使用 JSON Web Key Set (JWKS)」。詳情請參閱「(Key ID) 標頭參數」。
header.type 會設為 JWT
header.name 命名標頭的值 (標準或額外)。在 JWT 的標頭部分,每個額外標頭都會設定其中一個。
header-json 以 JSON 格式提供的標頭。
is_expired 是或否
payload-claim-names JWT 支援的陳述式陣列。
payload-json
JSON 格式的酬載。
seconds_remaining 權杖失效前的秒數。如果符記已到期,這個數字會為負數。
time_remaining_formatted 代碼到期前剩餘的時間,格式為人類可讀的字串。範例:00:59:59.926
valid 在 VerifyJWT 的情況下,如果簽名已驗證,且目前時間在權杖到期時間之前,且在權杖 notBefore 值之後 (如果有),這個變數就會設為 true。否則為 false。

在 DecodeJWT 的情況下,這個變數不會設定。

錯誤參考資料

本節說明這項政策觸發錯誤時,Apigee 傳回的錯誤代碼和錯誤訊息,以及 Apigee 設定的錯誤變數。如果您要開發錯誤處理錯誤規則,就必須瞭解這項資訊。如需更多資訊,請參閱「政策錯誤的相關資訊」和「處理錯誤」。

執行階段錯誤

政策執行時可能會發生這些錯誤。

錯誤代碼 HTTP 狀態 發生時機
steps.jwt.AlgorithmInTokenNotPresentInConfiguration 401 驗證政策包含多個演算法時會發生。
steps.jwt.AlgorithmMismatch 401 Generate 政策中指定的演算法與 Verify 政策中預期的演算法不符。指定的演算法必須相符。
steps.jwt.FailedToDecode 401 政策無法解碼 JWT。JWT 可能已損毀。
steps.jwt.GenerationFailed 401 政策無法產生 JWT。
steps.jwt.InsufficientKeyLength 401 金鑰長度必須小於 HS256 演算法的 32 個位元組、HS386 演算法的 48 個位元組,以及 HS512 演算法的 64 個位元組。
steps.jwt.InvalidClaim 401 缺少聲明或聲明不相符,或是缺少標頭或標頭不相符。
steps.jwt.InvalidConfiguration 401 <Algorithm><Algorithms> 元素都存在。
steps.jwt.InvalidCurve 401 金鑰指定的曲線不適用於橢圓曲線演算法。
steps.jwt.InvalidIterationCount 401 在加密 JWT 中使用的迭代計數不等於 VerifyJWT 政策設定中指定的迭代計數。這項規定僅適用於使用 <PasswordKey> 的 JWT。
steps.jwt.InvalidJsonFormat 401 標頭或酬載中發現無效的 JSON。
steps.jwt.InvalidKeyConfiguration 401 <PublicKey> 元素中的 JWKS 無效。原因可能是從 Apigee 執行個體無法存取 JWKS URI 端點。建立轉送 Proxy,並使用 JWKS 端點做為目標,測試端點的連線能力。
steps.jwt.InvalidSaltLength 401 在加密 JWT 中使用的鹽值長度與 VerifyJWT 政策設定中指定的鹽值長度不符。這項規定僅適用於使用 <PasswordKey> 的 JWT。
steps.jwt.InvalidPasswordKey 401 指定的鍵不符合規定。
steps.jwt.InvalidPrivateKey 401 指定的鍵不符合規定。
steps.jwt.InvalidPublicKey 401 指定的鍵不符合規定。
steps.jwt.InvalidSecretKey 401 指定的鍵不符合規定。
steps.jwt.InvalidToken 401 當 JWT 簽名驗證失敗時,就會發生此錯誤。
steps.jwt.JwtAudienceMismatch 401 目標對象權利聲明在權杖驗證時失敗。
steps.jwt.JwtIssuerMismatch 401 發出者權利聲明在權杖驗證時失敗。
steps.jwt.JwtSubjectMismatch 401 主體宣告在權杖驗證時失敗。
steps.jwt.KeyIdMissing 401 Verify 政策會使用 JWKS 做為公開金鑰來源,但已簽署的 JWT 不會在標頭中加入 kid 屬性。
steps.jwt.KeyParsingFailed 401 無法從指定的金鑰資訊剖析公開金鑰。
steps.jwt.NoAlgorithmFoundInHeader 401 當 JWT 不含演算法標頭時,就會發生此錯誤。
steps.jwt.NoMatchingPublicKey 401 Verify 政策使用 JWKS 做為公開金鑰來源,但已簽署 JWT 中的 kid 並未列在 JWKS 中。
steps.jwt.SigningFailed 401 在 GenerateJWT 中,如果金鑰小於 HS384 或 HS512 演算法的最小大小
steps.jwt.TokenExpired 401 政策嘗試驗證已過期的權杖。
steps.jwt.TokenNotYetValid 401 權杖尚未生效。
steps.jwt.UnhandledCriticalHeader 401 crit 標頭中由「驗證 JWT」政策所找到的標頭,並未列在 KnownHeaders 中。
steps.jwt.UnknownException 401 發生不明例外狀況。
steps.jwt.WrongKeyType 401 指定的金鑰類型有誤。例如,如果您為橢圓曲線演算法指定 RSA 金鑰,或為 RSA 演算法指定曲線金鑰。

部署錯誤

部署含有這項政策的 Proxy 時,可能會發生這些錯誤。

錯誤名稱 原因 修正
InvalidNameForAdditionalClaim 如果 <AdditionalClaims> 元素子元素 <Claim> 中使用的宣稱是下列已註冊名稱之一:kidisssubaudiatexpnbfjti,則部署作業會失敗。
InvalidTypeForAdditionalClaim 如果 <AdditionalClaims> 元素子元素 <Claim> 中使用的宣稱不是 stringnumberbooleanmap 類型,則部署作業會失敗。
MissingNameForAdditionalClaim 如果在 <AdditionalClaims> 元素的子元素 <Claim> 中未指定權杖名稱,則部署作業會失敗。
InvalidNameForAdditionalHeader 如果 <AdditionalClaims> 元素的子元素 <Claim> 中使用的聲明名稱為 algtyp,就會發生此錯誤。
InvalidTypeForAdditionalHeader 如果 <AdditionalClaims> 元素子元素 <Claim> 中使用的宣稱類型不是 stringnumberbooleanmap 類型,則部署作業會失敗。
InvalidValueOfArrayAttribute 如果 <AdditionalClaims> 元素的子元素 <Claim> 中陣列屬性的值未設為 truefalse,就會發生這個錯誤。
InvalidValueForElement 如果 <Algorithm> 元素中指定的值不是支援的值,則部署作業會失敗。
MissingConfigurationElement 如果 <PrivateKey> 元素未與 RSA 系列演算法搭配使用,或 <SecretKey> 元素未與 HS 系列演算法搭配使用,就會發生這個錯誤。
InvalidKeyConfiguration 如果在 <PrivateKey><SecretKey> 元素中未定義子元素 <Value>,則部署作業會失敗。
EmptyElementForKeyConfiguration 如果 <PrivateKey><SecretKey> 元素的子元素 <Value> 的 ref 屬性為空白或未指定,部署作業就會失敗。
InvalidConfigurationForVerify 如果 <Id> 元素是在 <SecretKey> 元素中定義,就會發生這個錯誤。
InvalidEmptyElement 如果「驗證 JWT」政策的 <Source> 元素為空白,就會發生這個錯誤。如果有此值,則必須使用 Apigee 流程變數名稱定義。
InvalidPublicKeyValue 如果 <PublicKey> 元素子元素 <JWKS> 中使用的值並未採用 RFC 7517 中指定的有效格式,則部署作業會失敗。
InvalidConfigurationForActionAndAlgorithm 如果 <PrivateKey> 元素與 HS Family 演算法搭配使用,或是 <SecretKey> 元素與 RSA Family 演算法搭配使用,則部署作業會失敗。

錯誤變數

這些變數會在發生執行階段錯誤時設定。詳情請參閱「關於政策錯誤的相關資訊」。

變數 地點 範例
fault.name="fault_name" fault_name 是錯誤名稱,如上方「執行階段錯誤」表格所列。錯誤名稱是錯誤代碼的最後一個部分。 fault.name Matches "InvalidToken"
JWT.failed 所有 JWT 政策在失敗的情況下都會設定相同的變數。 JWT.failed = true

錯誤回應範例

JWT 政策錯誤代碼

針對錯誤處理,最佳做法是擷取錯誤回應的 errorcode 部分。請勿依賴 faultstring 中的文字,因為該文字可能會變更。

錯誤規則範例

    <FaultRules>
        <FaultRule name="JWT Policy Errors">
            <Step>
                <Name>JavaScript-1</Name>
                <Condition>(fault.name Matches "InvalidToken")</Condition>
            </Step>
            <Condition>JWT.failed=true</Condition>
        </FaultRule>
    </FaultRules>