驗證 WWS 政策

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

優勢

驗證用戶端或其他系統收到的 JWS 簽名。這項政策也會將標頭擷取到內容變數中,以便後續的政策或條件檢查這些值,以便制定授權或轉送決策。詳情請參閱 JWS 和 JWT 政策總覽

如果 JWS 通過驗證並有效,要求就能繼續進行。如果 JWS 簽名無法驗證,或是 JWS 因某種錯誤類型無效而無效,所有處理程序都會停止,回應中也會傳回錯誤。

如要瞭解 JWS 的幾個部分,以及其加密與簽署的方式,請參閱 RFC7515

影片

請觀看短片,瞭解如何在 JWS 上驗證簽名。雖然這部影片專門用於驗證 JWT,但其中許多概念與 JWS 相同。

範例

確認已附加的 JWS 使用 HS256 演算法簽署

這個範例政策會驗證已使用 HS256 加密演算法簽署的 JWS,亦即使用 SHA-256 總和檢查碼簽署的 JWS。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 會強制執行其他限制,例如自動移除非英數字元。

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

不適用 必要
continueOnError 如果設為 false,即可在政策失敗時傳回錯誤。大部分政策都是預期中的行為。

設為 true,即可在政策失敗後繼續執行資料流。

false 選用
已啟用 如要強制執行政策,請設為 true

設為 false 即可「停用」政策。即使政策仍附加在流程中,系統也不會強制執行政策。

true 選用
async 此屬性已淘汰。 false 已淘汰

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

除了名稱屬性,您還可以使用其他自然語言名稱,在管理 UI Proxy 編輯器中為政策加上標籤。

預設 如果省略這個元素,則會使用政策名稱屬性的值。
外觀狀態 選用
類型 字串

<Algorithm>

<Algorithm>HS256</Algorithm>

指定要簽署權杖的加密演算法。RS*/PS*/ES* 演算法採用公開/密鑰金鑰組,HS* 演算法則採用共用密鑰。另請參閱「 關於簽名加密演算法」一文。

您可以指定多個值,並以半形逗號分隔。例如「HS256, HS512」或「RS256、PS256」。 不過,您無法將 HS* 演算法與任何其他演算法結合,或是與其他 ES* 演算法結合,因為需要使用特定金鑰類型。您可以結合 RS* 和 PS* 演算法。

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

<其他標頭/聲明>

<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 聲明名稱。其他聲明的值可以是字串、數字、布林值、地圖或陣列。地圖只是一組名稱/值組合。這類聲明的值可在政策設定中明確指定,也可以透過流程變數參照間接指定。

預設 不適用
外觀狀態 選用
類型

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

如果未指定類型,則類型會預設為「字串」。

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

<Claim> 元素採用以下屬性:

  • name - (必填) 版權聲明的名稱。
  • ref - (選用) 流程變數的名稱。如果存在,政策會使用這個變數的值做為聲明。如果同時指定 ref 屬性和明確的憑證附加資訊值,系統預設會使用明確的值,並在參照流程變數未解析時使用。
  • type - (選用) 其中之一:字串 (預設值)、數字、布林值或地圖
  • 陣列 - (選用) 設為 true,表示該值是類型陣列。預設值:false。

<DetachedContent>

<DetachedContent>variable-name-here</DetachedContent>

包含內容酬載的產生的 JWS 格式為:

header.payload.signature

如果您使用 GenerateJWS 政策來建立卸離的酬載,產生的 JWS 會省略酬載,並採用以下格式:

header..signature

如果是卸離的酬載,您必須使用 <DetachedContent> 元素將酬載傳送至 VerifyJWS 政策。指定的內容酬載必須採用建立 JWS 簽名時的原始未編碼格式。

這項政策會在下列情況擲回錯誤:

  • 當 JWS 不包含已卸離的內容酬載 (錯誤代碼為 steps.jws.ContentIsNotDetached) 時,就會指定 <DetachedContent>
  • 省略 <DetachedContent>,且 JWS 具有已卸離的內容酬載 (錯誤代碼為 steps.jws.InvalidSignature)。
預設 N/A
外觀狀態 選用
類型 變數參照

<IgnoreCriticalHeaders>

<IgnoreCriticalHeaders>true|false</IgnoreCriticalHeaders>

如果 <KnownHeaders> 元素中未列出 JWS 的 crit 標頭中列出的任何標頭,請設為 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> 元素可包含條件所列項目的超集。只有在 條件 中列出的所有標頭都必須列在 <KnownHeaders> 元素中即可。凡是在 條件 中找到且未列於 <KnownHeaders> 的標頭,都會導致 VerifyJWS 政策失敗。

您可以視需要將 <IgnoreCriticalHeaders> 元素設為 true,藉此設定 VerifyJWS 政策以忽略 crit 標頭。

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

<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。

預設 不適用
外觀狀態 如要使用 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 的演算法。

預設 不適用
外觀狀態 如要驗證以 RSA 演算法簽署的 JWS,您必須使用 JWKS 或 Value 元素。
類型 字串
有效值 流程變數或字串。

<SecretKey/Value>

<SecretKey>
  <Value ref="private.your-variable-name"/>
</SecretKey>

提供透過 HMAC 演算法驗證或簽署權杖的密鑰。只有在演算法為 HS256、HS384 或 HS512 時才使用。使用 ref 屬性在流程變數中傳遞鍵。

預設 不適用
外觀狀態 HMAC 演算法的必填屬性。
類型 字串
有效值 參照字串的流程變數。

注意:如果是流程變數,則必須包含「private」前置字串。例如:private.mysecret

<來源>

<Source>JWS-variable</Source>

如果有,則指定政策預期會尋找 JWS 驗證的流程變數。

預設 request.header.authorization (如需有關預設值的重要資訊,請參閱上述注意事項)。
外觀狀態 選用
類型 字串
有效值 邊緣流程變數名稱。

流程變數

成功執行後,「Verify JWS」和「Decode 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 時加入)。另請參閱 JWT 和 JWS 政策總覽的「使用 JSON 網路金鑰組 (JWKS)」一節,瞭解如何驗證 JWS。 詳情請參閱「(金鑰 ID) 標頭參數」。
header.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。

EmptyElementForKeyConfiguration

FailedToResolveVariable

InvalidConfigurationForActionAndAlgorithmFamily

InvalidConfigurationForVerify

InvalidEmptyElement

InvalidFamiliesForAlgorithm

InvalidKeyConfiguration

InvalidNameForAdditionalClaim

InvalidNameForAdditionalHeader

InvalidPublicKeyId

InvalidPublicKeyValue

InvalidSecretInConfig

InvalidTypeForAdditionalClaim

InvalidTypeForAdditionalHeader

InvalidValueForElement

InvalidValueOfArrayAttribute

InvalidVariableNameForSecret

MissingConfigurationElement

MissingElementForKeyConfiguration

MissingNameForAdditionalClaim

MissingNameForAdditionalHeader

其他可能的部署錯誤。

錯誤變數

這些變數是在執行階段錯誤發生時設定。詳情請參閱「政策錯誤的注意事項」。

Variables 地點 範例
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>