驗證 JWT

適用於:所有 API 管理 層

validate-jwt 原則會強制必須存在擷取自指定 HTTP 標頭、擷取自指定查詢的參數,或對應的指定值,指定查詢參數的受支援 JSON Web 權杖 (JWT),且為有效。

注意

若要驗證 Microsoft Entra 服務提供的 JWT,API 管理也會提供 validate-azure-ad-token 原則。

注意

請依照原則陳述式中提供的順序,來設定原則的元素和子元素。 為了協助您設定此原則,入口網站會提供引導式表單型編輯器。 深入了解如何設定或編輯 APIM 原則

原則陳述式

<validate-jwt
    header-name="name of HTTP header containing the token (alternatively, use query-parameter-name or token-value attribute to specify token)"
    query-parameter-name="name of query parameter used to pass the token (alternative, use header-name or token-value attribute to specify token)"
    token-value="expression returning the token as a string (alternatively, use header-name or query-parameter attribute to specify token)"
    failed-validation-httpcode="HTTP status code to return on failure"
    failed-validation-error-message="error message to return on failure"
    require-expiration-time="true | false"
    require-scheme="scheme"
    require-signed-tokens="true | false"
    clock-skew="allowed clock skew in seconds"
    output-token-variable-name="name of a variable to receive a JWT object representing successfully validated token">
  <openid-config url="full URL of the configuration endpoint, for example, https://login.constoso.com/openid-configuration" />
  <issuer-signing-keys>
    <key>Base64 encoded signing key | certificate-id="mycertificate" | n="modulus" e="exponent"</key>
    <!-- if there are multiple keys, then add additional key elements -->
  </issuer-signing-keys>
  <decryption-keys>
    <key>Base64 encoded signing key | certificate-id="mycertificate" | n="modulus" e="exponent" </key>
    <!-- if there are multiple keys, then add additional key elements -->
  </decryption-keys>
  <audiences>
    <audience>audience string</audience>
    <!-- if there are multiple possible audiences, then add additional audience elements -->
  </audiences>
  <issuers>
    <issuer>issuer string</issuer>
    <!-- if there are multiple possible issuers, then add additional issuer elements -->
  </issuers>
  <required-claims>
    <claim name="name of the claim as it appears in the token" match="all | any" separator="separator character in a multi-valued claim">
      <value>claim value as it is expected to appear in the token</value>
      <!-- if there is more than one allowed value, then add additional value elements -->
    </claim>
    <!-- if there are multiple possible allowed claim, then add additional claim elements -->
  </required-claims>
</validate-jwt>

屬性

屬性 描述 是必要欄位 預設
header-name 保留權杖的 HTTP 標頭名稱。 允許使用原則運算式。 您必須指定 header-namequery-parameter-nametoken-value 的其中之一。 N/A
query-parameter-name 保留權杖的查詢參數名稱。 允許使用原則運算式。 您必須指定 header-namequery-parameter-nametoken-value 的其中之一。 N/A
token-value 運算式,傳回包含標記的字串。 您不得傳回 Bearer 做為權杖值的一部分。 允許使用原則運算式。 您必須指定 header-namequery-parameter-nametoken-value 的其中之一。 N/A
failed-validation-httpcode JWT 未通過驗證時所要傳回的 HTTP 狀態碼。 允許使用原則運算式。 No 401
failed-validation-error-message 如果 JWT 未通過驗證,在 HTTP 回應主體中傳回的錯誤訊息。 此訊息必須正確逸出任何特殊字元。 允許使用原則運算式。 No 預設錯誤訊息視驗證問題而定,例如「JWT 不存在」。
require-expiration-time 布林值。 指定權杖中是否需有逾期宣告。 允許使用原則運算式。 No true
require-scheme 權杖結構描述的名稱,例如「Bearer」。 當已設定此屬性時,原則將會確定指定的結構描述存在於授權標頭值中。 允許使用原則運算式。 No N/A
require-signed-tokens 布林值。 指定是否需要簽署權杖。 允許使用原則運算式。 No true
clock-skew 時間範圍。 用來指定權杖簽發者和 API 管理執行個體的系統時鐘之間最大預期時間差異。 允許使用原則運算式。 No 0 秒
output-token-variable-name 字串。 成功驗證權杖時,將接收權杖值做為型別 Jwt 物件的內容變數名稱。 不允許使用原則運算式。 No N/A

元素

元素 描述 必要
openid-config 新增其中一或多個元素,以指定可從中取得簽署金鑰和簽發者的相容 OpenID 設定端點 URL。

包含 JSON Web 金鑰集 (JWKS) 的設定會每隔 1 小時從端點提取並進行快取。 如果所驗證的權杖參考快取設定中遺漏的驗證金鑰 (使用 kid 宣告),或者如果擷取失敗,API 管理最多每 5 分鐘從端點提取一次。 這些間隔如有變更,恕不另行通知。

回應應該根據 URL 所定義的規格:https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata

針對 Microsoft Entra ID,請使用在應用程式註冊中設定的 OpenID Connect 中繼資料端點,例如:
- v2 https://login.microsoftonline.com/{tenant-name}/v2.0/.well-known/openid-configuration
- v2 多租用戶 https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration
- v1 https://login.microsoftonline.com/{tenant-name}/.well-known/openid-configuration
- 客戶租用戶 (預覽版) https://{tenant-name}.ciamlogin.com/{tenant-id}/v2.0/.well-known/openid-configuration

替代您的目錄租用戶名稱或識別碼,例如 {tenant-name}contoso.onmicrosoft.com
No
issuer-signing-keys 用來驗證已簽署權杖的 Base64 編碼安全性金鑰清單 (於 key 子陳述式中)。 如果存在多個安全性金鑰,則會嘗試每個金鑰,直到全部試完 (即表示驗證失敗) 或其中一個金鑰成功 (很適合用於權杖變換) 為止。

選擇性地使用 id 屬性來指定金鑰,以符合 kid 宣告。 若要驗證以非對稱密鑰簽署的令牌,請選擇性地使用certificate-id屬性值為上傳至 API 管理 之憑證的標識碼,或 Base64url 編碼格式簽署金鑰的 RSA 模數n和指數e組來指定公鑰。
No
decryption-keys 用於解密權杖的 Base64 編碼金鑰清單 (於 key 子元素中)。 如果有多個安全性金鑰存在,則系統會嘗試每個金鑰,直到試完所有金鑰 (即表示驗證失敗) 或某個金鑰成功為止。

選擇性地使用 id 屬性來指定金鑰,以符合 kid 宣告。 若要解密使用非對稱密鑰加密的令牌,選擇性地使用certificate-id屬性值為上傳至 API 管理 之憑證的標識符,或 Base64url 編碼格式之密鑰的 RSA 模數n和指數e組來指定公鑰。
No
audiences 可在權杖上呈現的可接受受眾宣告清單 (於 audience 子元素中)。 如果存在多個受眾值,則會嘗試每個值,直到全部試完 (即表示驗證失敗) 或其中一個值成功為止。 必須指定至少一個受眾。 No
issuers 簽發權杖的可接受主體清單 (於 issuer 子元素中)。 如果存在多個簽發者值,則會嘗試每個值,直到全部試完 (即表示驗證失敗) 或其中一個值成功為止。 No
required-claims 預計將在權杖上呈現以使其被視為有效的宣告清單 (於 claim 子元素中)。 當有多個宣告存在時,權杖必須根據 match 屬性的值來比對宣告值。 No

金鑰屬性

屬性 描述 是必要欄位 預設
id 字串。 用來比對 JWT 中所呈現之 kid 宣告的識別碼。 No N/A
certificate-id 上傳至 API 管理 的憑證實體標識符,用來指定公鑰來驗證使用非對稱金鑰簽署的令牌。 No N/A
n 用來驗證使用非對稱金鑰簽署之令牌簽發者的公鑰模數。 必須使用指數 e 的值來指定。 不允許使用原則運算式。 No N/A
e 用來驗證使用非對稱金鑰簽署之令牌簽發者的公鑰指數。 必須使用模數 n 的值來指定。 不允許使用原則運算式。 No N/A

宣告屬性

屬性 描述 是必要欄位 預設
match claim 元素的 match 屬性可指定原則中的每個宣告值是否都必須存在於權杖,才能驗證成功。 可能的值包括:

- all - 原則中的每個宣告值都必須存在於權杖,才能驗證成功。

- any - 至少一個宣告必須存在於權杖,才能驗證成功。
No 全部
separator 字串。 指定用於從多重值宣告中擷取一組值的分隔符號 (例如 ",")。 No N/A

使用方式

使用注意事項

  • validate-jwt 原則會要求 exp 註冊的宣告包含在 JWT 權杖中 (除非已指定 require-expiration-time 屬性並設定為 false)。
  • 此原則同時支援對稱和非對稱簽署演算法:
    • 對稱 - 支援下列加密演算法:A128CBC-HS256、A192CBC-HS384、A256CBC-HS512。
      • 如果在原則中使用,則必須以Base64編碼形式內嵌在原則內提供密鑰。
    • 非對稱 - 支援下列加密 algortithms:PS256、RS256、RS512。
      • 如果在原則中使用,則密鑰可透過 OpenID 組態端點提供,或藉由提供包含公鑰之上傳憑證的識別碼,或公鑰的模數指數組。
  • 若要搭配自主裝載閘道使用一或多個 OpenID 設定端點來設定原則,則雲端閘道也必須可連線 OpenID 設定端點 URL。
  • 您可以針對不同的用途,在不同的範圍中使用存取限制原則。 例如,您可以藉由在 API 層級套用 validate-jwt 原則,以 Microsoft Entra 驗證保護整個 API,您也可以在 API 作業層級套用該原則並對於更細微的控制使用 claims
  • 使用自定義標頭時 (header-name),將會忽略已設定的必要配置 (require-scheme)。 若要使用必要的配置,必須在 Authorization 標頭中提供 JWT 權杖。

範例

簡單權杖驗證

<validate-jwt header-name="Authorization" require-scheme="Bearer">
    <issuer-signing-keys>
        <key>{{jwt-signing-key}}</key>  <!-- signing key specified as a named value -->
    </issuer-signing-keys>
    <audiences>
        <audience>@(context.Request.OriginalUrl.Host)</audience>  <!-- audience is set to API Management host name -->
    </audiences>
    <issuers>
        <issuer>http://contoso.com/</issuer>
    </issuers>
</validate-jwt>

使用 RSA 憑證進行權杖驗證

<validate-jwt header-name="Authorization" require-scheme="Bearer">
    <issuer-signing-keys>
        <key certificate-id="my-rsa-cert" />  <!-- signing key specified as certificate ID, enclosed in double-quotes -->
    </issuer-signing-keys>
    <audiences>
        <audience>@(context.Request.OriginalUrl.Host)</audience>  <!-- audience is set to API Management host name -->
    </audiences>
    <issuers>
        <issuer>http://contoso.com/</issuer>
    </issuers>
</validate-jwt>

Microsoft Entra ID 單一租用戶權杖驗證

<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
    <openid-config url="https://login.microsoftonline.com/contoso.onmicrosoft.com/.well-known/openid-configuration" />
    <audiences>
        <audience>25eef6e4-c905-4a07-8eb4-0d08d5df8b3f</audience>
    </audiences>
    <required-claims>
        <claim name="id" match="all">
            <value>insert claim here</value>
        </claim>
    </required-claims>
</validate-jwt>

Microsoft Entra ID 客戶租用戶權杖驗證

<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
	<openid-config url="https://<tenant-name>.ciamlogin.com/<tenant-id>/v2.0/.well-known/openid-configuration" />
	<required-claims>
		<claim name="azp" match="all">
			<value>insert claim here</value>
		</claim>
	</required-claims>
</validate-jwt>

Azure Active Directory B2C 權杖驗證

<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
    <openid-config url="https://login.microsoftonline.com/tfp/contoso.onmicrosoft.com/b2c_1_signin/v2.0/.well-known/openid-configuration" />
    <audiences>
        <audience>d313c4e4-de5f-4197-9470-e509a2f0b806</audience>
    </audiences>
    <required-claims>
        <claim name="id" match="all">
            <value>insert claim here</value>
        </claim>
    </required-claims>
</validate-jwt>

根據權杖宣告授與作業的存取權

此範例示範如何使用 validate-jwt 原則來根據權杖宣告值授與作業的存取權。

<validate-jwt header-name="Authorization" require-scheme="Bearer" output-token-variable-name="jwt">
    <issuer-signing-keys>
        <key>{{jwt-signing-key}}</key> <!-- signing key is stored in a named value -->
    </issuer-signing-keys>
    <audiences>
        <audience>@(context.Request.OriginalUrl.Host)</audience>
    </audiences>
    <issuers>
        <issuer>contoso.com</issuer>
    </issuers>
    <required-claims>
        <claim name="group" match="any">
            <value>finance</value>
            <value>logistics</value>
        </claim>
    </required-claims>
</validate-jwt>
<choose>
    <when condition="@(context.Request.Method == "POST" && !((Jwt)context.Variables["jwt"]).Claims["group"].Contains("finance"))">
        <return-response>
            <set-status code="403" reason="Forbidden" />
        </return-response>
    </when>
</choose>

如需使用原則的詳細資訊,請參閱: