Azure Event Grid サブスクリプションの検証エラーのトラブルシューティング

Webhookエンドポイント向けにEvent Gridイベントサブスクリプションを作成する際、Event Gridはイベントを配信する前にあなたがそのエンドポイントの所有者であることを確認しなければなりません。 その検証ハンドシェイクが完了しなければ、サブスクリプション作成は失敗します。 この記事では、なぜハンドシェイクが失敗するのか、そしてそれをどう解決するかを解説します。

Symptoms

イベント購読を作成すると、以下のテキストに似たエラーメッセージが表示されます。

The attempt to validate the provided endpoint https://your-endpoint-here failed. For more details, visit https://aka.ms/esvalidation

このエラーは、Event GridがあなたのWebhookエンドポイントとの検証ハンドシェイクを完了できなかったことを示しており、サブスクリプションを作成しません。

Cause

Event Gridは、イベント配信を開始する前にWebhookエンドポイントの所有権を証明する必要があります。 この要件により、悪意のあるユーザーがエンドポイントにイベントを大量に送るのを防ぎます。 検証エラーは、Event Gridとエンドポイント間のハンドシェイクが成功しなかったときに発生します。 一般的な原因には、次のようなものがあります。

  • エンドポイントが、同期ハンドシェイク用の検証コードをエコーバックしないか、非同期(手動)ハンドシェイクで 200 OK を返していません。
  • エンドポイントの前に設置されたファイアウォール、Azure Application Gateway、またはウェブアプリケーションファイアウォール(WAF)が検証リクエストをブロックし、403 (Forbidden)を返します。
  • エンドポイントはCloudEvents v1.0スキーマを使用していますが、 HTTP OPTIONS の検証リクエストには応答しません。
  • エンドポイントは自己署名証明書を使っていますが、Event Gridは検証に対応していません。

検証ハンドシェイクの詳細な説明については、「 Event Gridイベントスキーマを用いたエンドポイント検証 」および CloudEventsスキーマを用いたエンドポイント検証を参照してください。

解決策1:Event Gridスキーマサブスクリプションの検証ハンドシェイクをテストする

サンプル のSubscriptionValidationEvent をウェブフックに送信し、応答を確認します:

  1. curlなどのツールを使って、サンプル SubscriptionValidationEvent リクエストボディとともにウェブフックのURLにHTTP POSTリクエストを送信します。
  2. もしあなたのウェブフックが同期ハンドシェアを実装しているなら、レスポンスで validationCode を返しているか確認してください。 HTTP 200 OKステータスコードを返送する必要があります。 Event Gridは HTTP 202 Accepted を有効な応答として認識せず、リクエストは30秒以内に完了しなければなりません。
  3. もしウェブフックが非同期(手動)ハンドシェイクを実装しているなら、エンドポイントが 200 OKを返すか確認してください。 その後、10分以内にイベントデータの validationUrl にGETリクエストを送信してハンドシェイクを完了します。 検証URLはポート553を使用しているので、そのポートがブロックされている場合はファイアウォールルールを更新してください。

こちらは送信できるJSONペイロード SubscriptionValidationEvent サンプルです:

[
  {
    "id": "aaaa0000-bb11-2222-33cc-444444dddddd",
    "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "subject": "",
    "data": {
      "validationCode": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
    },
    "eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
    "eventTime": "2018-01-25T22:12:19.4556811Z",
    "metadataVersion": "1",
    "dataVersion": "1"
  }
]

以下が予想される成功した対応です:

{
  "validationResponse": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
}

こちらが、Event Gridイベントスキーマを使うWebhookサブスクリプションの検証用に相当するcurlコマンドです:

curl -X POST -d '[{"id": "aaaa0000-bb11-2222-33cc-444444dddddd","topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","subject": "","data": {"validationCode": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"},"eventType": "Microsoft.EventGrid.SubscriptionValidationEvent","eventTime": "2018-01-25T22:12:19.4556811Z", "metadataVersion": "1","dataVersion": "1"}]' -H 'Content-Type: application/json' https://{your-webhook-url.com}

詳しくは「 Event Grid Event Schemaによるエンドポイント検証」をご覧ください。

解決策2:検証リクエストをブロックするファイアウォールやWAFルールを削除する

もしウェブフックが403 (Forbidden)に戻ったら、Azure Application Gatewayの背後にあるのかウェブアプリケーションのファイアウォールの背後にあるのかを確認してください。 もしそうなら、以下のファイアウォールルールを無効にして、HTTP POSTを再度実行してください:

  • 920300 (要求に accept ヘッダーがありません)
  • 942430(制限付きSQL文字異常検出(ARGS):特殊文字数を超える数(12))
  • 920230 (複数の URL エンコードが検出されました)
  • 942130(SQLインジェクション攻撃: SQL恒真式を検出)
  • 931130(リモートファイル包含(RFI)攻撃の可能性:ドメイン外参照またはリンク)

解決策3:CloudEventsスキーマサブスクリプションの検証

サブスクリプションがCloudEvents v1.0スキーマを使用している場合、Event Gridはサブスクリプション検証イベントの代わりにCloudEventsの不正防止を適用します。 エンドポイントは HTTP OPTIONS メソッドに応答し、 WebHook-Allowed-Origin ヘッダーを返さなければなりません。 詳しくは、 CloudEventsスキーマを用いたエンドポイント検証をご覧ください。

さらにサポートが必要な場合は、Event Grid の Microsoft Q&A ページで質問するか、サポート チケットを開いてください。