本頁內容適用於 Apigee 和 Apigee Hybrid。
查看
Apigee Edge 說明文件。
VerifyJWT 政策會驗證簽署的 JWT,或解密並驗證從用戶端或其他系統收到的加密 JWT。這項政策也會將聲明擷取至環境變數中,以便後續政策或條件檢查這些值,做出授權或路由決策。如需詳細簡介,請參閱 JWS 和 JWT 政策總覽。
執行這項政策時,如果是已簽署的 JWT,Apigee 會使用提供的驗證金鑰驗證 JWT 的簽名。如果是加密的 JWT,Apigee 會使用解密金鑰解密 JWT。無論是哪種情況,Apigee 隨後都會根據到期時間和生效時間 (如有) 驗證 JWT 是否有效。這項政策也可以選擇性驗證 JWT 中特定憑證附加資訊的值,例如主體、簽發者、目標對象或額外憑證附加資訊的值。
如果 JWT 經過驗證且有效,系統會將 JWT 中包含的所有聲明擷取到環境變數中,供後續政策或條件使用,並允許要求繼續進行。如果無法驗證 JWT 簽章,或 JWT 因其中一個時間戳記而無效,系統會停止所有處理作業,並在回應中傳回錯誤。
政策是否驗證已簽署或加密的 JWT,取決於您用來指定 JWT 驗證演算法的元素:
- 如果您使用
<Algorithm>元素,政策會驗證已簽署的 JWT。 - 如果使用
<Algorithms>元素,政策會驗證加密的 JWT。
這項政策是標準政策,可部署至任何環境類型。如要瞭解各環境類型適用的政策類型和可用性,請參閱「政策類型」。
如要瞭解 JWT 的各個部分,以及加密和簽署方式,請參閱 RFC7519。
驗證已簽署的 JWT
本節說明如何驗證已簽署的 JWT。如為已簽署的 JWT,請使用 <Algorithm> 元素指定金鑰簽署演算法。
已簽署 JWT 的範例
下列範例說明如何驗證已簽署的 JWT。
HS256 演算法
這個範例政策會驗證以 HS256 加密演算法簽署的 JWT,並使用 SHA-256 核對和的 HMAC。JWT 會透過名為 jwt 的表單參數,在 Proxy 要求中傳遞。金鑰包含在名為 private.secretkey 的變數中。
如需完整範例,包括如何向政策提出要求,請參閱上方影片。
政策設定包含 Apigee 解碼及評估 JWT 所需的資訊,例如 JWT 的位置 (位於「來源」元素中指定的流程變數)、必要的簽署演算法、私密金鑰的位置 (儲存在 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 代理程式中的後續政策或條件檢查這些值。如要查看這項政策設定的變數清單,請參閱「流程變數」。
RS256 演算法
這個範例政策會驗證以 RS256 演算法簽署的 JWT。如要驗證,請提供公開金鑰。JWT 會透過名為 jwt 的表單參數,在 Proxy 要求中傳遞。公開金鑰包含在名為 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 代理程式中的後續政策或條件檢查這些值。如要查看這項政策設定的變數清單,請參閱「流程變數」。
上述範例使用 <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 私密金鑰。 |
|
<PrivateKey> <Value ref="private.ec_privatekey"/> </PrivateKey> 注意:您指定的變數必須解析為 PEM 編碼格式的橢圓曲線私密金鑰。 |
|
<SecretKey encoding="base16|hex|base64|base64url"> <Value ref="private.flow-variable-name-here"/> </SecretKey> |
|
<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 使用者介面會強制執行其他限制,例如自動移除非英數字元。
視需要使用 |
不適用 | 必填 |
| continueOnError |
設為 false,以便在政策失敗時傳回錯誤。這是大多數政策的預期行為。
設為 |
false | 選用 |
| 已啟用 |
設為 true 即可強制執行政策。
設為 |
true | 選用 |
| 非同步 | 這項屬性已淘汰。 | false | 已淘汰 |
<DisplayName>
<DisplayName>Policy Display Name</DisplayName>
除了名稱屬性之外,您也可以使用這個屬性,在管理 UI 代理編輯器中,以其他自然語言名稱標示政策。
| 預設 | 如果省略這個元素,系統會使用政策名稱屬性的值。 |
| 外觀狀態 | 選用 |
| 類型 | 字串 |
<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> |
|
<SecretKey> |
|
<PasswordKey> |
|
<PrivateKey> |
如需金鑰加密演算法為 RSA-OAEP-256 的範例,請參閱「驗證加密的 JWT」,瞭解如何使用 <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>
注意:目前透過 UI 新增 GenerateJWT 政策時,系統會插入 CustomClaims 元素。這個元素無法運作,因此會遭到忽略。請改用 <AdditionalClaims> 元素。使用者介面會在稍後更新,插入正確的元素。
<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 |
| 外觀狀態 | 選用 |
| 類型 | 布林值 |
| 有效值 | true 或 false |
<IgnoreIssuedAt>
<IgnoreIssuedAt>true|false</IgnoreIssuedAt>
如果 JWT 包含指定未來時間的 iat (核發時間) 聲明,且您希望政策擲回錯誤,請設為 false (預設值)。設為 true,讓政策在驗證期間忽略 iat。
| 預設 | false |
| 外觀狀態 | 選用 |
| 類型 | 布林值 |
| 有效值 | true 或 false |
<IgnoreUnresolvedVariables>
<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>
如果希望政策在無法解析政策中指定的任何參照變數時擲回錯誤,請設為 false。設為 true 可將任何無法解析的變數視為空字串 (空值)。
| 預設 | 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" ],
}如果 JWT 中有 crit 標頭,VerifyJWT 政策會檢查該標頭,並確認 <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- 週
例如,您可以指定下列其中一個值:120s、10m、1h、7d、3w。
這項政策會從到期值 (exp) 減去生效前值 (nbf),計算權杖的實際生命週期。如果缺少 exp 或 nbf,政策就會擲回錯誤。如果權杖生命週期超過指定時間範圍,政策就會擲回錯誤。
您可以將選用屬性 useIssueTime 設為 true,在計算權杖生命週期時使用 iat 值,而非 nbf 值。
MaxLifespan 元素為選用項目。如果使用這個元素,只能使用一次。
<PrivateKey>
使用這個元素指定私密金鑰,可用於驗證以非對稱演算法加密的 JWT。以下說明可能的子元素。
<Password>
<PrivateKey> <Password ref="private.privatekey-password"/> </PrivateKey>
<PrivateKey> 元素的子項。指定政策在驗證加密 JWT 時,如有必要,應使用哪個密碼解密私密金鑰。使用 ref 屬性,在流程變數中傳遞密碼。
| 預設 | 不適用 |
| 外觀狀態 | 選用 |
| 類型 | 字串 |
| 有效值 |
流程變數參照。
注意:您必須指定流程變數。如果政策設定以純文字指定密碼,Apigee 會拒絕這項設定,視為無效。流程變數必須以「private」為前置字元。例如: |
<Value>
<PrivateKey> <Value ref="private.variable-name-here"/> </PrivateKey>
<PrivateKey> 元素的子項。指定政策用來驗證加密 JWT 的 PEM 編碼私密金鑰。使用 ref 屬性,在流程變數中傳遞金鑰。
| 預設 | 不適用 |
| 外觀狀態 | 驗證使用非對稱金鑰加密演算法加密的 JWT 時,必須提供這項資訊。 |
| 類型 | 字串 |
| 有效值 |
包含字串的流程變數,代表 PEM 編碼的 RSA 私密金鑰值。
注意:流程變數必須加上「private」前置字元。例如:
|
<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:
|
<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> 的子元素和屬性:
| 子項 | 狀態 | 說明 |
|---|---|---|
| 編碼 (屬性) | 選用 | 指定如何編碼參照變數中的金鑰。根據預設,如果沒有 <SecretKey encoding="hex" > <Value ref="private.secretkey"/> </SecretKey> 在上述範例中,由於編碼為 |
| 值 (元素) | 必填 | 經過編碼的密鑰。指定用於驗證酬載的私密金鑰。使用 <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。如果您在 Authorization 標頭中以不記名權杖形式傳遞 JWT (加上 Bearer 前置字串),請勿在政策設定中指定 <Source> 元素。舉例來說,如果您在 Authorization 標頭中傳遞 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 秒 (無寬限期) |
| 外觀狀態 | 選用 |
| 類型 | 字串 |
| 有效值 |
時間範圍運算式,或包含運算式的流程變數參照。
時間範圍可以指定為正整數,後接一個表示時間單位的字元,如下所示:
|
<Type>
<Type>type-string-here</Type>
說明政策是否驗證已簽署或加密的 JWT。
<Type> 元素為選用項目。您可以使用這項屬性,向讀者說明政策是否會產生已簽署或加密的 JWT。
- 如果存在
<Type>元素:- 如果
<Type>的值為Signed,政策會驗證已簽署的 JWT,且必須存在<Algorithm>元素。 - 如果
<Type>的值為Encrypted,政策會驗證加密的 JWT,且必須存在<Algorithms>元素。
- 如果
- 如果沒有
<Type>元素:- 如果存在
<Algorithm>元素,政策會假設<Type>為Signed。 - 如果存在
<Algorithms>元素,政策會假設<Type>為Encrypted。
- 如果存在
- 如果沒有
<Algorithm>或<Algorithms>,設定無效。
| 預設 | 不適用 |
| 外觀狀態 | 選用 |
| 類型 | 字串 |
| 有效值 | Signed 或 Encrypted |
流程變數
成功後,「驗證 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> 中使用的宣稱是下列已註冊名稱之一:kid、iss、sub、aud、iat、exp、nbf 或 jti,則部署作業會失敗。 |
build |
InvalidTypeForAdditionalClaim |
如果 <AdditionalClaims> 元素子元素 <Claim> 中使用的宣稱不是 string、number、boolean 或 map 類型,則部署作業會失敗。 |
build |
MissingNameForAdditionalClaim |
如果在 <AdditionalClaims> 元素的子元素 <Claim> 中未指定權杖名稱,則部署作業會失敗。 |
build |
InvalidNameForAdditionalHeader |
如果 <AdditionalClaims> 元素的子元素 <Claim> 中使用的聲明名稱為 alg 或 typ,就會發生此錯誤。 |
build |
InvalidTypeForAdditionalHeader |
如果 <AdditionalClaims> 元素子元素 <Claim> 中使用的宣稱類型不是 string、number、boolean 或 map 類型,則部署作業會失敗。 |
build |
InvalidValueOfArrayAttribute |
如果 <AdditionalClaims> 元素的子元素 <Claim> 中陣列屬性的值未設為 true 或 false,就會發生這個錯誤。 |
build |
InvalidValueForElement |
如果 <Algorithm> 元素中指定的值不是支援的值,則部署作業會失敗。 |
build |
MissingConfigurationElement |
如果 <PrivateKey> 元素未與 RSA 系列演算法搭配使用,或 <SecretKey> 元素未與 HS 系列演算法搭配使用,就會發生這個錯誤。 |
build |
InvalidKeyConfiguration |
如果在 <PrivateKey> 或 <SecretKey> 元素中未定義子元素 <Value>,則部署作業會失敗。 |
build |
EmptyElementForKeyConfiguration |
如果 <PrivateKey> 或 <SecretKey> 元素的子元素 <Value> 的 ref 屬性為空白或未指定,部署作業就會失敗。 |
build |
InvalidConfigurationForVerify |
如果 <Id> 元素是在 <SecretKey> 元素中定義,就會發生這個錯誤。 |
build |
InvalidEmptyElement |
如果「驗證 JWT」政策的 <Source> 元素為空白,就會發生這個錯誤。如果有此值,則必須使用 Apigee 流程變數名稱定義。 |
build |
InvalidPublicKeyValue |
如果 <PublicKey> 元素子元素 <JWKS> 中使用的值並未採用 RFC 7517 中指定的有效格式,則部署作業會失敗。 |
build |
InvalidConfigurationForActionAndAlgorithm |
如果 <PrivateKey> 元素與 HS Family 演算法搭配使用,或是 <SecretKey> 元素與 RSA Family 演算法搭配使用,則部署作業會失敗。 |
build |
錯誤變數
這些變數會在發生執行階段錯誤時設定。詳情請參閱「關於政策錯誤的相關資訊」。
| 變數 | 地點 | 範例 |
|---|---|---|
fault.name="fault_name" |
fault_name 是錯誤名稱,如上方「執行階段錯誤」表格所列。錯誤名稱是錯誤代碼的最後一個部分。 | fault.name Matches "InvalidToken" |
JWT.failed |
所有 JWT 政策在失敗的情況下都會設定相同的變數。 | JWT.failed = true |
錯誤回應範例
針對錯誤處理,最佳做法是擷取錯誤回應的 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>