您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件。 info
結果
驗證從用戶端或其他系統收到的 JWS 簽章。這項政策也會將標頭擷取至環境變數,以便後續政策或條件檢查這些值,做出授權或路徑決策。如需詳細簡介,請參閱 JWS 和 JWT 政策總覽。
如果 JWS 經過驗證且有效,要求即可繼續執行。如果無法驗證 JWS 簽章,或因某種錯誤導致 JWS 無效,系統會停止所有處理作業,並在回應中傳回錯誤。
如要瞭解 JWS 的各個部分,以及加密和簽署方式,請參閱 RFC7515。
影片
請觀看短片,瞭解如何驗證 JWS 的簽章。雖然這部影片專門介紹如何驗證 JWT,但許多概念也適用於 JWS。
範例
驗證以 HS256 演算法簽署的附加 JWS
這項範例政策會驗證以 HS256 加密演算法簽署的附加 JWS,並使用 SHA-256 總和檢查碼。JWS 會透過名為 JWS 的表單參數,在 Proxy 要求中傳遞。金鑰包含在名為 private.secretkey 的變數中。
附加的 JWS 包含編碼的標頭、酬載和簽章:
header.payload.signature
政策設定包含 Edge 解碼及評估 JWS 時所需的資訊,例如 JWS 的位置 (位於 <Source> 元素中指定的流程變數)、必要的簽署演算法,以及私密金鑰的位置 (儲存在 Edge 流程變數中,例如可能從 Edge KVM 擷取)。
<VerifyJWS name="JWS-Verify-HS256">
<DisplayName>JWS Verify HS256</DisplayName>
<Algorithm>HS256</Algorithm>
<Source>request.formparam.JWS</Source>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<SecretKey>
<Value ref="private.secretkey"/>
</SecretKey>
</VerifyJWS>這項政策會將輸出內容寫入環境變數,以便 API Proxy 中的後續政策或條件檢查這些值。如要查看這項政策設定的變數清單,請參閱「流程變數」。
驗證以 RS256 演算法簽署的分離式 JWS
這個範例政策會驗證以 RS256 演算法簽署的分離式 JWS。如要驗證,請提供公開金鑰。JWS 會透過名為 JWS 的表單參數,在 Proxy 要求中傳遞。公開金鑰包含在名為 public.publickey 的變數中。
分離式 JWS 會從 JWS 省略酬載:
header..signature
您可以指定包含酬載的變數名稱給 <DetachedContent> 元素,將酬載傳遞至 VerifyJWS 政策。<DetachedContent> 中指定的內容必須是建立 JWS 簽章時的原始未編碼形式。
<VerifyJWS name="JWS-Verify-RS256"> <DisplayName>JWS Verify RS256</DisplayName> <Algorithm>RS256</Algorithm> <Source>request.formparam.JWS</Source> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <PublicKey> <Value ref="public.publickey"/> </PublicKey> <DetachedContent>private.payload</DetachedContent> </VerifyJWS>
這項政策會將輸出內容寫入環境變數,以便 API Proxy 中的後續政策或條件檢查這些值。如要查看這項政策設定的變數清單,請參閱「流程變數」。
設定主要元素
用來指定驗證 JWS 金鑰的元素取決於所選演算法,如下表所示:
| 演算法 | 重要元素 | |
|---|---|---|
| HS* |
<SecretKey> <Value ref="private.secretkey"/> </SecretKey> |
|
| RS*、ES*、PS* | <PublicKey> <Value ref="rsa_public_key"/> </PublicKey> 或是: <PublicKey> <JWKS ref="jwks_val_ref_or_url"/> </PublicKey> |
|
| *如要進一步瞭解金鑰規定,請參閱「簽章加密演算法簡介」。 | ||
元素參考資料
政策參考資料說明「驗證 JWS」政策的元素和屬性。
注意:設定會因使用的加密演算法而略有不同。如需特定用途的設定範例,請參閱「範例」。
適用於頂層元素的屬性
<VerifyJWS name="JWS" continueOnError="false" enabled="true" async="false">
所有政策父項元素都有下列屬性。
| 屬性 | 說明 | 預設 | 外觀狀態 |
|---|---|---|---|
| 名稱 |
政策的內部名稱。名稱只能使用以下字元:
A-Z0-9._\-$ %。不過,Edge 管理 UI 會強制執行其他限制,例如自動移除非英數字元的字元。
視需要使用 |
N/A | 必填 |
| continueOnError |
設為 false,在政策失敗時傳回錯誤。這是大多數政策的預期行為。
設為 |
false | 選用 |
| 已啟用 |
設為 true 即可強制執行政策。
設為 |
true | 選用 |
| 非同步 | 這項屬性已淘汰。 | false | 已淘汰 |
<DisplayName>
<DisplayName>Policy Display Name</DisplayName>
除了名稱屬性外,您還可以使用這個屬性,在管理 UI 代理項目編輯器中,以其他自然語言名稱標示政策。
| 預設 | 如果省略這個元素,系統會使用政策名稱屬性的值。 |
| 外觀狀態 | 選用 |
| 類型 | 字串 |
<Algorithm>
<Algorithm>HS256</Algorithm>
指定用來簽署權杖的加密演算法。RS*/PS*/ES* 演算法採用公開/私密金鑰組,而 HS* 演算法則採用共用密鑰。另請參閱「 簽章加密演算法簡介」。
您可以指定多個值 (以半形逗號分隔)。例如「HS256、HS512」或「RS256、PS256」。 不過,HS* 演算法無法與其他演算法合併使用,ES* 演算法也無法與其他演算法合併使用,因為這些演算法需要特定金鑰類型。您可以結合 RS* 和 PS* 演算法。
| 預設 | N/A |
| 外觀狀態 | 必填 |
| 類型 | 以半形逗號分隔的值字串 |
| 有效值 | HS256、HS384、HS512、RS256、RS384、RS512、ES256、ES384、ES512、PS256、PS384、PS512 |
<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>
驗證 JWS 標頭是否包含指定的額外聲明名稱/值組,以及聲明的值是否相符。
額外聲明使用的名稱並非標準、已註冊的 JWS 聲明名稱。額外聲明的值可以是字串、數字、布林值、對應或陣列。對應只是一組名稱/值組合。您可以在政策設定中明確指定任何這類型態的聲明值,也可以透過參照流程變數間接指定。
| 預設 | N/A |
| 外觀狀態 | 選用 |
| 類型 |
字串 (預設值)、數字、布林值或對應。 如未指定類型,預設為 String。 |
| 陣列 | 設為 true,表示值是否為型別陣列。預設值: false |
| 有效值 | 您要用於額外聲明的任何值。 |
<Claim> 元素會採用下列屬性:
- name - (必要) 聲明名稱。
- ref - (選用) 流程變數的名稱。如果存在,政策會使用這個變數的值做為聲明。如果同時指定 ref 屬性和明確的聲明值,則預設會使用明確值,且如果參照的流程變數未解析,也會使用明確值。
- type - (選用) 其中一個:字串 (預設)、數字、布林值或對應
- array - (選用) 設為 true,表示值是否為型別陣列。預設值: false。
<DetachedContent>
<DetachedContent>variable-name-here</DetachedContent>
產生的 JWS 含有內容酬載,格式如下:
header.payload.signature
如果您使用 GenerateJWS 政策建立分離式酬載,產生的 JWS 會省略酬載,且格式如下:
header..signature
如果是分離式酬載,您必須使用 <DetachedContent> 元素,將酬載傳遞至 VerifyJWS 政策。指定內容酬載必須採用原始未編碼形式,也就是建立 JWS 簽章時的形式。
在下列情況下,政策會擲回錯誤:
- 如果 JWS 不含已卸離的內容酬載,則會指定
<DetachedContent>(錯誤代碼為steps.jws.ContentIsNotDetached)。 <DetachedContent>已省略,且 JWS 具有分離的內容酬載 (錯誤代碼為steps.jws.InvalidSignature)。
| 預設 | N/A |
| 外觀狀態 | 選用 |
| 類型 | 變數參照 |
<IgnoreCriticalHeaders>
<IgnoreCriticalHeaders>true|false</IgnoreCriticalHeaders>
如果 JWS 的 crit 標頭中列出的任何標頭未列在 <KnownHeaders> 元素中,且您希望政策擲回錯誤,請設為 false。
設為 true 可讓 VerifyJWS 政策忽略 crit 標頭。
將這個元素設為 true 的原因之一,是如果您處於測試環境,且不希望因缺少標頭而導致政策失敗,
| 預設 | false |
| 外觀狀態 | 選用 |
| 類型 | 布林值 |
| 有效值 | true 或 false |
<IgnoreUnresolvedVariables>
<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>
如果希望政策在無法解析政策中指定的任何參照變數時擲回錯誤,請設為 false。設為 true 可將任何無法解析的變數視為空字串 (空值)。
| 預設 | false |
| 外觀狀態 | 選用 |
| 類型 | 布林值 |
| 有效值 | true 或 false |
<KnownHeaders>
<KnownHeaders>a,b,c</KnownHeaders> or: <KnownHeaders ref=’variable_containing_headers’/>
GenerateJWS 政策會使用 <CriticalHeaders> 元素,在權杖中填入 crit 標頭。例如:
{
“typ: “...”,
“alg” : “...”,
“crit” : [ “a”, “b”, “c” ],
}VerifyJWS 政策會檢查 JWS 中的 crit 標頭 (如有),並針對列出的每個項目,檢查 <KnownHeaders> 元素是否也列出該標頭。<KnownHeaders> 元素可包含 crit 中列出的項目超集。只要 crit 中列出的所有標頭都列在 <KnownHeaders> 元素中即可。如果政策在 crit 中找到任何標頭,但該標頭未列在 <KnownHeaders> 中,就會導致 VerifyJWS 政策失敗。
您可以視需要將 <IgnoreCriticalHeaders> 元素設為 true,讓 VerifyJWS 政策忽略 crit 標頭。
| 預設 | N/A |
| 外觀狀態 | 選用 |
| 類型 | 以半形逗號分隔的字串陣列 |
| 有效值 | 陣列或含有陣列的變數名稱。 |
<PublicKey/JWKS>
<!-- Specify the JWKS. --> <PublicKey> <JWKS>jwks-value-here</JWKS> </PublicKey> or: <!-- Specify a variable containing the JWKS. --> <PublicKey> <JWKS ref="public.jwks"/> </PublicKey> or: <!-- Specify a public URL that returns the JWKS. The URL is static, meaning you cannot set it using a variable. --> <PublicKey> <JWKS uri="jwks-url"/> </PublicKey>
以 JWKS 格式 (RFC 7517) 指定值,其中包含一組公開金鑰。僅在演算法為 RS256/RS384/RS512、PS256/PS384/PS512 或 ES256/ES384/ES512 時使用。
如果傳入的 JWS 含有 JWKS 集合中的金鑰 ID,政策就會使用正確的公開金鑰驗證 JWS 簽章。如要瞭解這項功能的詳細資訊,請參閱「 使用 JSON Web Key Set (JWKS) 驗證 JWS」。
如果您從公開網址擷取值,Edge 會將 JWKS 快取 300 秒。快取過期時,Edge 會再次擷取 JWKS。
| 預設 | N/A |
| 外觀狀態 | 如要使用 RSA 演算法驗證 JWS,必須使用 JWKS 或 Value 元素。 |
| 類型 | 字串 |
| 有效值 | 流程變數、字串值或網址。 |
<PublicKey/Value>
<PublicKey> <Value ref="public.publickey"/> </PublicKey> -or- <PublicKey> <Value> -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw2kPrRzcufvUNHvTH/WW Q0UrCw5c0+Y707KX3PpXkZGbtTT4nvU1jC0d1lHV8MfUyRXmpmnNxJHAC2F73IyN C5TBtXMORc+us7A2cTtC4gZV256bT4h3sIEMsDl0Joz9K9MPzVPFxa1i0RgNt06n Xn/Bs2UbbLlKP5Q1HPxewUDEh0gVMqz9wdIGwH1pPxKvd3NltYGfPsUQovlof3l2 ALvO7i5Yrm96kknfFEWf1EjmCCKvz2vjVbBb6mp1ZpYfc9MOTZVpQcXSbzb/BWUo ZmkDb/DRW5onclGzxQITBFP3S6JXd4LNESJcTp705ec1cQ9Wp2Kl+nKrKyv1E5Xx DQIDAQAB -----END PUBLIC KEY----- </Value> </PublicKey>
指定用於驗證 JWS 簽章的公開金鑰。使用 ref 屬性在流程變數中傳遞金鑰,或直接指定 PEM 編碼金鑰。僅在演算法為 RS256/RS384/RS512、PS256/PS384/PS512 或 ES256/ES384/ES512 時使用。
| 預設 | N/A |
| 外觀狀態 | 如要驗證以 RSA 演算法簽署的 JWS,您必須使用 JWKS 或 Value 元素。 |
| 類型 | 字串 |
| 有效值 | 流程變數或字串。 |
<SecretKey/Value>
<SecretKey> <Value ref="private.your-variable-name"/> </SecretKey>
提供用於以 HMAC 演算法驗證或簽署權杖的私密金鑰。只有在演算法為 HS256、HS384 或 HS512 時才使用。使用 ref 屬性在流程變數中傳遞金鑰。
| 預設 | N/A |
| 外觀狀態 | HMAC 演算法需要這項資訊。 |
| 類型 | 字串 |
| 有效值 |
參照字串的流程變數。
注意:如果是流程變數,則必須加上「private」前置字元。例如:
|
<Source>
<Source>JWS-variable</Source>
如果存在,則指定政策預期會找到要驗證的 JWS 的流程變數。
| 預設 | request.header.authorization (請參閱上方的附註,瞭解預設值的重要資訊)。 |
| 外觀狀態 | 選用 |
| 類型 | 字串 |
| 有效值 | Edge 流程變數名稱。 |
流程變數
成功時,已設定「Verify JWS」(驗證 JWS) 和「Decode JWS」(解碼 JWS) 政策。 結構定義變數:
jws.{policy_name}.{variable_name}
舉例來說,如果政策名稱為 verify-jws,則政策會儲存
將 JWS 中指定的演算法套用至此結構定義變數:
jws.verify-jws.header.algorithm
| 變數名稱 | 說明 |
|---|---|
decoded.header.name |
酬載中標頭的 JSON 可剖析值。針對以下項目設定一個變數:
。雖然您也可以使用 header.name 流程變數,
這是存取標頭的建議變數。 |
header.algorithm |
JWS 使用的簽署演算法。例如 RS256、HS384 等。 詳情請參閱「(演算法) 標頭參數」。 |
header.kid |
金鑰 ID (如果已在產生 JWS 時加入)。另請參閱「使用 JSON 網路金鑰組 (JWKS)。」在 JWT 和 JWS 中 政策總覽,藉此驗證 JWS。 詳情請參閱(金鑰 ID) 標頭參數。 |
header.type |
標頭類型值。 詳情請見(Type) 標頭參數。 |
header.name |
命名標頭的值 (標準或其他)。系統會在以下情況下 每個額外標頭 (JWS) 的標頭 |
header-json |
JSON 格式的標頭。 |
payload |
如果 JWS 有附加酬載,則為 JWS 酬載。如果是卸離的酬載,這個變數會是空的。 |
valid |
以 VerifyJWS 來說,在簽名驗證後,這個變數將為 true;
目前時間是在權杖到期前,以及符記 notBefore 值之後 (如果有的話)
。否則為 false。
若是 DecodeJWS,則未設定此變數。 |
錯誤參考資料
本節說明當這項政策觸發錯誤時,傳回的錯誤代碼和錯誤訊息,以及 Edge 設定的錯誤變數。 如果您正在開發錯誤規則來處理錯誤,請務必瞭解這項資訊。詳情請參閱「政策錯誤須知」和「處理錯誤」。
執行階段錯誤
執行政策時,可能會發生這些錯誤。
| 錯誤代碼 | HTTP 狀態 | 發生時機 |
|---|---|---|
steps.jws.AlgorithmInTokenNotPresentInConfiguration |
401 | 驗證政策採用多個演算法時發生 |
steps.jws.AlgorithmMismatch |
401 | 產生政策在標頭中指定的演算法與驗證政策中預期的演算法不符。指定的演算法必須相符。 |
steps.jws.ContentIsNotDetached |
401 | 當 JWS 不包含已卸離的內容酬載時,系統會指定 <DetachedContent>。 |
steps.jws.FailedToDecode |
401 | 政策無法解碼 JWS。JWS 可能已損毀。 |
steps.jws.InsufficientKeyLength |
401 | 適用於小於 32 個位元組的 HS256 演算法 |
steps.jws.InvalidClaim |
401 | 可能是因為缺少版權聲明或版權聲明不符,或是缺少標題或標頭不符的情形。 |
steps.jws.InvalidCurve |
401 | 索引鍵指定的曲線不適用於橢圓曲線演算法。 |
steps.jws.InvalidJsonFormat |
401 | JWS 標頭含有無效的 JSON。 |
steps.jws.InvalidJws |
401 | 當 JWS 簽名驗證失敗時,就會發生這個錯誤。 |
steps.jws.InvalidPayload |
401 | JWS 酬載無效。 |
steps.jws.InvalidSignature |
401 | 省略 <DetachedContent>,且 JWS 具有卸離的內容酬載。 |
steps.jws.KeyIdMissing |
401 | 驗證政策會使用 JWKS 做為公開金鑰來源,但已簽署的 JWS 不會在標頭中加入 kid 屬性。 |
steps.jws.KeyParsingFailed |
401 | 無法從指定的金鑰資訊剖析公開金鑰。 |
steps.jws.MissingPayload |
401 | 缺少 JWS 酬載。 |
steps.jws.NoAlgorithmFoundInHeader |
401 | JWS 省略演算法標頭時發生。 |
steps.jws.NoMatchingPublicKey |
401 | 驗證政策會使用 JWKS 做為公開金鑰來源,但已簽署 JWS 中的 kid 並未列在 JWKS 中。 |
steps.jws.UnhandledCriticalHeader |
401 | 透過驗證 JWS 政策在 crit 標頭中找到的標頭未列於 KnownHeaders 中。 |
steps.jws.UnknownException |
401 | 發生不明例外狀況。 |
steps.jws.WrongKeyType |
401 | 指定的金鑰類型有誤。舉例來說,如果您為橢圓曲線演算法指定 RSA 金鑰,或是為 RSA 演算法指定曲線鍵, |
部署錯誤
若您部署包含這項政策的 Proxy,就可能會發生這些錯誤。
| 錯誤名稱 | 發生時機 |
|---|---|
InvalidAlgorithm |
有效值僅為:RS256、RS384、RS512、PS256、PS384、PS512、ES256、ES384、ES512、HS256、HS384、HS512。 |
|
|
其他可能的部署錯誤。 |
錯誤變數
系統會在發生執行階段錯誤時設定這些變數。詳情請參閱重要須知 政策錯誤。
| 變數 | 地點 | 範例 |
|---|---|---|
fault.name="fault_name" |
fault_name 是錯誤的名稱,如上方「執行階段錯誤」表格所列。錯誤名稱是錯誤程式碼的最後部分。 | fault.name Matches "TokenExpired" |
JWS.failed |
如果作業失敗,所有 JWS 政策都會設定相同的變數。 | jws.JWS-Policy.failed = true |
錯誤回應範例
針對錯誤處理,最佳做法是將錯誤的 errorcode 部分加以包裝
回應。請勿參考 faultstring 中的文字,因為可能會變動。
錯誤規則範例
<FaultRules>
<FaultRule name="JWS Policy Errors">
<Step>
<Name>JavaScript-1</Name>
<Condition>(fault.name Matches "TokenExpired")</Condition>
</Step>
<Condition>JWS.failed=true</Condition>
</FaultRule>
</FaultRules>