使用事件网格事件架构的终结点验证
Webhook 是从 Azure 事件网格接收事件的多种方式之一。 当新事件准备就绪时,事件网格服务会向已配置的终结点 POST HTTP 请求,并在请求正文中包含该事件信息。
与众多支持 Webhook 的其他服务一样,事件网格需要你证明对 Webhook 的所有权,然后才能开始向该终结点传送事件。 此要求可防止恶意用户用大量事件淹没你的终结点。
通过事件网格事件验证终结点
如果使用以下 Azure 服务中的任何一项,Azure 基础结构将自动进行此验证:
如果使用其他任何类型的终结点(例如基于 HTTP 触发器的 Azure 函数),终结点代码需要参与事件网格的验证握手。 事件网格支持通过两种方式来验证订阅。
同步握手:在创建事件订阅时,事件网格会将一个订阅验证事件发送到终结点。 此事件的架构与任何其他事件网格事件类似。 此事件的数据部分包括一个
validationCode
属性。 你的应用程序会确认验证请求是否针对预期的事件订阅,并在响应中同步返回验证码。 所有事件网格版本都支持此握手机制。异步握手:在某些情况下,无法在响应中同步返回
validationCode
。 例如,如果使用非 Microsoft 服务(如Zapier
或 IFTTT),则无法以编程方式使用验证码进行响应。事件网格支持手动验证握手。 如果你在创建事件订阅时使用的 SDK 或工具使用了 API 版本 2018-05-01-preview 或更高版本,则事件网格将在订阅验证事件的数据部分中发送
validationUrl
属性。 若要完成握手,请在事件数据中找到该 URL 并向其发送一个 GET 请求。 你可以使用 REST 客户端或 Web 浏览器。提供的 URL 的有效期为 10 分钟。 在该时间内,事件订阅的预配状态为
AwaitingManualAction
。 如果在 10 分钟内未完成手动验证,则配置状态被设为Failed
。 你将必须在开始手动验证之前重新创建事件订阅。此身份验证机制还要求 Webhook 终结点返回 HTTP 状态代码 200,这样它就知道验证事件的 POST 已被接受,然后它就可以进入手动验证模式。 换句话说,如果终结点返回 200,但没有同步返回验证响应,则模式将转换为手动验证模式。 如果在 10 分钟内验证 URL 收到一个 GET 请求,则将验证握手视为成功。
注意
不支持使用自签名证书进行验证。 请改为使用商业证书颁发机构 (CA) 颁发的签名证书。
验证详细信息
- 在创建/更新事件订阅时,事件网格会将一个订阅验证事件发送到目标终结点。
- 事件包含标头值
aeg-event-type: SubscriptionValidation
。 - 事件正文具有与其他事件网格事件相同的架构。
- 事件的
eventType
属性为Microsoft.EventGrid.SubscriptionValidationEvent
。 - 该事件的
data
属性包括一个validationCode
属性,其中含有随机生成的字符串。 例如,validationCode: acb13…
。 - 事件数据还包括
validationUrl
属性,其中包含用于手动验证订阅的 URL。 - 该数组仅包含验证事件。 你回显验证代码后,事件网格会以单独的请求发送其他事件。
- 事件网格数据平面 SDK 包含对应订阅验证事件数据和订阅验证响应的类。
以下示例显示了 SubscriptionValidationEvent 示例:
[
{
"id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66",
"topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"subject": "",
"data": {
"validationCode": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6",
"validationUrl": "https://rp-chinanorth2.eventgrid.azure.cn:553/eventsubscriptions/myeventsub/validate?id=0000000000-0000-0000-0000-00000000000000&t=2022-10-28T04:23:35.1981776Z&apiVersion=2018-05-01-preview&token=1A1A1A1A"
},
"eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
"eventTime": "2022-10-28T04:23:35.1981776Z",
"metadataVersion": "1",
"dataVersion": "1"
}
]
为证明终结点所有权,请在 validationResponse
属性中回显验证代码,如下例所示:
{
"validationResponse": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6"
}
执行下列步骤之一:
你必须返回 HTTP 200 OK 响应状态代码。 HTTP 202 Accepted 未被识别为有效的事件网格订阅验证响应。 必须在 30 秒内完成 HTTP 请求。 如果未在 30 秒内完成操作,那么操作将被取消,并在 5 秒后重试。 如果所有尝试都失败,则会将其视为验证握手错误。
应用程序已准备好处理并返回验证代码,这表明你创建了事件订阅并预期接收该事件。 假设不支持握手验证,而黑客知道了应用程序 URL。 黑客可以使用应用程序的 URL 创建主题和事件订阅,并通过发送大量事件开始对应用程序执行 DoS 攻击。 握手验证可防止发生这种情况。
假设已在应用中实现了验证,因为你创建了自己的事件订阅。 即使黑客使用应用 URL 创建事件订阅,验证请求事件的正确实现也会检查请求中的
aeg-subscription-name
标头,以确定它是你识别的事件订阅。即使在正确的握手实现之后,黑客也可以通过复制看似来自事件网格的请求来淹没应用程序 (它已验证事件订阅) 。 若要防止这一点,必须使用 Microsoft Entra 身份验证保护 Webhook。 有关详细信息,请参阅将事件传送到 Microsoft Entra 保护的终结点。
另外,还可以通过将 GET 请求发送到验证 URL 来手动验证订阅。 事件订阅将一直处于挂起状态,直到得到验证。 验证 URL 使用端口 553。 如果防火墙规则阻止端口 553,则需要更新规则才能成功进行手动握手。
在订阅验证事件的验证中,如果确定它不是预期事件的事件订阅,则不会返回 200 响应或根本不返回响应。 因此,验证将失败。
有关处理订阅验证握手的示例,请参阅 C# 示例。
相关内容
请参阅以下文章,了解如何排查事件订阅验证问题:排查事件订阅验证问题。