Получение уведомлений об изменениях через Центры событий Azure

Веб-перехватчики не подходят для получения уведомлений об изменениях в сценариях с высокой пропускной способностью или когда получатель не может предоставить общедоступный URL-адрес уведомления. В качестве альтернативы можно использовать Центры событий Azure.

Примеры сценариев с высокой пропускной способностью, в которых можно использовать Центры событий Azure, включают приложения, подписывающиеся на большой набор ресурсов, приложения, подписывающиеся на ресурсы, которые часто меняются, и мультитенантные приложения, которые подписываются на ресурсы в большом наборе организаций.

В этой статье описывается процесс управления подпиской Microsoft Graph и получение уведомлений об изменениях через Центры событий Azure.

Получение уведомлений об изменениях с помощью Центры событий Azure

Концентраторы событий Azure — это сервис приема и распространения популярных событий в режиме реального времени, созданный для масштабирования. Использование концентраторов событий Azure для получения уведомлений о изменениях отличается от веб-перехватчиков несколькими моментами, в том числе:

  • Не приходится полагаться на общедоступные URL-адреса уведомлений. Пакет SDK центров событий передает уведомления в приложение.
  • Нет необходимости отвечать на проверку URL-адреса уведомлений. Можно пропустить полученное сообщение о проверке.
  • Необходимо подготовить концентратор событий.
  • Необходимо подготовить Key Vault Azure.

Настройка хранилища Azure Key Vault и концентраторов событий 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 KeyVault и Центры событий Azure вы можете создать подписку на уведомления об изменениях и начать получать уведомления об изменениях через Центры событий Azure.

Создание подписки

Подписки на изменение уведомлений с помощью концентраторов событий почти идентичны уведомлениям об изменениях с помощью веб-перехватчиков. Разница main во время создания подписки — notificationUrl. Необходимо настроить его на EventHub:https://<azurekeyvaultname>.vault.azure.net/secrets/<secretname>?tenantId=<domainname> со следующими значениями:

  • azurekeyvaultname — название созданного хранилища ключей. Его можно найти в DNS-имени.
  • secretname — название созданного секрета. Его можно найти на странице Секреты в хранилище Azure Key Vault.
  • domainname — имя клиента; например, contoso.com или contoso.com. Так как этот домен используется для доступа к Key Vault Azure, важно, чтобы он соответствовал домену, используемому подпиской Azure, содержащей Key Vault Azure. Чтобы получить эти сведения, перейдите на страницу обзора созданного Key Vault Azure и выберите подписку. Имя домена выводится в поле Каталог.

Примечание.

Дублирование подписок запрещено. Если запрос подписки содержит те же значения для changeType и ресурса , что и в существующей подписке, запрос завершается ошибкой с кодом 409 ConflictHTTP и сообщением Subscription Id <> already exists for the requested combinationоб ошибке .

Получение уведомлений

Уведомления об изменениях теперь доставляются в приложение Центрами событий. Дополнительные сведения см. в статье Получение событий в документации по концентраторам событий.

Прежде чем получать уведомления в приложении, необходимо создать другую политику общего доступа с разрешением "Прослушивать" и получить строка подключения, как описано в разделе Настройка концентратора событий.

Совет

Создайте отдельную политику для приложения, которое прослушивает сообщения Центров событий вместо того, чтобы повторно использовать тот же строка подключения, заданный в Azure KeyVault. Это разделение соответствует принципу наименьших привилегий, гарантируя, что каждый компонент решения имеет только необходимые разрешения.

Обработка уведомлений о проверке

Приложение получает уведомления о проверке каждый раз, когда создает новую подписку. Эти уведомления следует пропустить. В приведенном ниже примере представлен текст сообщения о проверке.

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

Подписки на расширенные уведомления с большими полезными данными

Максимальный размер сообщений для Центров событий составляет 1 МБ. При использовании расширенных уведомлений могут потребоваться уведомления, превышающие это ограничение. Чтобы получать уведомления размером более 1 МБ через Центры событий, необходимо также добавить учетную запись хранения BLOB-объектов в запрос подписки.

Настройка хранилища и создание подписки

  1. Создайте учетную запись хранения.
  2. Создайте контейнер в учетной записи хранения и назначьте ему имя.
  3. Получите ключи доступа к учетной записи хранения или строка подключения.
  4. Добавьте строка подключения в хранилище ключей и присвойте ему имя. Это значение является именем секрета.
  5. Создайте или повторно создайте подписку, включив свойство blobStoreUrl в следующем синтаксисе: blobStoreUrl: "https://<azurekeyvaultname>.vault.azure.net/secrets/<secretname>?tenantId=<domainname>"

Получение расширенных уведомлений

Когда Центры событий получают полезные данные уведомления размером более 1 МБ, уведомление не содержит свойств resource, resourceData и encryptedContent , включенных в расширенные уведомления. Вместо этого уведомление содержит дополнительное свойствоPayloadStorageId с идентификатором, указывающим на большой двоичный объект в учетной записи хранения, где хранятся эти свойства.

Что делать, если приложение Microsoft Graph Отслеживание изменений отсутствует?

Субъект-служба Microsoft Graph Отслеживание изменений может отсутствовать в клиенте в зависимости от времени создания клиента и административных операций. Глобальный уникальный идентификатор appId субъекта-службы — это 0bf30f3b-4a52-48df-9a82-234910c4a086 , и вы можете выполнить следующий запрос, чтобы убедиться, что он существует в клиенте.

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

Если субъект-служба не существует, создайте его следующим образом. Для выполнения этой операции вызывающему приложению необходимо предоставить разрешение Application.ReadWrite.All .

Метод 1

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

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

Метод 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"
}