Azure Event Hubsを介して変更通知を受け取る

Webhook は、高スループットのシナリオで変更通知を受信したり、受信者が公開されている通知 URL を公開できない場合に適していない場合があります。 別の方法として、Azure Event Hubsを使用できます。

高スループットシナリオの良い例としては、大規模なリソース セットをサブスクライブするアプリケーション、高頻度で変更されるリソースをサブスクライブするアプリケーション、大規模な組織のリソースをサブスクライブするマルチテナント アプリケーションなどがあります。

この記事では、Microsoft Graph サブスクリプションを管理するプロセスと、Azure Event Hubsを通じて変更通知を受信する方法について説明します。

Azure Event Hubs を使用した変更通知の受け取り

Azure Event Hubs は、一般的なリアルタイム イベントの取り込みと配布サービスであり、規模に合わせて構築されています。 従来の Webhook の代わりに Azure Event Hubs を使用して変更通知を受け取ることができます。
変更通知の受け取りに Azure Event Hub を使用する方法は、次のような点で Webhook とは異なります。

  • 公開されている通知 URL には依存しません。 Event Hubs SDK は、通知をアプリケーションにリレーします。
  • 通知 URL の検証に返信する必要はありません。 受信した検証メッセージは無視してかまいません。
  • Azure イベント ハブを用意する必要があります。
  • Azure Key Vault をプロビジョニングする必要があります。

Azure KeyVault および 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 KeyVault および Azure Event Hubs サービスを作成すると、サブスクリプションを作成し、Azure Event Hubs を介して変更通知を受け取ることができます。

サブスクリプションの作成

Event Hubs を使用した変更通知のサブスクリプションは、Webhook を使用した変更通知とほぼ同じです。 主な違いは、通知の配信を Event Hubs に依存していることです。 サブスクリプションの作成を含む他のすべての作業が似ています。

サブスクリプションを作成するときの主な違いは、notificationUrl です。 次の値を使用して、この値を EventHub:https://<azurekeyvaultname>.vault.azure.net/secrets/<secretname>?tenantId=<domainname> に設定する必要があります。

  • azurekeyvaultname - キー コンテナーを作成したときに付けた名前。 DNS 名で見つけることができます。
  • secretname - シークレットを作成したときに付けた名前。 Azure Key Vault の [シークレット] ページで見つけることができます。
  • domainname - テナントの名前 (例: consto.onmicrosoft.com または contoso.com)。 このドメインは Azure Key Vault へのアクセスに使用されるため、Azure Key Vault を保持する Azure サブスクリプションで使用されるドメインと一致することが重要です。 この情報を取得するには、作成した Azure Key Vault の概要ページに移動し、サブスクリプションをクリックします。 ドメイン名がディレクトリ フィールドの下に表示されます。

通知の受け取り

イベントは、Event Hubs によってアプリケーションに配信されます。 詳細については、Event Hubs ドキュメントで「イベントの受け取り」を参照してください。

アプリケーションで通知を受け取るには、まず、「Azure イベント ハブの構成」に記載されている手順のように、「待ち受け」権限を持つ他の共有アクセス ポリシーを作成し、接続文字列を取得する必要があります。

注意: Azure KeyVault で設定したものと同じ接続文字列を再利用する代わりに、Event Hubs のメッセージを待ち受けるアプリケーションの別のポリシーを作成します。 これにより、ソリューションの各コンポーネントは、必要なアクセス許可のみを持ち、最小限のアクセス許可のセキュリティ プリンシパルに従います。

注: アプリケーションは、新しいサブスクリプションが作成されるたびに検証メッセージを受け取ります。 これらの通知は無視してください。 次の例は、検証メッセージの本文を表します。

 {
    "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 Explorer次のクエリを実行します。

クエリの詳細: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 コマンドレットを使用して、不足しているサービス プリンシパルを追加することもできます。 スクリプトの例を次に示します。

Connect-Graph -Scopes "Application.ReadWrite.All"
New-MgServicePrincipal -AppId "0bf30f3b-4a52-48df-9a82-234910c4a086"

次の手順

次の Azure Event Hubs クイック スタートをご覧ください。