你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用自定义 Webhook 身份验证通过 MQTT 中转站进行身份验证

本文介绍如何使用 Webhook 或 Azure 函数通过 Azure 事件网格命名空间进行身份验证。

Webhook 身份验证允许外部 HTTP 终结点(Webhook 或函数)动态对消息队列遥测传输(MQTT)连接进行身份验证。 此方法使用 Microsoft Entra ID JSON Web 令牌验证来确保安全访问。

当客户端尝试连接时,代理会调用用户定义的 HTTP 终结点来验证凭据,例如共享访问签名令牌、用户名和密码,甚至执行证书吊销列表检查。 Webhook 评估请求,并返回允许或拒绝连接的决定,以及用于细化授权的可选元数据。 此方法支持跨各种设备机群和用例的灵活集中式身份验证策略。

先决条件

  • 具有系统分配的托管标识或用户分配的托管标识的事件网格命名空间。
  • 外部 Webhook 或 Azure 函数。
  • 向事件网格命名空间的托管标识授予对 Azure 函数或 Webhook 的访问权限。

高级步骤

若要对命名空间使用自定义 Webhook 身份验证,请执行以下步骤:

  1. 创建命名空间并配置其子资源。
  2. 在事件网格命名空间上启用托管标识。
  3. 授予托管标识对 Azure 函数或 Webhook 的访问权限。
  4. 在事件网格命名空间上配置自定义 Webhook 设置。
  5. 将客户端连接到事件网格命名空间,并通过 Webhook 或函数进行身份验证。

创建命名空间并配置其子资源

若要创建命名空间并配置其子资源,请按照快速入门中的说明作 :使用 Azure 门户在事件网格命名空间上发布和订阅 MQTT 消息。 跳过创建证书和客户端的步骤,因为客户端标识来自提供的令牌。 客户端属性基于客户端令牌中的自定义声明。 客户端属性用于客户端组查询、主题模板变量和路由扩充配置。

在事件网格命名空间上启用托管标识

若要在事件网格命名空间上启用系统分配的托管标识,请使用以下命令:

az eventgrid namespace update --resource-group <resource group name> --name <namespace name> --identity "{type:systemassigned}" 

有关如何使用 Azure 门户配置系统和用户分配标识的信息,请参阅 为事件网格命名空间启用托管标识

授予托管标识对函数或 Webhook 的适当访问权限

向事件网格命名空间的托管标识授予对目标 Azure 函数或 Webhook 的适当访问权限。

若要为 Azure 函数设置自定义身份验证,请执行以下步骤。

创建Microsoft Entra应用

  1. 在 Microsoft Entra ID 中创建Microsoft Entra 应用

  2. 在应用的 “概述 ”页上,记下 应用程序(客户端)ID 值。

    显示Microsoft Entra ID 应用的“概述”页的屏幕截图,其中突出显示了应用程序(客户端)ID。

  3. 在左侧菜单中,选择“ 公开 API”。 在 应用程序 ID URI 旁边,选择“ 添加”。

  4. 记下“编辑应用程序 ID URI”窗格中的应用程序 ID URI 值,然后选择“保存”。

    显示Microsoft Entra 应用的应用程序 ID URI 的屏幕截图。

为 Azure 函数设置身份验证

如果已从 Azure 门户创建基本 Azure 函数,请设置身份验证并验证使用托管标识创建的 Microsoft Entra ID 令牌。

  1. 转到 Azure Functions 应用。

  2. 在左侧菜单中,选择“ 身份验证”,然后选择“ 添加标识提供者”。

    显示“身份验证”页的屏幕截图。

  3. “添加标识提供者 ”页上,对于 标识提供者,从下拉列表中选择 Microsoft

  4. “应用注册 ”部分中,指定以下属性的值:

    1. 应用程序(客户端)ID:输入前面记录的 Microsoft Entra 应用的客户端 ID。

    2. 颁发者 URL:在窗体 https://login.microsoftonline.com/<tenantid>/v2.0中添加颁发者 URL。

      显示“添加标识提供者”的屏幕截图,其中Microsoft为标识提供者。

  5. 对于 允许的令牌访问群体,请添加前面记录的 Microsoft Entra 应用 的应用程序 ID URI 值。

  6. 在“ 其他检查 ”部分中,对于 客户端应用程序开发,请选择 “允许来自特定客户端应用程序的请求”。

  7. “允许的客户端应用程序 ”窗格中,输入用于生成令牌的系统分配托管标识的客户端 ID。 可以在Microsoft Entra ID 资源的企业应用中找到此 ID。

  8. 根据特定要求选择其他设置,然后选择“ 添加”。

现在,生成并使用 Microsoft Entra ID 令牌。

  1. 使用具有应用程序 ID URI 作为资源的托管标识生成Microsoft Entra ID 令牌。
  2. 使用此令牌并将其包含在请求标头中来调用 Azure 函数。

在事件网格命名空间上配置自定义 Webhook 身份验证设置

使用 Azure 门户和 Azure CLI 在事件网格命名空间上配置自定义 Webhook 身份验证设置。 首先创建命名空间,然后对其进行更新。

使用 Azure 门户

  1. Azure 门户中转到事件网格命名空间。

  2. 在“事件网格命名空间”页面中,选择左侧菜单上的“配置”。

  3. “自定义 Webhook 身份验证 ”部分中,指定以下属性的值:

    1. 托管标识类型:选择 已分配的用户
    2. Webhook URL:输入事件网格服务使用指定的托管标识发送经过身份验证的 Webhook 请求的 URL 终结点的值。
    3. 令牌访问群体 URI:输入 Microsoft Entra 应用程序 ID 或 URI 的值,以获取在传递请求中作为持有者令牌包含的访问令牌。
    4. Microsoft Entra ID 租户 ID:输入用于获取经过身份验证的 Webhook 传递的持有者令牌的 entra 租户 ID Microsoft 的值。
  4. 选择应用

    屏幕截图显示事件网格命名空间的 Webhook 身份验证配置。

使用 Azure CLI

若要使用自定义 Webhook 身份验证配置更新命名空间,请使用以下命令:

az eventgrid namespace update \ 
    --resource-group <resource-group-name> \ 
    --name <namespace-name> \ 
    --api-version 2025-04-01-preview \ 
    --identity-type UserAssigned \ 
    --identity-user-assigned-identities "/subscriptions/XXXXXXXXXXX/resourcegroups/XXXXXXXXXXX/providers/Microsoft.ManagedIdentity/userAssignedIdentities/XXXXXXXXXXX={}" \ 
    --set properties.isZoneRedundant=true \ 
        properties.topicSpacesConfiguration.state=Enabled \ 
        properties.topicSpacesConfiguration.clientAuthentication.webHookAuthentication.identity.type=UserAssigned \ 
        properties.topicSpacesConfiguration.clientAuthentication.webHookAuthentication.identity.userAssignedIdentity="/subscriptions/XXXXXXXXXXX/resourcegroups/XXXXXXXXXXX/providers/Microsoft.ManagedIdentity/userAssignedIdentities/XXXXXXXXXXX" \ 
        properties.topicSpacesConfiguration.clientAuthentication.webHookAuthentication.endpointUrl="https://XXXXXXXXXXX" \ 
        properties.topicSpacesConfiguration.clientAuthentication.webHookAuthentication.azureActiveDirectoryApplicationIdOrUri="api://XXXXXXXXXXX/.default" \ 
        properties.topicSpacesConfiguration.clientAuthentication.webHookAuthentication.azureActiveDirectoryTenantId="XXXXXXXXXXX" 

替换 <NAMESPACE_NAME><RESOURCE_GROUP_NAME> 替换为实际值。 填写订阅、资源组、标识、应用 ID、URL 和租户 ID 中的占位符。 为了增强基于 Webhook 的身份验证的性能和可靠性,我们强烈建议为 Webhook 终结点启用 HTTP/2 支持。

Webhook API 详细信息

请求标头

授权:持有者令牌

令牌是配置为调用 Webhook 的托管标识的 Microsoft Entra 令牌。

请求有效负载

{
    "clientId": "<string>",
    "userName": "<string>",
    "password": "<base64 encoded bytes>",
    "authenticationMethod": "<string>",
    "authenticationData": "<base64 encoded bytes>",
    "clientCertificate": "<certificate in PEM format>",
    "clientCertificateChain": "<certificates from chain in PEM format>"
}

有效负载字段说明

领域 必需/可选 DESCRIPTION
clientId 必选 MQTT CONNECT 数据包中的客户端 ID。
userName 可选 MQTT CONNECT 数据包中的用户名。
password 可选 Base64 编码中 MQTT CONNECT 数据包的密码。
authenticationMethod 可选 MQTT CONNECT 数据包的身份验证方法(仅限 MQTT5)。
authenticationData 可选 基于 Base64 编码(仅 MQTT5)中 MQTT CONNECT 数据包的身份验证数据。
clientCertificate 可选 PEM 格式的客户端证书。
clientCertificateChain 可选 客户端提供的其他证书需要从客户端证书生成链到证书颁发机构证书。
userProperties 可选 CONNECT 数据包(仅 MQTT5)中的用户属性。

响应有效负载

成功的响应

HTTP/1.1 200 OK 
Content-Type: application/json 

{ 
    "decision": "allow", 
    "clientAuthenticationName": "<string>", 
    "attributes": { 
        "attr": "<int/string/array_of_strings>", 
        ... 
    }, 
    "expiration": "<unix time format>" 
} 

拒绝的响应

HTTP/1.1 400 Bad Request 
Content-Type: application/json 

{ 
    "decision": "deny", 
    "errorReason": "<string>" 
}

响应字段说明

领域 DESCRIPTION
decision(必需) 身份验证决策为或 allowdeny
clientAuthenticationName 客户端身份验证名称(标识名称)。 (设置为 decisionallow.)
attributes 具有属性的字典。 键是属性名称,值是 int/string/array。 (当 decision 设置为 allow.)
expiration Unix 时间格式的过期日期。 (当 decision 设置为 allow.)
errorReason 如果 decision 设置为 deny.,则显示错误消息。 该错误已记录。 (当 decision 设置为 deny.)

支持的属性类型示例

"num_attr_pos": 1, 
"num_attr_neg": -1, 
"str_attr": "str_value", 
"str_list_attr": [ 
    "str_value_1", 
    "str_value_2" 
] 

所有正确的数据类型(适合 <int32/string/array_of_strings>的数字)都用作属性。 在示例中,num_attr_pos声明num_attr_negstr_attrstr_list_attr声明具有正确的数据类型,并用作属性。