Receber notificações de alteração por meio de Hubs de Eventos do Azure

Os webhooks não são adequados para receber notificações de alteração em cenários de alta taxa de transferência ou quando o receptor não pode expor uma URL de notificação disponível publicamente. Como alternativa, você pode usar Hubs de Eventos do Azure.

Exemplos de cenários de alta taxa de transferência em que você pode usar Hubs de Eventos do Azure incluem aplicativos que assinam um grande conjunto de recursos, aplicativos que assinam recursos que mudam com frequência e aplicativos multilocatários que assinam recursos em um grande conjunto de organizações.

O artigo orienta você durante o processo de gerenciamento de sua assinatura do Microsoft Graph e como receber notificações de alteração por meio de Hubs de Eventos do Azure.

Usando Hubs de Eventos do Azure para receber a notificação de alteração

Os Hubs de Eventos do Azure é um serviço popular de inclusão e distribuição de eventos em tempo real, compilado para ser dimensionável. Usar os Hubs de Eventos do Azure para receber notificações de alteração difere do webhooks em algumas maneiras, incluindo:

  • Você não depende de URLs com notificações publicamente expostas. O SDK dos Hubs de Eventos retransmite as notificações para seu aplicativo.
  • Não é necessário responder à validação da URL de notificação. Você pode ignorar a mensagem de validação recebida.
  • Você precisa provisionar um hub de eventos.
  • Você precisa provisionar um Key Vault do Azure ou adicionar o serviço de Controle de Alterações do Microsoft Graph à função de Remetente de Dados no Hub de Eventos.

Configurar a autenticação Hubs de Eventos do Azure

A CLI do Azure permite que você faça script e automatize tarefas administrativas no Azure. O CLI pode ser instalado em seu computador local ou ser executado diretamente a partir do 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}"

Nota: O script fornecido aqui é compatível com shells baseados em Linux, Windows WSL e Cloud Shell do Azure. Ele requer algumas atualizações para serem executadas em shells do Windows.

Create a assinatura e receber notificações

Depois de criar os serviços necessários do Azure KeyVault e Hubs de Eventos do Azure, agora você pode criar sua assinatura de notificação de alterações e começar a receber notificações de alteração por meio de Hubs de Eventos do Azure.

Create a assinatura

A criação de uma assinatura para receber notificações de alteração com Hubs de Eventos é quase idêntica à criação da assinatura do webhook, mas com alterações importantes na propriedade notificationUrl . Primeiro examine as etapas de criação da assinatura do webhook antes de continuar.

Na criação da assinatura, o notificationUrl deve apontar para o local dos Hubs de Eventos.

Se você estiver usando Key Vault, a propriedade notificationUrl será semelhante a esta: EventHub:https://<azurekeyvaultname>.vault.azure.net/secrets/<secretname>?tenantId=<domainname>, com os seguintes valores:

  • azurekeyvaultname - O nome que você atribuiu ao cofre de chaves quando o criou. Pode ser encontrado no nome DNS.
  • secretname - O nome que você atribuiu ao segredo quando o criou. Pode ser encontrado na página Segredos. do Azure Key Vault.
  • domainname - O nome do locatário; por exemplo, contoso.com. Como esse domínio é usado para acessar o Azure Key Vault, é importante que ele corresponda ao domínio usado pela assinatura do Azure que contém o Key Vault do Azure. Para obter essa informação, você pode ir para a página de visão geral do Azure Key Vault que você criou e clique na assinatura. O nome de domínio é exibido sob o campo Diretório.

Observação

Assinaturas duplicadas não são permitidas. Quando uma solicitação de assinatura contém os mesmos valores para changeType e recurso que uma assinatura existente contém, a solicitação falha com um código 409 Conflictde erro HTTP e a mensagem de Subscription Id <> already exists for the requested combinationerro .

Receber notificações

As notificações de alteração agora são entregues ao seu aplicativo pelos Hubs de Eventos. Para detalhes, confira Recebendo eventos na documentação Hubs de Eventos.

Antes de receber as notificações em seu aplicativo, você precisa criar outra política de acesso compartilhado com uma permissão "Escutar" e obter o cadeia de conexão, semelhante às etapas listadas em Configurar o hub de eventos.

Dica

Create uma política separada para o aplicativo que escuta mensagens dos Hubs de Eventos em vez de reutilização do mesmo cadeia de conexão que você definiu no Azure KeyVault. Essa separação segue o princípio de privilégio mínimo, garantindo que cada componente da solução tenha apenas as permissões necessárias.

Manipulando notificações de validação

Seu aplicativo recebe notificações de validação sempre que cria uma nova assinatura. Você deve ignorar essas notificações. O exemplo a seguir representa o corpo de uma mensagem de validação.

 {
    "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"
            }
        }
    ]
}

Assinaturas para notificações avançadas com grandes cargas

O tamanho máximo da mensagem para Hubs de Eventos é de 1 MB. Ao usar notificações avançadas, você pode esperar notificações que excedam esse limite. Para receber notificações maiores que 1 MB por meio dos Hubs de Eventos, você também deve adicionar uma conta de armazenamento de blobs à sua solicitação de assinatura.

Configurar o armazenamento e criar uma assinatura

  1. Create uma conta de armazenamento.
  2. Create um contêiner na conta de armazenamento e atribua-lhe um nome.
  3. Recupere as chaves ou cadeia de conexão de acesso da conta de armazenamento.
  4. Adicione o cadeia de conexão ao cofre de chaves e dê-lhe um nome. Esse valor é o nome secreto.
  5. Create ou recriar sua assinatura, agora incluindo a propriedade blobStoreUrl na seguinte sintaxe:blobStoreUrl: "https://<azurekeyvaultname>.vault.azure.net/secrets/<secretname>?tenantId=<domainname>"

Receber notificações avançadas

Quando os Hubs de Eventos recebem uma carga de notificação maior que 1 MB, a notificação não contém as propriedades resource, resourceData e encryptedContent incluídas em notificações avançadas. Em vez disso, a notificação contém uma propriedade AdicionalPayloadStorageId com uma ID que aponta para o blob em sua conta de armazenamento em que essas propriedades são armazenadas.

E se o aplicativo Controle de Alterações do Microsoft Graph estiver ausente?

O Microsoft Graph Controle de Alterações entidade de serviço pode estar ausente do locatário, dependendo de quando o locatário foi criado e operações administrativas. O appId globalmente exclusivo da entidade de serviço é 0bf30f3b-4a52-48df-9a82-234910c4a086 e você pode executar a consulta a seguir para confirmar se ela existe no locatário.

GET https://graph.microsoft.com/v1.0/servicePrincipals(appId='0bf30f3b-4a52-48df-9a82-234910c4a086')

Se a entidade de serviço não existir, crie-a da seguinte maneira. Você deve conceder ao aplicativo de chamada a permissão Application.ReadWrite.All para executar essa operação.

Método 1

POST https://graph.microsoft.com/v1.0/servicePrincipals
Content-type: application/json

{
    "appId": "0bf30f3b-4a52-48df-9a82-234910c4a086"
}

Método 2

POST https://graph.microsoft.com/v1.0/servicePrincipals(appId='0bf30f3b-4a52-48df-9a82-234910c4a086')
Content-type: application/json
Prefer: create-if-missing

{
    "displayName": "Microsoft Graph Change Tracking"
}