產生 JWT 政策

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

優勢

產生已簽署的 JWT,其中包含可設定的憑證附加資訊。接著,我們可以將 JWT 傳回給用戶端、傳輸至後端目標,或是以其他方式使用。詳情請參閱 JWS 和 JWT 政策總覽

影片

請觀看短片,瞭解如何產生已簽署的 JWT。

範例

產生使用 HS256 演算法簽署的 JWT

這個範例政策會產生新的 JWT,並使用 HS256 演算法簽署該 JWT。HS256 需要利用共用密鑰來簽署及驗證簽名。

觸發這項政策動作時,Edge 會將 JWT 標頭和酬載編碼,接著以數位方式簽署 JWT。如需完整範例,包括如何提出政策要求,請觀看上方的影片。

這裡的政策設定將建立 JWT,其中包含 JWT 規格定義的一組標準憑證附加資訊,包括有效期限 1 小時,以及額外的憑證附加資訊。您可以視需要加入更多版權聲明,數量不限。如要進一步瞭解這個範例政策中每個元素的相關規定和選項,請參閱元素參考資料。

<GenerateJWT name="JWT-Generate-HS256">
    <DisplayName>JWT Generate HS256</DisplayName>
    <Algorithm>HS256</Algorithm>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <SecretKey>
        <Value ref="private.secretkey"/>
        <Id>1918290</Id>
    </SecretKey>
    <ExpiresIn>1h</ExpiresIn>
    <Subject>monty-pythons-flying-circus</Subject>
    <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
    <Audience>fans</Audience>
    <Id/>
    <AdditionalClaims>
        <Claim name="show">And now for something completely different.</Claim>
    </AdditionalClaims>
    <OutputVariable>jwt-variable</OutputVariable>
</GenerateJWT>

產生的 JWT 會有這個標頭...

{
  "typ" : "JWT", 
  "alg" : "HS256",
  "kid" : "1918290"
}

...且酬載會包含類似下方的內容:

{ 
  "sub" : "monty-pythons-flying-circus",
  "iss" : "urn://apigee-edge-JWT-policy-test",
  "aud" : "show",
  "iat" : 1506553019,
  "exp" : 1506556619,
  "jti" : "BD1FF263-3D25-4593-A685-5EC1326E1F37",
  "show": "And now for something completely different."
}

iatexpjti 憑證附加的值會有所不同。

產生使用 RS256 演算法簽署的 JWT

這個範例政策會產生一個新的 JWT,並使用 RS256 演算法簽署該 JWT。產生 RS256 簽名時,需要使用 RSA 私密金鑰,須以 PEM 編碼格式提供。如需完整範例,包括如何提出政策要求,請觀看上方的影片。

觸發這項政策動作時,Edge 會將 JWT 編碼並進行數位簽署,包括憑證附加資訊。如要瞭解 JWT 的組成部分,以及這些元件的加密與簽署方式,請參閱 RFC7519

<GenerateJWT name="JWT-Generate-RS256">
    <Algorithm>RS256</Algorithm>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <PrivateKey>
        <Value ref="private.privatekey"/>
        <Password ref="private.privatekey-password"/>
        <Id ref="private.privatekey-id"/>
    </PrivateKey>
    <Subject>apigee-seattle-hatrack-montage</Subject>
    <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
    <Audience>urn://c60511c0-12a2-473c-80fd-42528eb65a6a</Audience>
    <ExpiresIn>60m</ExpiresIn>
    <Id/>
    <AdditionalClaims>
        <Claim name="show">And now for something completely different.</Claim>
    </AdditionalClaims>
    <OutputVariable>jwt-variable</OutputVariable>
</GenerateJWT>

設定重要元素

您用於指定 JWT 產生金鑰的元素取決於您選擇的演算法,如下表所示:

演算法 主要元素
HS{256/384/512}*
<SecretKey>
  <Value ref="private.secretkey"/>
  <Id>1918290</Id>
</SecretKey>
RS/PS/ES{256/384/512}*
<PrivateKey>
  <Value ref="private.privatekey"/>
  <Password ref="private.privatekey-password"/>
  <Id ref="private.privatekey-id"/>
</PrivateKey>

<Password><Id> 為選用元素。

*如要進一步瞭解金鑰相關規定,請參閱「關於簽名加密演算法」一文。

產生 JWT 的元素參考資料

政策參考資料說明 Generate JWT 政策的元素和屬性。

注意:視您使用的加密演算法而定,設定可能略有不同。如需特定用途的設定範例,請參閱範例

套用至頂層元素的屬性

<GenerateJWT name="JWT" 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>algorithm-here</Algorithm>

指定要簽署權杖的加密演算法。

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

<Audience>

<Audience>audience-here</Audience>

or:

<Audience ref='variable_containing_audience'/>

政策會產生 JWT,其中含有設為指定值的 aud 憑證附加資訊。這項憑證可用來識別 JWT 適用對象的接收者。這是 RFC7519 中所述的其中一項註冊憑證附加資訊。

預設 不適用
外觀狀態 選用
類型 陣列 (逗號分隔值的清單)
有效值 可用來識別目標對象的任何內容。

<其他聲明/版權聲明>

<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 的酬載中指定額外的憑證要求名稱/值組合。您可以將憑證附加資訊明確指定為字串、數字、布林值、地圖或陣列。地圖只是一組名稱/值組合。

預設 不適用
外觀狀態 選用
有效值 你要用於額外聲明的任何值。您可以將憑證附加資訊明確指定為字串、數字、布林值、地圖或陣列。

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

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

加入 <Claim> 元素後,系統會在您設定政策時以靜態方式設定聲明名稱。或者,您可以傳送 JSON 物件來指定要求名稱。由於 JSON 物件是以變數的形式傳遞,因此產生的 JWT 中的要求名稱會在執行階段決定。

例如:

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

產生的 JWT 包含 JSON 物件中的所有憑證附加資訊。

<其他標頭/聲明>

<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 標頭中。

預設 不適用
外觀狀態 選用
有效值 你要用於額外聲明的任何值。您可以將憑證附加資訊明確指定為字串、數字、布林值、地圖或陣列。

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

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

<CriticalHeaders>

<CriticalHeaders>a,b,c</CriticalHeaders>

or:

<CriticalHeaders ref=’variable_containing_headers’/>

將重要標頭「條件」加入 JWT 標頭中。crit 標頭是一個標頭名稱陣列,必須可供 JWT 接收器識別及辨識。例如:

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

在執行階段,VerifyJWT 政策會檢查 crit 標頭。 針對 crit 標頭中列出的每個項目,系統會檢查 VerifyJWT 政策的 <KnownHeaders> 元素是否也會列出該標頭。凡是在 條件中未列於 <KnownHeaders> 中的標頭,皆會導致 VerifyJWT 政策失敗。

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

<CustomClaims>

注意:目前當您透過 UI 新增 GenerateJWT 政策時,系統會插入 CustomClaims 元素。這個元素無法運作,因此會遭到忽略。正確的元素是 <AdditionalClaims>。稍後系統會更新使用者介面,並插入正確的元素。

<ExpiresIn>

<ExpiresIn>time-value-here</ExpiresIn>

以毫秒、秒、分鐘、小時或天為單位指定 JWT 的生命週期。

預設 N/A
外觀狀態 選用
類型 整數
有效值

包含值之流程變數的值或參照。可以按照下列方式指定時間單位:

  • ms = 毫秒 (預設)
  • s = 秒
  • m = 分鐘
  • h = 小時
  • d = 天

例如,ExpiresIn=10d 相當於 86, 4000s 的 ExpiresIn

<編號>

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

產生包含特定 Jti 憑證附加資訊的 JWT。如果文字值和 ref 屬性皆空白,政策會產生包含隨機 UUID 的 jti。JWT ID (jti) 憑證附加資訊是 JWT 的專屬 ID。如要進一步瞭解 jti,請參閱 RFC7519

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

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

如要讓政策在政策中指定的任何參照變數無法解析時擲回錯誤,請設為 false。設為 true 會將任何無法解析的變數視為空字串 (空值)。

預設 false
外觀狀態 選用
類型 布林值
有效值 true 或 false

<Issuer>

<Issuer ref='variable-name-here'/>
<Issuer>issuer-string-here</Issuer>

政策會產生 JWT,其中含有名稱為 iss, 的要求,並將值設為指定值。可識別 JWT 核發者的憑證附加資訊。這是 RFC7519 中所述的一組註冊憑證附加資訊。

預設 不適用
外觀狀態 選用
類型 字串或參照
有效值 任何檔案

<NotBefore>

<!-- Specify an absolute time. -->
<NotBefore>2017-08-14T11:00:21-07:00</NotBefore>
 -or-
<!-- Specify a time relative to when the token is generated. -->
<NotBefore>6h</NotBefore>

指定權杖生效的時間。系統會在指定時間前失效。您可以指定絕對時間值,或是與權杖產生時間相關的時間。

預設 不適用
外觀狀態 選用
類型 字串
有效值 如下所示。

絕對時間值的 NotBefore 元素有效時間值

名稱 格式 範例
可排序 yyyy-MM-dd'T'HH:mm:ss.SSSZ 2017-08-14T11:00:21.269-0700
RFC 1123 EEE, dd MMM yyyy HH:mm:ss zzz 2017 年 8 月 14 日星期一 11:00:21 (太平洋夏令時間)
RFC 850 EEEE, dd-MMM-yy HH:mm:ss zzz 週一 14 至 8 月 17 日,太平洋夏令時間 11:00:21
ANCI-C EEE MMM d HH:mm:ss yyyy 2017 年 8 月 14 日 11:00:21

如需相對時間值,請指定整數和時間範圍,例如:

  • 10 秒
  • 60 分鐘
  • 12 小時

<OutputVariable>

<OutputVariable>jwt-variable</OutputVariable>

指定要將這項政策產生的 JWT 放在何處。根據預設,系統會將此資料置於資料流變數 jwt.POLICYNAME.generated_jwt 中。

預設 jwt.POLICYNAME.generated_jwt
外觀狀態 選用
類型 字串 (流程變數名稱)

<PrivateKey/Id>

<PrivateKey>
  <Id ref="flow-variable-name-here"/>
</PrivateKey>

or

<PrivateKey>
  <Id>your-id-value-here</Id>
</PrivateKey>

指定要納入 JWT 標頭的金鑰 ID (kid)。僅適用於 RS256/RS384/RS512、PS256/PS384/PS512 或 ES256/ES384/ES512 的演算法。

預設 不適用
外觀狀態 選用
類型 字串
有效值 流程變數或字串

<PrivateKey/Password>

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

視需要指定政策應用來解密私密金鑰的密碼。使用 ref 屬性在流程變數中傳遞鍵。僅適用於 RS256/RS384/RS512、PS256/PS384/PS512 或 ES256/ES384/ES512 的演算法。

預設 不適用
外觀狀態 選用
類型 字串
有效值 流程變數參考資料。

注意:您必須指定流程變數。因為政策設定無效,Edge 將拒絕為無效的政策設定,而該政策設定是以明文形式指定。流程變數的前置字串須為「private」。例如,private.mypassword

<PrivateKey/Value>

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

指定用來簽署 JWT 的 PEM 編碼私密金鑰。使用 ref 屬性在流程變數中傳遞鍵。僅適用於演算法為 RS256/RS384/RS512、PS256/PS384/PS512 或 ES256/ES384/ES512 的演算法。

預設 不適用
外觀狀態 必須使用 RS256 演算法產生 JWT。
類型 字串
有效值 流程變數,其中包含代表 PEM 編碼 RSA 私密金鑰值的字串。

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

<密鑰/ID>

<SecretKey>
  <Id ref="flow-variable-name-here"/>
</SecretKey>

or

<SecretKey>
  <Id>your-id-value-here</Id>
</SecretKey>

指定要納入使用 HMAC 演算法簽署的 JWT 標頭中的金鑰 ID (kid)。只有在演算法為 HS256/HS384/HS512 時才使用。

預設 不適用
外觀狀態 選用
類型 字串
有效值 流程變數或字串

<SecretKey/Value>

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

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

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

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

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

<Subject>

<Subject>subject-string-here</Subject>
<Subject ref="flow_variable" />

例如:

<Subject ref="apigee.developer.email"/>

政策會產生一個 JWT 含有設為指定值的「sub」憑證附加資訊。這項聲明會識別或做出 JWT 主體的陳述。這是 RFC7519 中提及的標準憑證附加資訊組合之一。

預設 不適用
外觀狀態 選用
類型 字串
有效值 任何不重複的值,可用來識別主旨或參照某個值的資料流變數。

流程變數

產生 JWT 政策未設定流程變數。

錯誤參考資料

本節說明當這項政策觸發錯誤時,傳回的錯誤代碼和錯誤訊息,以及 Edge 設定的錯誤變數。 如果您正在開發錯誤規則來處理錯誤,請務必瞭解這項資訊。詳情請參閱「政策錯誤須知」和「處理錯誤」。

執行階段錯誤

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

錯誤代碼 HTTP 狀態 發生時機
steps.jwt.AlgorithmInTokenNotPresentInConfiguration 401 驗證政策採用多個演算法時發生。
steps.jwt.AlgorithmMismatch 401 產生政策中指定的演算法與驗證政策中預期的演算法不符。指定的演算法必須相符。
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.InvalidCurve 401 索引鍵指定的曲線不適用於橢圓曲線演算法。
steps.jwt.InvalidJsonFormat 401 標頭或酬載含有無效的 JSON。
steps.jwt.InvalidToken 401 如果 JWT 簽名驗證失敗,就會發生這個錯誤。
steps.jwt.JwtAudienceMismatch 401 權杖驗證失敗,目標對象聲明失敗。
steps.jwt.JwtIssuerMismatch 401 核發機構憑證驗證失敗。
steps.jwt.JwtSubjectMismatch 401 驗證權杖的主體擁有權聲明失敗。
steps.jwt.KeyIdMissing 401 驗證政策會使用 JWKS 做為公開金鑰來源,但已簽署的 JWT 不會在標頭中加入 kid 屬性。
steps.jwt.KeyParsingFailed 401 無法從指定的金鑰資訊剖析公開金鑰。
steps.jwt.NoAlgorithmFoundInHeader 401 發生於 JWT 未包含演算法標頭時。
steps.jwt.NoMatchingPublicKey 401 驗證政策會使用 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,就會發生這個錯誤。
InvalidConfigurationForActionAndAlgorithm 如果將 <PrivateKey> 元素與 HS 系列演算法搭配使用,或是將 <SecretKey> 元素與 RSA Family 演算法搭配使用,部署作業就會失敗。
InvalidValueForElement 如果 <Algorithm> 元素中指定的值不是支援的值,部署作業就會失敗。
MissingConfigurationElement 如果 <PrivateKey> 元素未與 RSA 系列演算法搭配使用,或是 <SecretKey> 元素並未與 HS 系列演算法搭配使用,就會發生這個錯誤。
InvalidKeyConfiguration 如果未在 <PrivateKey><SecretKey> 元素中定義子項元素 <Value>,部署就會失敗。
EmptyElementForKeyConfiguration 如果 <PrivateKey><SecretKey> 元素子項元素 <Value> 的 ref 屬性為空白或未指定,則部署作業將會失敗。
InvalidVariableNameForSecret 如果在 <PrivateKey><SecretKey> 元素的子項元素 <Value> 的 ref 屬性中指定的流程變數名稱不含私人前置字串 (private.),就會發生這個錯誤。
InvalidSecretInConfig 如果 <PrivateKey><SecretKey> 元素的子元素 <Value> 不含私人前置字串 (private.),就會發生這個錯誤。
InvalidTimeFormat 如果 <NotBefore> 元素中指定的值未使用支援的格式,部署就會失敗。

錯誤變數

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

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

錯誤回應範例

JWT 政策錯誤程式碼

如要處理錯誤,最佳做法是納入錯誤回應的 errorcode 部分。請勿依賴 faultstring 中的文字,因為文字可能會有所變動。

故障規則示例

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