验证 JWT
适用于:所有 API 管理层级
validate-jwt
策略强制要求从指定 HTTP 标头提取、从指定查询参数提取的受支持 JSON Web 令牌 (JWT) 或匹配特定值必须存在且有效。
注意
API 管理还提供了 validate-azure-ad-token
策略用于验证 Microsoft Entra 服务提供的 JWT。
提示
为了帮助你配置此策略,门户提供了基于窗体的引导式编辑器。 详细了解如何设置或编辑 API 管理策略。
策略语句
<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 id="kid-claim" certificate-id="mycertificate" n="modulus" e="exponent">Base64 encoded signing key</key>
<!-- if there are multiple keys, then add additional key elements -->
</issuer-signing-keys>
<decryption-keys>
<key certificate-id="mycertificate">Base64 encoded signing key</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-name 、query-parameter-name 、token-value 中的一个。 |
不适用 |
query-parameter-name | 包含令牌的查询参数的名称。 允许使用策略表达式。 | 必须指定 header-name 、query-parameter-name 、token-value 中的一个。 |
空值 |
token-value | 一个表达式,返回的字符串包含该令牌。 令牌值中不得返回 Bearer 。 允许使用策略表达式。 |
必须指定 header-name 、query-parameter-name 、token-value 中的一个。 |
空值 |
failed-validation-httpcode | JWT 未通过验证时会返回的 HTTP 状态代码。 允许使用策略表达式。 | 否 | 401 |
failed-validation-error-message | JWT 未通过验证时会在 HTTP 响应正文中返回的错误消息。 此消息必须对任何特殊字符正确地进行转义。 允许使用策略表达式。 | 否 | 默认错误消息取决于验证问题,例如“JWT 不存在”。 |
require-expiration-time | 布尔值。 指定令牌中是否需要到期声明。 允许使用策略表达式。 | 否 | 是 |
require-scheme | 令牌方案的名称,例如“Bearer”。 设置了此属性时,策略将确保 Authorization 标头值中存在指定的方案。 允许使用策略表达式。 | 否 | 空值 |
require-signed-tokens | 布尔值。 指定令牌是否需要签名。 允许使用策略表达式。 | 否 | 是 |
clock-skew | 时间跨度。 用于指定令牌颁发者的系统时钟与 API 管理实例之间的最大预期时间差。 允许使用策略表达式。 | 否 | 0 秒 |
output-token-variable-name | 字符串。 成功进行令牌验证后,将作为 Jwt 类型的对象接收令牌值的上下文变量的名称。 不允许使用策略表达式。 |
否 | 空值 |
元素
元素 | 说明 | 必需 |
---|---|---|
openid-config | 添加这些元素中的一个或多个,以指定兼容的 OpenID 配置终结点 URL,以便从该终结点获取签名密钥和颁发者。 每 1 小时从终结点拉取一次包含 JSON Web 密钥集 (JWKS) 的配置并进行缓存。 如果正在验证的令牌引用缓存配置中缺少的验证密钥(使用 kid 声明),或者如果检索失败,则 API 管理最多每 5 分钟从终结点拉取一次。 这些间隔如有更改,恕不另行通知。 响应应符合以下 URL 中定义的规范: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata 。 对于 Microsoft Entra ID,请使用在应用注册中配置的 OpenID Connect 元数据终结点,例如: - v2 https://login.partner.microsoftonline.cn/{tenant-name}/v2.0/.well-known/openid-configuration - v2 多租户 https://login.partner.microsoftonline.cn/organizations/v2.0/.well-known/openid-configuration - v1 https://login.partner.microsoftonline.cn/{tenant-name}/.well-known/openid-configuration - 客户租户(预览版) https://{tenant-name}.ciamlogin.com/{tenant-id}/v2.0/.well-known/openid-configuration 使用你的目录租户名称或 ID(例如 contoso.partner.onmschina.cn )替换 {tenant-name} 。 |
否 |
issuer-signing-keys | key 子元素中 Base64 编码的安全密钥列表,用于验证签名的令牌。 如果存在多个安全密钥,则会对每个密钥进行尝试,直到所有密钥都试完(这种情况表明验证失败),或者直到有一个密钥成功(这对令牌滚动更新十分有用)。 (可选)使用 id 属性指定密钥以匹配令牌的 kid 声明。 若要验证使用非对称密钥签名的令牌,可以选择性地使用 certificate-id 属性(其值设置为上传到 API 管理的证书的标识符)指定公钥,或使用该签名密钥的 RSA 模数 n 和指数 e 对采用 Base64url 编码格式指定公钥。 |
否 |
decryption-keys | key 子元素中的 Base64 编码密钥列表,用于解密令牌。 如果存在多个安全密钥,则会对每个密钥进行尝试,直到所有密钥都试完(这种情况表明验证失败)或直到有一个密钥成功为止。若要解密使用非对称密钥加密的令牌,可选择性地使用 certificate-id 属性指定公钥(该属性的值设置为上传到 API 管理的证书的标识符)。 |
否 |
audiences | audience 子元素中的可接受且可存在于令牌上的受众声明列表。 如果存在多个受众值,则会对每个值进行尝试,直到有一个值成功(如果所有值都试完却没有一个成功,则表明验证失败)。 必须指定至少一个受众。 |
否 |
issuers | issuer 子元素中可接受的、颁发了令牌的主体列表。 如果存在多个颁发者值,则会对每个值进行尝试,直到有一个值成功(如果所有值都试完却没有一个成功,则表明验证失败)。 |
否 |
required-claims | claim 子元素中的声明列表,这些声明应存在于令牌上,否则令牌会被视为无效。 如果存在多个声明,则令牌必须根据 match 属性值匹配声明值。 |
否 |
密钥属性
属性 | 说明 | 需要 | 默认 |
---|---|---|---|
id | (仅颁发者签名密钥)字符串。 用于匹配 JWT 中提供的 kid 声明的标识符。 |
否 | 空值 |
certificate-id | 上传到 API 管理的证书实体的标识符,用于指定公钥以验证使用非对称密钥签名的令牌。 | 否 | 空值 |
n | (仅颁发者签名密钥)用于验证使用非对称密钥签名的令牌的颁发者的公钥模数。 必须使用指数 e 的值指定。 不允许使用策略表达式。 |
否 | 空值 |
e | (仅颁发者签名密钥)用于验证使用非对称密钥签名的令牌的颁发者的公钥指数。 必须使用模数 n 的值指定。 不允许使用策略表达式。 |
否 | 空值 |
声明属性
属性 | 说明 | 需要 | 默认 |
---|---|---|---|
match | claim 元素的 match 属性用于指定:是否策略中的每个声明值都必须存在于令牌中验证才会成功。 可能的值为:- all - 策略中的每个声明值都必须存在于令牌中验证才会成功。- any - 至少一个声明值必须存在于令牌中验证才会成功。 |
否 | all |
separator | 字符串。 指定要用于从多值声明中提取一组值的分隔符(例如 ",")。 | 否 | 空值 |
使用情况
使用注意事项
validate-jwt
策略要求exp
注册声明包括在 JWT 令牌中,除非require-expiration-time
属性已指定并设置为false
。- 策略支持对称和非对称签名算法:
- 对称 - 支持以下加密算法:A128CBC-HS256、A192CBC-HS384、A256CBC-HS512。
- 如果在策略中使用,则必须在策略中以 Base64 编码格式提供内联方式的密钥。
- 非对称 - 支持以下加密算法:PS256、RS256、RS512、ES256。
- 如果在策略中使用,则密钥可以通过 OpenID 配置终结点来提供,也可通过提供已上传证书(采用 PFX 格式)的 ID 来提供,该证书包含公钥或公钥的模数-指数对。
- 对称 - 支持以下加密算法:A128CBC-HS256、A192CBC-HS384、A256CBC-HS512。
- 若要使用与自承载网关配合使用的一个或多个 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.partner.microsoftonline.cn/contoso.partner.onmschina.cn/.well-known/openid-configuration" />
<audiences>
<audience>00001111-aaaa-2222-bbbb-3333cccc4444</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.partner.microsoftonline.cn/tfp/contoso.partner.onmschina.cn/b2c_1_signin/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>11112222-bbbb-3333-cccc-4444dddd5555</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>
相关策略
后续步骤
有关使用策略的详细信息,请参阅:
- 教程:转换和保护 API
- 策略参考,其中提供了策略语句及其设置的完整列表
- 策略表达式
- 设置或编辑策略
- 策略示例