Testing WebHooks Locally with a Reverse Proxy

29/02/2016

I have been testing out the new Microsoft Graph Subscriptions API that allows you to get notified when, e.g. mails are received in Exchange online.

To use this API you have to setup a webhook that gets called by the exchange servers. The requirement to this webhook is that it should be accessible over the internet and it should also use https. Those requirements could potentially make development and testing of the webhook endpoint pretty time consuming if you had to deploy it to a public web server for every iteration.

Luckily there are alternatives. By using a Reverse proxy you can tunnel traffic from a publicly accessible endpoint to your development box. The first tool I used for this was meetfinch.com, meetfinch works just like you would expect, you install it and decided which internal port that you want exposed on the internet, they generate a public URL for you and then you are ready to go. The downside with meetfinch is that it costs money to use.

An alternative that is free, is ngrok.com. It is less flashy, only a commandline interface, but I can live with that for the price tag. It also comes with https support just like meetfinch.

My local Web API i used to test the subscription endpoint looks like this.
[csharp]
public class SubscriptionController : ApiController
{

[Route("api/subscription/message")]
[HttpPost]
public IHttpActionResult ValidationEndpoint(string validationtoken)
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Content = new StringContent(validationtoken, System.Text.Encoding.UTF8, "text/plain");

return ResponseMessage(resp);
}

[Route("api/subscription/message")]
[HttpPost]
public IHttpActionResult MessageNotification(dynamic message)
{
Console.WriteLine(JsonConvert.SerializeObject(message));
return Ok();
}
}
[/csharp]

To expose it to the internet I simply run ngrok.exe http 46875 since my local IIS express site it on port 46875.
ngrok1

Ngrok starts and I get a remote endpoint, in my case https://4ebc7b7d.ngrok.io. Now if I try to browse it I get an error 400 bad request. This is because my iisexpress is only configured to accept connection on the hostname localhost, not on 4ebc7b7d.ngrok.io. But we can change that.

To make IIS express accept the request, we have to open the applicationhost.config file it is located in \.vs\config\applicationhost.config

Search for the port number in the file, you should see a line like this.
[xml]
<bindings>
<binding protocol="http" bindingInformation="*:46875:localhost" />
</bindings>
[/xml]

Now add an extra binding
[xml]
<bindings>
<binding protocol="http" bindingInformation="*:46875:localhost" />
<binding protocol="http" bindingInformation="*:46875:4ebc7b7d.ngrok.io" />
</bindings>
[/xml]

Now your IIS express will accept connections on the hostname given to you by ngrok.com. Note for this to work you have to run Visual Studio as administrator and make sure to restart the iis express process before the change takes effect.

But that is all there is to it, now you local dev box is accessible on the internet, even on https.

Another nice feature of ngrok is that it comes with a little web server, that gives you some statistics, so you can see if you endpoints gets called.
ngrok2