Reputation: 3974
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:\test\test.txt
- which was not the case
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. I also have some javascript running on the homepage to poll for any changes to dataReceived
but I see nothing is happening.
Mentioning here: I have a remote debugger attached to the w3wp.exe process, the breakpoint on ExecuteAsync and GenericJsonWebHookHandler does not get hit
Are there any other specific setup that needs to be done in order for the webhook to be captured?
Upvotes: 4
Views: 8684
Reputation: 3974
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
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
Upvotes: 4