Krohn February 2016

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

2 - I configured the WebApiConfig to receive custom webhooks:

    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:

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

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:\tes

Answers


Krohn February 2016

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. The body of the hook resides in the HttpRequest.Request.Inputstream, which can be opened using a streamreader. 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)

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. It published the request with the json. HTTP 200 was the response from the server.

Breakpoint was hit. The HttpMethod picked up the post. The Request's InputStream was read and stored in documentContents. JObject.Parse fired off and put the contents of the post into a JObject variable called json

The contents of json was written to a file stored on the server - indicating that the request was properly received.

What I plan to do to improve this, for security

Post Status

Asked in February 2016
Viewed 2,337 times
Voted 5
Answered 1 times

Search




Leave an answer