Webhook のイベント配信

Webhook は、Azure Event Grid からイベントを受信する多数ある方法の 1 つです。 新しいイベントの準備ができるたびに、Event Grid サービスは、本文にイベント情報が含まれる HTTP 要求を構成済み HTTP エンドポイントに POST します。

Webhook をサポートする他の多くのサービスと同様に、Event Grid を使用するには、Webhook エンドポイントへのイベントの配信を開始する前に、そのエンドポイントの所有権を証明する必要があります。 この要件により、悪意のあるユーザーはエンドポイントをイベントで氾濫させることができなくなります。

Event Grid イベントを使用したエンドポイントの検証

次の 3 つの Azure サービスのいずれかを使っているときは、この検証は Azure インフラストラクチャによって自動的に処理されます。

他の種類のエンドポイント (HTTP トリガー ベースの Azure 関数など) を使用する場合は、エンドポイントのコードが Event Grid を使用した検証ハンドシェイクに参加する必要があります。 Event Grid では、サブスクリプションを検証する 2 つの方法がサポートされています。

  • 同期ハンドシェイク: イベント サブスクリプションの作成時に、Event Grid はサブスクリプション検証イベントをエンドポイントに送信します。 このイベントのスキーマは、他の Event Grid イベントに似ています。 このイベントのデータ部分には validationCode プロパティが含まれます。 アプリケーションにより、検証の要求が、想定されるイベント サブスクリプションの対象として確認されると、検証コードを応答で同期的に返します。 このハンドシェイク メカニズムは、すべての Event Grid バージョンでサポートされます。

  • 非同期ハンドシェイク: 応答で validationCode を同期的に返さない場合があります。 たとえば、サード パーティのサービス (Zapier または IFTTT など) を利用する場合、検証コードへの応答は、プログラムによって行うことができません。

    手動の検証ハンドシェイクが Event Grid によってサポートされます。 API バージョン 2018-05-01-preview 以降を使用する SDK またはツールでイベント サブスクリプションを作成すると、Event Grid によって、サブスクリプション検証イベントのデータ部分で validationUrl プロパティが送信されます。 ハンドシェイクを完了するには、イベント データ内でその URL を探し、そこへ GET 要求を実行します。 REST クライアントと Web ブラウザーのどちらでも使用できます。

    指定された URL は 10 分間有効です。 この期間、イベント サブスクリプションのプロビジョニング状態は AwaitingManualAction になります。 手動による検証を 10 分以内に完了しなかった場合、プロビジョニング状態には Failed が設定されます。 手動による検証を始める前に、もう一度イベント サブスクリプションを作成する必要があります。

    この認証メカニズムではまた、webhook エンドポイントが 200 の HTTP 状態コードを返すことも必要です。それにより、手動検証モードに設定される前に、検証イベントの POST が受け付けられたことを認識できるようになります。 つまり、エンドポイントが 200 を返しても、同期的に検証の応答を戻さないと、モードは手動検証モードに移行されます。 10 分以内に検証 URL に GET が存在した場合、検証ハンドシェイクは成功したと見なされます。

Note

検証に自己署名証明書を使用することは、サポートされていません。 代わりに、商用証明機関 (CA) からの署名入り証明書を使用します。

検証の詳細

  • イベント サブスクリプションの作成時または更新時に、Event Grid はサブスクリプション検証イベントをターゲット エンドポイントに投稿します。
  • このイベントには、ヘッダー値 aeg-event-type: SubscriptionValidation が含まれています。
  • イベント本文のスキーマは、他の Event Grid イベントと同じです。
  • このイベントの eventType プロパティは Microsoft.EventGrid.SubscriptionValidationEvent です。
  • このイベントの data プロパティには、ランダムに生成された文字列を含む validationCode プロパティが含まれています。 たとえば、「 validationCode: acb13… 」のように入力します。
  • イベント データには、validationUrl プロパティと、サブスクリプションを手動で検証するための URL も含まれます。
  • 配列には、検証イベントのみが含まれています。 その他のイベントは、検証コードをエコーで返した後、別の要求で送信されます。
  • EventGrid データ プレーン SDK には、サブスクリプション検証イベント データとサブスクリプション検証の応答に対応するクラスがあります。

SubscriptionValidationEvent の例を以下に示します。

[
  {
    "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66",
    "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "subject": "",
    "data": {
      "validationCode": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6",
      "validationUrl": "https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/myeventsub/validate?id=0000000000-0000-0000-0000-00000000000000&t=2022-10-28T04:23:35.1981776Z&apiVersion=2018-05-01-preview&token=1A1A1A1A"
    },
    "eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
    "eventTime": "2022-10-28T04:23:35.1981776Z",
    "metadataVersion": "1",
    "dataVersion": "1"
  }
]

エンドポイントの所有権を証明するには、次の例に示すように、validationResponse プロパティで検証コードをエコーで返します。

{
  "validationResponse": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6"
}

次に、次のいずれかの手順を実行します。

  • HTTP 200 OK 応答状態コードを返す必要があります。 HTTP 202 Accepted は、有効な Event Grid サブスクリプション検証の応答として認識されません。 HTTP 要求は 30 秒以内に完了する必要があります。 操作が 30 秒以内に完了しない場合、操作は取り消され、5 秒後に再試行される場合があります。 すべての試行が失敗した場合、検証ハンドシェイク エラーとして扱われます。

    アプリケーションが処理して検証コードを返す準備が整っているということは、イベント サブスクリプションを作成し、イベントの受信が想定されているということです。 ハンドシェイク検証がサポートされておらず、ハッカーにアプリケーションの URL を知られてしまうシナリオを想像してみてください。 ハッカーは、アプリケーションの URL を使用してトピックとイベント サブスクリプションを作成し、多数のイベントを送信してアプリケーションに対する DoS 攻撃の実行を開始できます。 ハンドシェイクの検証によって、この発生を防止します。

    独自のイベント サブスクリプションを作成したために、アプリに検証が既に実装されているとします。 ハッカーがアプリの URL を使用してイベント サブスクリプションを作成しても、検証要求イベントが正しく実装されていると、要求内の aeg-subscription-name ヘッダーがチェックされて、それが認識するイベント サブスクリプションであることが確認されます。

    その正しいハンドシェイクの実装後でも、ハッカーは Event Grid から送信されたようにみえる要求をレプリケートすることで、アプリ (イベント サブスクリプションを既に検証済み) にフラッド攻撃を実行できます。 これを回避するには、Microsoft Entra 認証を使用して Webhook をセキュリティで保護する必要があります。 詳細については、「Microsoft Entra で保護されたエンドポイントにイベントを配信する」を参照してください。

  • または、検証 URL に GET 要求を手動で送信して、サブスクリプションを検証することができます。 イベント サブスクリプションは、検証されるまで保留状態にとどまります。 検証 URL ではポート 553 が使用されます。 ファイアウォール規則によってポート 553 がブロックされている場合、手動ハンドシェイクを正常に行うには、規則を更新する必要があります。

    サブスクリプション検証イベントの検証で、それがイベントを想定しているイベント サブスクリプションではないことが特定された場合、200 応答が返されないか、応答がまったくありません。 そのため、検証は失敗します。

サブスクリプション検証ハンドシェイクの処理の例については、C# のサンプルに関するページをご覧ください。

CloudEvents v1.0 を使用したエンドポイントの検証

CloudEvents v1.0 では、HTTP OPTIONS メソッドを使用して、独自の不正使用防止のセマンティクスが実装されます。 詳細については、 こちらを参照してください。 出力に CloudEvents スキーマを使用すると、Event Grid では、Event Grid の検証イベント メカニズムではなく CloudEvents v1.0 の不正使用防止が使用されます。

イベント スキーマの互換性

トピックが作成されると、受信イベント スキーマが定義されます。 また、サブスクリプションが作成されると、送信イベント スキーマが定義されます。 次の表に、サブスクリプションの作成時に使用できる互換性を示します。

受信イベント スキーマ 送信イベント スキーマ サポートされています
Event Grid スキーマ Event Grid スキーマ はい
Cloud Events v1.0 スキーマ はい
カスタムの入力スキーマ No
Cloud Events v1.0 スキーマ Event Grid スキーマ No
Cloud Events v1.0 スキーマ はい
カスタムの入力スキーマ No
カスタムの入力スキーマ Event Grid スキーマ はい
Cloud Events v1.0 スキーマ はい
カスタムの入力スキーマ はい

次のステップ

イベント サブスクリプション検証をトラブルシューティングする方法については、イベント サブスクリプション検証のトラブルシューティングに関する記事を参照してください。