驗證 WWS 政策

本頁適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

政策圖示

結果

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

如果 JWS 已驗證且有效,系統就會允許要求繼續進行。如果無法驗證 JWS 簽名,或是 JWS 因某種錯誤而無效,則所有處理作業都會停止,並在回應中傳回錯誤。

這項政策是可擴充的政策,視您的 Apigee 授權而定,使用這項政策可能會產生費用或使用量影響。如要瞭解政策類型和使用相關性,請參閱「政策類型」。

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

影片

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

範例

驗證使用 HS256 演算法簽署的附加 JWS

這個範例政策會驗證附加的 JWS,該 JWS 是使用 HS256 加密演算法 HMAC 和 SHA-256 總和檢查碼簽署。透過名為 JWS 的表單參數,在 Proxy 要求中傳遞 JWS。鍵包含在名為 private.secretkey 的變數中。

附加的 JWS 包含已編碼的標頭、酬載和簽章:

header.payload.signature

政策設定包含 Apigee 解碼及評估 JWS 所需的資訊,例如 JWS 所在位置 (在 <Source> 元素中指定的流程變數)、所需的簽署演算法,以及機密金鑰所在位置 (儲存在 Apigee 流程變數中,例如可從 Apigee 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 的表單參數,在 Proxy 要求中傳遞 JWS。公開金鑰包含在名為 public.publickey 的變數中。

已分離的 JWS 會省略 JWS 中的酬載:

header..signature

您可以將酬載傳遞至 VerifyJWS 政策,方法是將包含酬載的變數名稱指定給 <DetachedContent> 元素。<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>
*如要進一步瞭解金鑰要求,請參閱「關於簽章加密演算法」一文。

元素參照

政策參考資料說明瞭 Verify JWS 政策的元素和屬性。

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

S

套用至頂層元素的屬性

<VerifyJWS name="JWS" continueOnError="false" enabled="true" async="false">

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

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

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

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

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

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

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

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

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

除了使用名稱屬性,您也可以在 Apigee UI 代理程式編輯器中使用其他自然語言名稱標示政策。

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

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

<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 要求項式名稱。額外聲明的值可以是字串、數字、布林值、地圖或陣列。圖是一組名稱/值組合。您可以在政策設定中明確指定任何類型的權杖值,也可以間接指定流程變數。

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

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

如果未指定類型,則預設為 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 不含分離的內容酬載 (錯誤代碼為 steps.jws.ContentIsNotDetached),就會指定 <DetachedContent>
  • <DetachedContent> 已省略,且 JWS 具有分離的內容酬載 (錯誤代碼為 steps.jws.InvalidSignature)。
預設 N/A
在家狀態 選用
類型 變數參照

<IgnoreCriticalHeaders>

<IgnoreCriticalHeaders>true|false</IgnoreCriticalHeaders>

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

將這個元素設為 true 的原因之一,是如果您處於測試環境,且不希望政策因缺少標頭而失敗,

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

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

如果您希望政策在無法解析政策中指定的任何參照變數時擲回錯誤,請將此屬性設為 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 政策失敗。

您可以選擇將 VerifyJWS 政策設為忽略 crit 標頭,方法是將 <IgnoreCriticalHeaders> 元素設為 true

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

<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 金鑰集合 (JWKS) 驗證 JWS」一文。

如果您從公開網址擷取值,Apigee 會將 JWKS 快取 300 秒。快取過期後,Apigee 會再次擷取 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>

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

指定驗證使用對稱 (HS*) 演算法 (HS256、HS384 或 HS512 其中之一) 的 JWS 時要使用的秘密金鑰。

此元素為選用元素。不過,您必須包含 <PublicKey><SecretKey> 元素。驗證演算法為 RS*、PS* 或 ES* 的 JWS 時,請使用 <PublicKey> 元素;驗證演算法為 HS* 的 JWS 時,請使用 <SecretKey> 元素。

<SecretKey> 的子項

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

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

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

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

在上述範例中,由於編碼為 base64,如果變數 private.secretkey 的內容為 SUxvdmVBUElz,則索引鍵會解碼為一組 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>JWS-variable</Source>

如果存在,則會指定流程變數,政策會在該變數中尋找要驗證的 JWS。

預設 request.header.authorization (如需預設值的相關重要資訊,請參閱上述附註)。
在家狀態 選用
類型 字串
有效值 Apigee 流程變數名稱。

<Type>

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

選用元素,其唯一允許的值為 Signed,可指定政策驗證已簽署的 JWS。<Type> 只是為了與 GenerateJWT 和 VerifyJWT 政策的對應元素相符 (可採用 SignedEncrypted 的任一值)。

預設 不適用
在家狀態 選用
類型 字串
有效值 Signed

流程變數

成功後,「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 時新增)。如要驗證 JWS,請參閱「JWT 和 JWS 政策總覽」一文中的「使用 JSON Web 金鑰集合 (JWKS)」一節。詳情請參閱「(Key ID) 標頭參數」。
header.type 標頭類型值。詳情請參閱「(Type) 標頭參數」。
header.name 命名標頭的值 (標準或額外)。在 JWS 的標頭部分,每個額外標頭都會設定其中一個。
header-json 以 JSON 格式提供的標頭。
payload 如果 JWS 有附加的酬載,則為 JWS 酬載。如果是分離的酬載,這個變數會是空白。
valid 在 VerifyJWS 的情況下,如果簽名已驗證,且目前時間在符記到期時間之前,且在符記 notBefore 值之後 (如果有這些值的話),這個變數就會設為 true。否則為 false。

在 DecodeJWS 的情況下,這個變數並未設定。

錯誤參考資料

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

執行階段錯誤

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

錯誤代碼 HTTP 狀態 發生時機
steps.jws.AlgorithmInTokenNotPresentInConfiguration 401 驗證政策包含多個演算法時發生
steps.jws.AlgorithmMismatch 401 Generate 政策在標頭中指定的演算法與 Verify 政策中預期的演算法不符。指定的演算法必須相符。
steps.jws.ContentIsNotDetached 401 如果 JWS 不包含已分離的內容酬載,就會指定 <DetachedContent>
steps.jws.FailedToDecode 401 政策無法解碼 JWS。JWS 可能已損毀。
steps.jws.InsufficientKeyLength 401 針對 HS256 演算法,金鑰長度必須小於 32 位元組
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 Verify 政策會使用 JWKS 做為公開金鑰來源,但已簽署的 JWS 不會在標頭中加入 kid 屬性。
steps.jws.KeyParsingFailed 401 無法從指定的金鑰資訊剖析公開金鑰。
steps.jws.MissingPayload 401 缺少 JWS 酬載。
steps.jws.NoAlgorithmFoundInHeader 401 發生於 JWS 省略演算法標頭時。
steps.jws.NoMatchingPublicKey 401 Verify 政策使用 JWKS 做為公開金鑰來源,但已簽署的 JWS 中的 kid 並未列在 JWKS 中。
steps.jws.UnhandledCriticalHeader 401 crit 標頭中由「驗證 JWS」政策所找到的標頭,並未列在 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

其他可能的部署錯誤。

錯誤變數

系統會在發生執行階段錯誤時設定這些變數。詳情請參閱重要須知 政策錯誤。

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