简体   繁体   English

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

[英]How do I receive a custom webhook in an IIS hosted website?

Here is what I have done:这是我所做的:

1 - I have installed the nuget package: Microsoft.AspNet.WebHooks.Receivers.Custom 1.2.0-beta 1 - 我已经安装了 nuget 包:Microsoft.AspNet.WebHooks.Receivers.Custom 1.2.0-beta

2 - I configured the WebApiConfig to receive custom webhooks: 2 - 我将WebApiConfig配置为接收自定义 webhook:

    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 - I set up a secret key in the web.config: 3 - 我在 web.config 中设置了一个密钥:

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

4 - I have written a basic receiver (with the genericjson hook capture) 4 - 我写了一个基本的接收器(使用 genericjson 钩子捕获)

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);
    }
}

Now, one would expect with the steps above, if a webhook sender is set up to publish Json to the IIS hosted site, it should capture the notification as Json, assign the captured data to dataReceived and write a blank text file to c:\\test\\test.txt - which was not the case现在,通过上述步骤,如果一个 webhook 发送者被设置为将 Json 发布到 IIS 托管站点,它应该将通知捕获为 Json,将捕获的数据分配给dataReceived并将一个空白文本文件写入c:\\test\\test.txt -事实并非如此

Currently, I am testing this using Team Foundation Server to send a webhook test to https://mywebbhooksite.com:5050/?z=SECRET , and It succeeds - however, when I check if that little test file has been created, it's not there.目前,我正在使用 Team Foundation Server 向https://mywebbhooksite.com:5050/?z=SECRET发送一个 webhook 测试来测试它,并且它成功了- 但是,当我检查是否已经创建了那个小测试文件时,它是不在那里。 I also have some javascript running on the homepage to poll for any changes to dataReceived but I see nothing is happening.我还在主页上运行了一些 javascript 来轮询dataReceived任何更改,但我没有看到任何事情发生。

Mentioning here: I have a remote debugger attached to the w3wp.exe process, the breakpoint on ExecuteAsync and GenericJsonWebHookHandler does not get hit这里提到:我有一个远程调试器附加到 w3wp.exe 进程,ExecuteAsync 和 GenericJsonWebHookHandler 上的断点没有被命中

Are there any other specific setup that needs to be done in order for the webhook to be captured?为了捕获 webhook,是否还需要进行任何其他特定设置?

I took a filthy approach which works我采取了一种有效的肮脏方法

I ditched GenericJsonWebHookHandler and instead I have utilized the Application_BeginRequest() event in WebApiApplication instead to intercept data posted by the sender Webhook.我抛弃GenericJsonWebHookHandler和代替我已利用Application_BeginRequest()在事件WebApiApplication代替张贴由发送方网络挂接截距数据。 The body of the hook resides in the HttpRequest.Request.Inputstream , which can be opened using a streamreader.钩子的主体位于HttpRequest.Request.Inputstream ,可以使用流读取器打开它。 The contents can be read onto a string and parsed into a JObject (if the body of the request sent by the webhook Request is JSon)可以将内容读入string并解析为 JObject(如果 webhook Request 发送的请求主体为 JSon)

Here is my code.这是我的代码。

    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
        }
    }

The test:考试:

I went onto my webhook and commenced a webhook test.我进入了我的 webhook 并开始了 webhook 测试。 It published the request with the json.它用json发布了请求。 HTTP 200 was the response from the server. HTTP 200 是来自服务器的响应。

Breakpoint was hit.断点被击中。 The HttpMethod picked up the post. HttpMethod接受了这个职位。 The Request's InputStream was read and stored in documentContents .请求的InputStream被读取并存储在documentContents JObject.Parse fired off and put the contents of the post into a JObject variable called json JObject.Parse触发并将帖子的内容放入名为jsonJObject变量中

The contents of json was written to a file stored on the server - indicating that the request was properly received. json的内容被写入存储在服务器上的文件 - 表明请求已正确接收。

What I plan to do to improve this, for security我打算做什么来改善这一点,为了安全

For security purposes, I will encrypt the secret key I set in the web.config, and set the encrypted key in the web.config instead, and after that match it with the incoming URL Query parameters (using the same encryption algorithm) to see if that key is present and exactly the same为了安全起见,我将我在 web.config 中设置的秘钥进行加密,并在 web.config 中设置加密的密钥,然后将其与传入的 URL Query 参数(使用相同的加密算法)进行匹配以查看如果该键存在且完全相同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM