Azure事件网格订阅WebHook验证因Cloud Events Schema v1.0而失败

时间:2020-01-07 04:30:25

标签: azure-functions azure-eventgrid cloudevents

尝试创建WebHook订阅时,部署无法验证Azure Events中针对Cloud Events v1.0架构的HTTP触发器。我已经确认我的终结点使用适当的响应来处理验证握手。我的事件网格域正在使用Cloud Events v1.0架构。似乎在验证过程中甚至没有调用我的Azure函数,因为该函数的控制台中没有输出。

这对Cloud Events v1.0和WebHooks有用吗?

部署失败,并出现以下错误:{“代码”:“ URL验证”,“消息”:“尝试验证提供的端点xxxxx失败。”}

这是我的代码:

[FunctionName("ProcessEvent")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            var requestmessage = await req.Content.ReadAsStringAsync();
            var message = JToken.Parse(requestmessage);

            if (message.Type == JTokenType.Array)
            {
                // If the request is for subscription validation, send back the validation code.
                if (string.Equals((string)message[0]["eventType"],
                "Microsoft.EventGrid.SubscriptionValidationEvent",
                System.StringComparison.OrdinalIgnoreCase))
                {
                    log.LogInformation("Validate request received");

                    var myObj = new { validationResponse = message[0]["data"]["validationCode"].ToString() };
                    var jsonToReturn = JsonConvert.SerializeObject(myObj);

                    return new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent(jsonToReturn, Encoding.UTF8, "application/json")
                    };
                }
            }
            else
            {
                // The request is not for subscription validation, so it's for an event.
                // CloudEvents schema delivers one event at a time.
                log.LogInformation($"Source: {message["source"]}");
                log.LogInformation($"Time: {message["eventTime"]}");
                log.LogInformation($"Event data: {message["data"].ToString()}");
            }

            return req.CreateResponse(HttpStatusCode.OK);
}

1 个答案:

答案 0 :(得分:1)

使用CloudEvents v1.0进行的端点验证与此处所述的交付模式(例如, EventGridSchema CustomInputSchema )不同。

出于测试目的,可以将 Webhook.site 用作端点处理程序。 以下屏幕显示了EventGrid发送的 OPTIONS 调用以进行验证握手:

enter image description here

请注意,端点处理程序的地址必须为 https 。 如上图所示,有一个 webhook-request-callback 标头。复制其值a并将其放在浏览器中并发送。您应该获得以下文本:

"Webhook succesfully validated as a subscription endpoint."

从现在开始,Webhook可以收到通知消息,请参见以下屏幕:

enter image description here

如您所见,CloudEvent v1.0需要实现endpoint validation的HTTP OPTIONS响应。以下是此实现的示例:

string webhookcallback = req.Headers.GetValues("WebHook-Request-Callback")?.FirstOrDefault()?.Trim();       
if(string.IsNullOrEmpty(webhookcallback) == false)
{
    var hrm2 = req.CreateResponse(HttpStatusCode.OK);
    hrm2.Headers.Add("WebHook-Request-Origin", "eventgrid.azure.net");
    hrm2.Headers.Add("WebHook-Allowed-Rate", "120");

    System.Threading.ThreadPool.QueueUserWorkItem(delegate (object state)
    {
        Task.Delay(5000).Wait();
        using(var client = new HttpClient())
        {
            log.Warning($"{client.GetAsync(webhookcallback).Result.Content.ReadAsStringAsync().Result}");
        }
    });

    return hrm2;
}

将上述代码片段放入您的函数中。请注意,调用 WebHook-Request-Callback 地址不在 OPTIONS调用之内,必须在OK响应返回EventGrid后再进行,因此,一些延迟和后台线程。如果EventGrid在OPTIONS调用中接受此调用,那就太好了。