如何在 IIS 托管的网站中接收自定义 Webhook

本文关键字:自定义 Webhook 网站 IIS | 更新日期: 2023-09-27 18:33:53

这是我所做的:

1 - 我已经安装了nuget软件包:Microsoft.AspNet.WebHooks.Receivers.Custom 1.2.0-beta

2 - 我配置了WebApiConfig以接收自定义网络钩子:

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // Web API routes
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.InitializeReceiveCustomWebHooks(); //<<<---
    }

3 - 我在 web.config 中设置了一个密钥:

  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    ...
    <add key="MS_WebHookReceiverSecret_GenericJson" value="z=SECRET"/> 
  </appSettings>

4 - 我写了一个基本的接收器(带有通用钩子捕获(

public class GenericJsonWebHookHandler : WebHookHandler
{
    public static string dataReceived;
    public GenericJsonWebHookHandler()
    {
        this.Receiver = "genericjson";
    }
    public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
    {
        // Get JSON from WebHook
        JObject data = context.GetDataOrDefault<JObject>();
        if (context.Id == "i")
        {
            // do stuff
        }
        else if (context.Id == "z")
        {
            // do more stuff
            dataReceived = data.ToString();
            File.Create(@"c:'test'test1.txt");
        }
        return Task.FromResult(true);
    }
}

现在,人们会期望通过上述步骤,如果将 Webhook 发送器设置为将 Json 发布到 IIS 托管站点,它应该将通知捕获为 Json,将捕获的数据分配给dataReceived并将空白文本文件写入c:'test'test.txt - 事实并非如此

目前,我正在使用Team Foundation Server对此进行测试,以将webhook测试发送到https://mywebbhooksite.com:5050/?z=SECRET,并且成功了-但是,当我检查是否已创建该小测试文件时,它不存在。我也在主页上运行了一些 javascript 来轮询对dataReceived的任何更改,但我看到什么也没发生。

这里提到:我有一个远程调试器附加到w3wp.exe进程,ExecuteAsync和GenericJsonWebHookHandler上的断点不会被击中

为了捕获 webhook,是否需要完成任何其他特定设置?

如何在 IIS 托管的网站中接收自定义 Webhook

我采取了一种肮脏的方法,这种方法有效

我放弃了GenericJsonWebHookHandler,而是利用WebApiApplication中的Application_BeginRequest()事件来拦截发送方 Webhook 发布的数据。钩子的主体位于HttpRequest.Request.Inputstream,可以使用流阅读器打开。内容可以读取到string上并解析为 JObject(如果 webhook 请求发送的请求正文是 JSon(

这是我的代码。

    protected void Application_BeginRequest()
    {
        if (!Request.HttpMethod.Equals("post", StringComparison.InvariantCultureIgnoreCase)) {
            return; 
        }
        string documentContents;
        using (var receiveStream = Request.InputStream)
        {
            using (var readStream = new StreamReader(receiveStream, Encoding.UTF8))
            {
                documentContents = readStream.ReadToEnd();
            }
        }
        try
        {
            var json = JObject.Parse(documentContents);
            File.WriteAllLines(@"C:'test'keys.txt", new[] { documentContents, "'r'n", json.ToString() });
        }
        catch (Exception)
        {
             // do something
        }
    }

测试:

我进入我的网络钩子并开始了网络钩子测试。它使用 json 发布了请求。HTTP 200 是来自服务器的响应。

命中断点。HttpMethod接过了这个帖子。请求的InputStream被读取并存储在 documentContents 中。 JObject.Parse触发并将帖子的内容放入一个名为 jsonJObject变量中

json的内容已写入存储在服务器上的文件中 - 指示已正确接收请求。

为了安全起见,我计划做些什么来改善这一点

出于安全目的,我将加密我在 web.config 中设置的密钥,

并在 web.config 中设置加密密钥,然后将其与传入的 URL 查询参数(使用相同的加密算法(匹配,以查看该密钥是否存在且完全相同