Validação de ponto de extremidade com esquema de eventos da Grade de Eventos

Webhooks são uma dentre várias maneiras de receber eventos da Grade de Eventos do Azure. Quando um novo evento está pronto, o serviço Grade de Eventos faz o POST de uma solicitação HTTP para o ponto de extremidade configurado com as informações do evento no corpo da solicitação.

Como muitos outros serviços que dão suporte a webhooks, a Grade de Eventos do Azure exige que você comprovar a "propriedade" de seu ponto de extremidade do Webhook antes de começar a entrega de eventos para esse ponto de extremidade. Esse requisito impede que um usuário mal-intencionado inunde seu ponto de extremidade com eventos.

Validação de ponto de extremidade com eventos da Grade de Eventos

Quando você usa qualquer um dos seguintes três serviços do Azure, a infraestrutura do Azure trata automaticamente essa validação:

Se você estiver usando qualquer outro tipo de ponto de extremidade, como uma função do Azure baseada no gatilho HTTP, o código do ponto de extremidade precisará participar de um handshake de validação com o EventGrid. A Grade de Eventos dá suporte a duas maneiras de validar a assinatura.

  • Handshake síncrono: No momento da criação da assinatura, a Grade de Eventos posta um Evento de Validação de Assinatura para o ponto de extremidade de destino. O esquema desse evento é semelhante a qualquer outro evento da Grade de Eventos. A parte de dados desse evento inclui um validationCode propriedade. Seu aplicativo verifica se a solicitação de validação é para uma assinatura de evento esperada e retorna o código de validação na resposta de forma síncrona. Esse mecanismo de handshake é compatível com todas as versões da Grade de Eventos.

  • Handshake assíncrono: em determinados casos, você não pode retornar o validationCode em resposta de forma síncrona. Por exemplo, se você usar um serviço que não é da Microsoft (como Zapier ou IFTTT), não será possível responder programaticamente com o código de validação.

    A Grade de Eventos dá suporte a um handshake de validação manual. Se você estiver criando uma inscrição de evento com um SDK ou ferramenta que usa a versão da API 2018-05-01-preview ou posterior, a Grade de Eventos envia uma propriedade validationUrl na parte de dados do evento de validação da assinatura. Para concluir o handshake, localize essa URL nos dados do evento e faça uma solicitação GET para ele. Você pode usar um cliente REST ou o navegador da web.

    A URL fornecida é válida por 10 minutos. Durante esse tempo, o estado de fornecimento da assinatura do evento é AwaitingManualAction. Se você não concluir a validação manual em 10 minutos, o estado de provisionamento será definido como Failed. Você terá que criar a assinatura do evento novamente antes de iniciar a validação manual.

    Esse mecanismo de autenticação também exige que o ponto de extremidade do webhook retorne um código de status HTTP 200 para que ele saiba que o POST do evento de validação foi aceito antes que ele possa ser colocado no modo de validação manual. Em outras palavras, se o ponto de extremidade retornar 200, mas não retornar uma resposta de validação de forma síncrona, o modo será transferido para o modo de validação manual. Se houver um GET na URL de validação dentro de 10 minutos, o handshake de validação será considerado bem-sucedido.

Observação

Não há suporte para o uso de certificados autoassinados para validação. Em vez disso, use um certificado assinado de uma AC (autoridade de certificação) comercial.

Detalhes da validação

  • No momento da criação/atualização da assinatura, a Grade de Eventos posta um Evento de Validação de Assinatura para o ponto de extremidade de destino.
  • O evento contém um valor de cabeçalho aeg-event-type: SubscriptionValidation.
  • O corpo do evento tem o mesmo esquema que outros eventos da Grade de Eventos.
  • A propriedade eventType do evento é Microsoft.EventGrid.SubscriptionValidationEvent.
  • A propriedade validationCode do evento inclui uma propriedade data com uma cadeia de caracteres gerada aleatoriamente. Por exemplo, validationCode: acb13….
  • Os dados do evento também incluem uma propriedade validationUrl com uma URL para validar manualmente a assinatura.
  • A matriz contém apenas o evento de validação. Outros eventos serão enviados em uma solicitação separada, após retornar o código de validação.
  • Os SDKs do plano de dados da Grade de Eventos têm classes correspondentes para os dados de evento de validação de assinatura e a resposta de validação de assinatura.

Um SubscriptionValidationEvent de exemplo é mostrado no exemplo a seguir:

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

Para provar a propriedade do ponto de extremidade, retorne o código de validação na propriedade validationResponse, conforme mostrado no seguinte exemplo:

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

E siga uma destas etapas:

  • Você deve retornar um código de status de resposta HTTP 200 OK. HTTP 202 Accepted não é reconhecido como uma resposta de validação de assinatura de Grade de Eventos válida. A solicitação HTTP deve ser concluída dentro de 30 segundos. Se a operação não terminar em 30 segundos, ela será cancelada e você poderá tentar novamente após cinco segundos. Se todas as tentativas falharem, elas serão tratadas como um erro de handshake de validação.

    O fato de o aplicativo estar preparado para manipular e retornar o código de validação indica que você criou a assinatura do evento e deve receber o evento. Imagine o cenário em que não há suporte para validação de handshake e um hacker consegue saber a URL do aplicativo. O hacker pode criar um tópico e uma assinatura do evento com a URL do aplicativo e começar a realizar um ataque de DoS ao aplicativo enviando muitos eventos. A validação do handshake impede que isso aconteça.

    Imagine que você já tenha a validação implementada no aplicativo, pois criou suas próprias assinaturas do evento. Mesmo que um hacker crie uma assinatura do evento com a URL do aplicativo, a implementação correta do evento de solicitação de validação verificará o cabeçalho aeg-subscription-name na solicitação, para confirmar se é uma assinatura do evento que você reconhece.

    Mesmo após a implementação correta do handshake, um hacker pode inundar o aplicativo (ele já validou a assinatura do evento) replicando uma solicitação que parece ser proveniente da Grade de Eventos. Para evitar isso, você deve proteger o webhook com a autenticação do Microsoft Entra. Para obter mais informações, confira Entregar eventos aos pontos de extremidade protegidos do Microsoft Entra.

  • Ou então, você pode validar a assinatura manualmente, enviando uma solicitação GET para a URL de validação. A inscrição do evento permanece em um estado pendente até que validada. A URL de validação usa a porta 553. Se as regras de firewall bloquearem a porta 553, será necessário atualizar as regras para obter um handshake manual bem-sucedido.

    Na validação do evento de validação da assinatura, se você identificar que não é uma assinatura do evento para a qual você está esperando eventos, você não retornará uma resposta 200 ou nenhuma resposta. Portanto, a validação falhará.

Para obter um exemplo de lidar com o handshake de validação de assinatura, consulte uma amostra C#.

Consulte o seguinte artigo para saber como solucionar problemas de validações de assinatura de evento: Solucionar problemas de validações de assinatura de evento.