通过Azure 事件中心接收更改通知
Webhook 可能不适合在高吞吐量方案中接收更改通知,或者当接收方无法公开可用的通知 URL 时。 或者,可以使用 Azure 事件中心。
高吞吐量方案的不错示例包括订阅大量资源集的应用程序、订阅以高频率更改的资源的应用程序,以及跨大型组织订阅资源的多租户应用程序。
本文介绍如何管理 Microsoft Graph 订阅,并通过Azure 事件中心接收更改通知。
使用 Azure 事件中心接收更改通知
Azure 事件中心是专为大规模部署而构建的常用实时事件引入和分发服务。 你可以使用 Azure 事件中心而不是传统 Webhook 来接收更改通知。
使用 Azure 事件中心接收更改通知与 Webhook 在某些方面有所不同,包括:
- 不依赖公开显示的通知 URL。 事件中心 SDK 会将通知转发到你的应用程序。
- 无需恢复通知 URL 验证。 可忽略收到的验证消息。
- 需要预配 Azure 事件中心。
- 需要预配 Azure 密钥保管库。
设置 Azure 密钥保管库和 Azure 事件中心
本节将指导你完成所需的 Azure 服务设置。
Azure CLI 允许你在 Azure 中编写脚本并自动执行管理任务。 可以在本地计算机上安装 CLI 或直接从 Azure Cloud Shell 运行。
# --------------
# TODO: update the following values
#sets the name of the resource group
resourcegroup=rg-graphevents-dev
#sets the location of the resources
location='uk south'
#sets the name of the Azure Event Hubs namespace
evhamespacename=evh-graphevents-dev
#sets the name of the hub under the namespace
evhhubname=graphevents
#sets the name of the access policy to the hub
evhpolicyname=grapheventspolicy
#sets the name of the Azure KeyVault
keyvaultname=kv-graphevents
#sets the name of the secret in Azure KeyVault that will contain the connection string to the hub
keyvaultsecretname=grapheventsconnectionstring
# --------------
az group create --location $location --name $resourcegroup
az eventhubs namespace create --name $evhamespacename --resource-group $resourcegroup --sku Basic --location $location
az eventhubs eventhub create --name $evhhubname --namespace-name $evhamespacename --resource-group $resourcegroup --partition-count 2 --message-retention 1
az eventhubs eventhub authorization-rule create --name $evhpolicyname --eventhub-name $evhhubname --namespace-name $evhamespacename --resource-group $resourcegroup --rights Send
evhprimaryconnectionstring=`az eventhubs eventhub authorization-rule keys list --name $evhpolicyname --eventhub-name $evhhubname --namespace-name $evhamespacename --resource-group $resourcegroup --query "primaryConnectionString" --output tsv`
az keyvault create --name $keyvaultname --resource-group $resourcegroup --location $location --enable-soft-delete true --sku standard --retention-days 90
az keyvault secret set --name $keyvaultsecretname --value $evhprimaryconnectionstring --vault-name $keyvaultname --output none
graphspn=`az ad sp list --display-name 'Microsoft Graph Change Tracking' --query "[].appId" --output tsv`
az keyvault set-policy --name $keyvaultname --resource-group $resourcegroup --secret-permissions get --spn $graphspn --output none
keyvaulturi=`az keyvault show --name $keyvaultname --resource-group $resourcegroup --query "properties.vaultUri" --output tsv`
domainname=`az ad signed-in-user show --query 'userPrincipalName' | cut -d '@' -f 2 | sed 's/\"//'`
notificationUrl="EventHub:${keyvaulturi}secrets/${keyvaultsecretname}?tenantId=${domainname}"
echo "Notification Url:\n${notificationUrl}"
注意:此处提供的脚本与基于 Linux 的 命令行管理程序、Windows WSL 和 Azure Cloud Shell 兼容。 它要求在 Windows 命令行管理程序中运行某些更新。
创建订阅并接收通知
创建所需的 Azure 密钥保管库和 Azure 事件中心服务后,你将能够创建订阅并开始通过 Azure 事件中心接收更改通知。
创建订阅
使用事件中心订阅更改通知与使用 Webhook 订阅更改通知几乎相同。 主要区别在于前者依赖事件中心来传送通知。 所有其他操作都类似,包括创建订阅。
创建订阅期间的主要区别是 notificationUrl。 必须将其设置为 EventHub:https://<azurekeyvaultname>.vault.azure.net/secrets/<secretname>?tenantId=<domainname>
,并使用以下值:
azurekeyvaultname
- 创建密钥保管库时为其提供的名称。 可在 DNS 名称中找到它。secretname
- 创建密钥时为其提供的名称。 可在 Azure 密钥保管库的“密钥”页面上找到它。domainname
- 租户的名称;例如,consto.onmicrosoft.com 或 contoso.com。 由于此域将用于访问 Azure 密钥保管库,因此请务必使其与包含 Azure 密钥保管库的 Azure 订阅所使用的域相匹配。 若要获取此信息,可转到你创建的 Azure 密钥保管库的概述页面,并单击该订阅。 域名将显示在“目录”字段下。
接收通知
事件现在将通过事件中心传送到你的应用程序中。 有关详细信息,请参阅事件中心文档中的接收事件。
在应用程序中接收通知之前,你需要创建另一个具有“侦听”权限的共享访问策略并获取连接字符串,类似于配置 Azure 事件中心中列出的步骤。
注意:为应用程序创建单独的策略来侦听事件中心消息,而不是重用在 Azure 密钥保管库中设置的相同连接字符串。 这可确保解决方案的每个组件仅具有所需的权限,并遵循最低权限安全原则。
注意:应用程序会在每次创建新订阅时收到验证消息。 应忽略这些通知。 下面的示例表示验证消息的正文。
{
"value":[
{
"subscriptionId":"NA",
"subscriptionExpirationDateTime":"NA",
"clientState":"NA",
"changeType":"Validation: Testing client application reachability for subscription Request-Id: 522a8e7e-096a-494c-aaf1-ac0dcfca45b7",
"resource":"NA",
"resourceData":{
"@odata.type":"NA",
"@odata.id":"NA",
"id":"NA"
}
}
]
}
如果缺少Microsoft Graph 更改跟踪应用程序,会发生什么情况?
租户中可能缺少 Microsoft Graph 更改跟踪服务主体,这取决于租户的创建时间和管理操作。 要解决此问题,请在 Microsoft Graph 浏览器 中运行 以下查询。
查询详细信息: 0bf30f3b-4a52-48df-9a82-234910c4a086
是Microsoft Graph 更改跟踪应用程序的全局 appId。
POST https://graph.microsoft.com/v1.0/servicePrincipals
{
"appId": "0bf30f3b-4a52-48df-9a82-234910c4a086"
}
注意:运行此查询会导致访问被拒绝。 在这种情况下,请选择左上角帐户名称旁边的齿轮图标。 然后选择“选择权限”并搜索 Application.ReadWrite.All。 检查权限,然后选择“同意”。 同意此新权限后,再次运行请求。
注意:此 API 仅适用于学校或工作帐户,而不适用于个人帐户。 请确保使用域中的帐户登录。
或者,可以在 Microsoft Graph PowerShell 中使用 New-MgServicePrincipal cmdlet 添加缺少的服务主体。 下面是一个示例脚本。
Connect-Graph -Scopes "Application.ReadWrite.All"
New-MgServicePrincipal -AppId "0bf30f3b-4a52-48df-9a82-234910c4a086"
后续步骤
请参阅下面的 Azure 事件中心快速入门: