验证内容
适用于:所有 API 管理层级
validate-content
策略根据一个或多个支持的架构验证请求或响应正文的大小或内容。
下表显示了策略支持的架构格式和请求或响应内容类型。 内容类型值不区分大小写。
格式 | 内容类型 |
---|---|
JSON | 示例:application/json application/hal+json |
XML | 示例:application/xml |
SOAP | 允许的值:application/soap+xml (适用于 SOAP 1.2 API)text/xml (适用于 SOAP 1.1 API) |
注意
可供此验证策略使用的 API 架构的最大大小为 4 MB。 如果架构超过此限制,验证策略将在运行时返回错误。 若要提高限制,请与支持部门联系。
验证的内容
该策略针对架构在请求或响应中验证以下内容:
- 存在所有必需的属性。
- 如果架构设置了
additionalProperties
字段,就存在或不存在其他属性。 可以用allow-additional-properties
属性替代。 - 所有属性的类型。 例如,如果架构将属性指定为整数,则请求(或响应)必须包含整数,而不是另一种类型,如字符串。
- 属性的格式(如在架构中指定)—例如,正则表达式(如果指定了关键字
pattern
),整数为minimum
等。
提示
有关可用于架构的正则表达式模式约束的示例,请参阅 OWASP 验证正则表达式存储库。
提示
为了帮助你配置此策略,门户提供了基于窗体的引导式编辑器。 详细了解如何设置或编辑 API 管理策略。
策略语句
<validate-content unspecified-content-type-action="ignore | prevent | detect" max-size="size in bytes" size-exceeded-action="ignore | prevent | detect" errors-variable-name="variable name">
<content-type-map any-content-type-value="content type string" missing-content-type-value="content type string">
<type from | when="content type string" to="content type string" />
</content-type-map>
<content type="content type string" validate-as="json | xml | soap" schema-id="schema id" schema-ref="#/local/reference/path" action="ignore | prevent | detect" allow-additional-properties="true | false" case-insensitive-property-names="true | false"/>
</validate-content>
属性
属性 | 说明 | 需要 | 默认 |
---|---|---|---|
unspecified-content-type-action | 针对其内容类型未在 API 架构中指定的请求或响应执行的操作。 允许使用策略表达式。 | 是 | 空值 |
max_size | 请求或响应正文的最大长度(以字节为单位),根据 Content-Length 标头进行检查。 如果请求正文或响应正文经过压缩,则此值是解压缩后的长度。 最大允许值:102,400 字节 (100 KB)。 (如果需要提高此限制,请联系客户支持。)允许使用策略表达式。 |
是 | 空值 |
size-exceeded-action | 针对其正文超过 max-size 中指定大小的请求或响应执行的操作。 允许使用策略表达式。 |
是 | 空值 |
errors-variable-name | context.Variables 中的要将验证错误记录到的变量的名称。 不允许使用策略表达式。 |
否 | 空值 |
元素
名称 | 说明 | 必需 |
---|---|---|
content-type-map | 添加此元素,将传入请求或响应的内容类型映射到用于触发验证的另一个内容类型。 | 否 |
内容 | 添加其中的一个或多个元素可以验证请求或响应中的内容类型或映射的内容类型,并执行指定的操作。 | 否 |
content-type-map 属性
属性 | 说明 | 需要 | 默认 |
---|---|---|---|
any-content-type-value | 用于验证请求或响应正文的内容类型,与传入内容类型无关。 不允许使用策略表达式。 | 否 | 空值 |
missing-content-type-value | 当传入内容类型缺失或为空时用于验证请求或响应正文的内容类型。 不允许使用策略表达式。 | 否 | 空值 |
content-type-map-elements
名称 | 说明 | 必需 |
---|---|---|
type | 添加一个或多个此类元素,以将传入内容类型映射到用于验证请求或响应正文的内容类型。 使用 from 指定已知的传入内容类型,或将 when 与策略表达式配合使用以指定与条件匹配的任何传入内容类型。 如果已指定此项,则会替代 any-content-type-value 和 missing-content-type-value 中的映射。 |
否 |
content 属性
属性 | 说明 | 需要 | 默认 |
---|---|---|---|
类型 | 要为其执行正文验证的内容类型,在已指定此项的情况下针对 content-type-mapping 中映射的内容类型标头或值进行检查。 如果为空,此值将应用到 API 架构中指定的每个内容类型。若要验证 SOAP 请求和响应( validate-as 特性设置为“soap”),请将 type 设置为 application/soap+xml (适用于 SOAP 1.2 API)或 text/xml (适用于 SOAP 1.1 API)。 |
否 | 空值 |
validate-as | 用于验证具有匹配 type 的请求或响应正文的验证引擎。 支持的值:“json”、“xml”、“soap”。指定“soap”时,请求或响应中的 XML 将从 SOAP 信封中提取出来,并根据 XML 架构进行验证。 |
是 | 空值 |
schema-id | 已添加到 API 管理实例以进行内容验证的现有架构的名称。 如果未指定此项,则使用 API 定义中的默认架构。 | 否 | 空值 |
schema-ref | 对于 schema-id 中指定的 JSON 架构,可选择引用 JSON 文档中的有效本地引用路径。 示例:#/components/schemas/address 。 此特性应返回 API 管理将其作为有效 JSON 架构进行处理的 JSON 对象。就 XML 架构来说, schema-ref 不受支持,任何顶级架构元素都可用作 XML 请求或响应有效负载的根。 此验证会检查从 XML 请求或响应有效负载根开始的所有元素是否都遵循所提供的 XML 架构。 |
否 | 空值 |
allow-additional-properties | 布尔值。 对于 JSON 架构,请指定是否实现架构中配置的 additionalProperties 值的运行时替代:- true :支持请求或响应正文中的其他属性,即使将 JSON 架构的 additionalProperties 字段配置为不支持其他属性。 - false :不支持请求或响应正文中的其他属性,即使将 JSON 架构的 additionalProperties 字段配置为支持其他属性。如果未指定属性,策略会根据架构中 additionalProperties 字段的配置验证其他属性。 |
否 | 空值 |
case-insensitive-property-names | 布尔值。 对于 JSON 架构,指定是否比较 JSON 对象的属性名称而不区分大小写。 - true :比较属性名称,但不区分大小写。 - false :比较属性名称,且区分大小写。 |
否 | false |
操作
内容验证策略包含一个或多个用于指定操作的特性,该操作将由 API 管理在根据 API 架构验证 API 请求或响应中的实体时执行。
可为 API 架构中表示的元素指定操作,并可以根据策略为 API 架构中未表示的元素指定操作。
在策略的子元素中指定的操作将替代针对其父级指定的操作。
可用操作:
操作 | 说明 |
---|---|
ignore | 跳过验证。 |
prevent | 阻止请求或响应处理,记录详细的验证错误,并返回错误。 检测到第一组错误时便中断处理。 |
检测 (detect) | 记录验证错误,但不中断请求或响应处理。 |
使用情况
日志
有关在执行策略期间出现的验证错误的详细信息将记录到策略根元素的 errors-variable-name
特性中指定的 context.Variables
内的变量。 在 prevent
操作中进行配置后,验证错误会阻止进一步的请求或响应处理,并会传播到 context.LastError
属性。
若要调查错误,请使用跟踪策略将上下文变量中的错误记录到 Application Insights。
性能影响
添加验证策略可能会影响 API 吞吐量。 以下一般原则适用:
- API 架构越大,吞吐量越低。
- 请求或响应中的有效负载越大,吞吐量越低。
- 相比于有效负载大小,API 架构大小对性能的影响更大。
- 在某些情况下,根据若干 MB 大小的 API 架构进行验证可能会导致请求或响应超时。 在“消耗”和“开发人员”服务层级中,这种影响更为明显。
我们建议在预期的生产工作负载中执行负载测试,以评估验证策略对 API 吞吐量的影响。
内容验证架构
默认情况下,对请求或响应内容的验证使用 API 定义中的 JSON 或 XML 架构。 可以手动指定这些架构,也可以在将 API 从 OpenAPI 或 WSDL 规范导入 API 管理时自动生成这些架构。
使用 validate-content
策略,你可以根据需要针对已添加到 API 管理实例并且不属于 API 定义的一个或多个 JSON 或 XML 架构进行验证。 添加到 API 管理的架构可在多个 API 中重复使用。
若要使用 Azure 门户将架构添加到 API 管理实例,请执行以下操作:
在门户中导航到 API 管理实例。
在左侧菜单的“API”部分,选择“架构”>“+ 添加”。
在“创建架构”窗口中,执行以下操作:
- 为架构输入一个“名称”(ID)。
- 在“架构类型”中,选择“JSON”或“XML”。
- 输入“说明”。
- 在“Create 方法”中,执行下列操作之一:
- 选择“新建”,然后输入或粘贴架构。
- 选择“从文件导入”或“从 URL 导入”,然后输入架构位置。
备注
若要从 URL 导入某个架构,需要能够在浏览器中通过 Internet 访问该架构。
- 选择“保存”。
API 管理在相对 URI /schemas/<schemaId>
处添加架构资源,架构将显示在“架构”页面的列表中。 选择要在架构编辑器中查看其属性或进行编辑的架构。
备注
一个架构可以交叉引用添加到 API 管理实例的其他架构。 例如,使用类似于以下内容的元素包括添加到 API 管理的 XML 架构:<xs:include schemaLocation="/schemas/myschema" />
提示
GitHub 上提供用于解析 WSDL 和 XSD 架构引用以及将生成的架构成批导入到 API 管理的开源工具。
示例
JSON 架构验证
在以下示例中,API 管理将内容类型标头为空的请求或内容类型标头为 application/hal+json
的请求解释为内容类型为 application/json
的请求。 然后,API 管理在检测模式下针对一个为 API 定义中的 application/json
内容类型定义的架构执行验证。 将阻止有效负载大于 100 KB 的消息。 即使将架构的 additionalProperties
字段配置为支持其他属性,包含其他属性的请求也会被阻止。
<validate-content unspecified-content-type-action="prevent" max-size="102400" size-exceeded-action="prevent" errors-variable-name="requestBodyValidation">
<content-type-map missing-content-type-value="application/json">
<type from="application/hal+json" to="application/json" />
</content-type-map>
<content type="application/json" validate-as="json" action="detect" allow-additional-properties="false" />
</validate-content>
SOAP 架构验证
在以下示例中,API 管理将任何请求都解释为内容类型为 application/soap+xml
(SOAP 1.2 API 使用的内容类型)的请求,而不考虑传入内容类型。 请求在到达时可能带有空的内容类型标头、内容类型标头 text/xml
(由 SOAP 1.1 API 使用)或其他内容类型标头。 然后,API 管理从 SOAP 信封中提取 XML 有效负载,并针对名为“myschema”的架构在预防模式下执行验证。 将阻止有效负载大于 100 KB 的消息。
<validate-content unspecified-content-type-action="prevent" max-size="102400" size-exceeded-action="prevent" errors-variable-name="requestBodyValidation">
<content-type-map any-content-type-value="application/soap+xml" />
<content type="application/soap+xml" validate-as="soap" schema-id="myschema" action="prevent" />
</validate-content>
验证错误
API 管理生成以下格式的内容验证错误:
{
"Name": string,
"Type": string,
"ValidationRule": string,
"Details": string,
"Action": string
}
下表列出了验证策略的所有可能错误。
- 详细信息:可用于调查错误。 不应公开共享。
- 公共响应:返回到客户端的错误。 不会泄漏实现详细信息。
当验证策略指定 prevent
操作并产生错误时,API 管理的响应将包括 HTTP 状态代码:在入站部分中应用该策略时为 400,在出站部分应用该策略时为 502。
名称 | 类型 | 验证规则 | 详细信息 | 公共响应 | 操作 |
---|---|---|---|---|---|
validate-content | |||||
RequestBody | SizeLimit | 请求正文的长度为 {size} 个字节,超过了配置的限制({maxSize} 字节)。 | 请求正文的长度为 {size} 个字节,超过了限制({maxSize} 字节)。 | detect / prevent | |
ResponseBody | SizeLimit | 响应正文的长度为 {size} 个字节,超过了配置的限制({maxSize} 字节)。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent | |
{messageContentType} | RequestBody | 未指定 | 不允许未指定的内容类型 {messageContentType}。 | 不允许未指定的内容类型 {messageContentType}。 | detect / prevent |
{messageContentType} | ResponseBody | 未指定 | 不允许未指定的内容类型 {messageContentType}。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
ApiSchema | API 的架构不存在或无法解析。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent | ||
ApiSchema | API 的架构未指定定义。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent | ||
{messageContentType} | RequestBody / ResponseBody | MissingDefinition | API 的架构不包含与内容类型 {messageContentType} 关联的定义 {definitionName}。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
{messageContentType} | RequestBody | IncorrectMessage | 请求正文不符合与内容类型 {messageContentType} 关联的定义 {definitionName}。 {valError.Message} 行: {valError.LineNumber},位置: {valError.LinePosition} |
请求正文不符合与内容类型 {messageContentType} 关联的定义 {definitionName}。 {valError.Message} 行: {valError.LineNumber},位置: {valError.LinePosition} |
detect / prevent |
{messageContentType} | ResponseBody | IncorrectMessage | 响应正文不符合与内容类型 {messageContentType} 关联的定义 {definitionName}。 {valError.Message} 行: {valError.LineNumber},位置: {valError.LinePosition} |
由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
RequestBody | ValidationException | 无法验证 {messageContentType} 内容类型的请求正文。 {exception details} |
由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent | |
ResponseBody | ValidationException | 无法验证 {messageContentType} 内容类型的响应正文。 {exception details} |
由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent | |
validate-parameters / validate-headers | |||||
{paramName} / {headerName} | QueryParameter / PathParameter / RequestHeader | 未指定 | 不允许未指定的 {path parameter / query parameter / header} {paramName}。 | 不允许未指定的 {path parameter / query parameter / header} {paramName}。 | detect / prevent |
{headerName} | ResponseHeader | 未指定 | 不允许未指定的头 {headerName}。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
ApiSchema | API 的架构不存在或无法解析。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent | ||
ApiSchema | API 架构未指定定义。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent | ||
{paramName} | QueryParameter / PathParameter / RequestHeader / ResponseHeader | MissingDefinition | API 的架构不包含与 {query parameter / path parameter / header} {paramName} 关联的定义 {definitionName}。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
{paramName} | QueryParameter / PathParameter / RequestHeader | IncorrectMessage | 请求不能包含 {query parameter / path parameter / header} {paramName} 的多个值。 | 请求不能包含 {query parameter / path parameter / header} {paramName} 的多个值。 | detect / prevent |
{headerName} | ResponseHeader | IncorrectMessage | 响应不能包含头 {headerName} 的多个值。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
{paramName} | QueryParameter / PathParameter / RequestHeader | IncorrectMessage | {query parameter / path parameter / header} {paramName} 的值不符合定义。 {valError.Message} 行: {valError.LineNumber},位置: {valError.LinePosition} |
{query parameter / path parameter / header} {paramName} 的值不符合定义。 {valError.Message} 行: {valError.LineNumber},位置: {valError.LinePosition} |
detect / prevent |
{headerName} | ResponseHeader | IncorrectMessage | 头 {headerName} 的值不符合定义。 {valError.Message} 行: {valError.LineNumber},位置: {valError.LinePosition} |
由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
{paramName} | QueryParameter / PathParameter / RequestHeader | IncorrectMessage | 无法根据定义分析 {query parameter / path parameter / header} {paramName} 的值。 {ex.Message} |
无法根据定义分析 {query parameter / path parameter / header} {paramName} 的值。 {ex.Message} |
detect / prevent |
{headerName} | ResponseHeader | IncorrectMessage | 无法根据定义分析头 {headerName} 的值。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
{paramName} | QueryParameter / PathParameter / RequestHeader | ValidationError | 无法验证 {Query parameter / Path parameter / Header} {paramName}。 {exception details} |
由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
{headerName} | ResponseHeader | ValidationError | 无法验证头 {headerName}。 {exception details} |
由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
validate-status-code | |||||
{status-code} | StatusCode | 未指定 | 不允许响应状态代码 {status-code}。 | 由于发生内部错误,无法处理请求。 请与 API 所有者联系。 | detect / prevent |
下表列出了验证错误的所有可能原因值以及可能的消息值:
原因 | 消息 |
---|---|
错误的请求 | 针对上下文变量的 {Details},针对客户端的 {Public response} |
不允许响应 | 针对上下文变量的 {Details},针对客户端的 {Public response} |
相关策略
后续步骤
有关使用策略的详细信息,请参阅:
- 教程:转换和保护 API
- 策略参考,其中提供了策略语句及其设置的完整列表
- 策略表达式
- 设置或编辑策略
- 策略示例