About Setting up asana webhook with asp.net webmethod

Hello,

I am trying to set up the webhook, with asp.net webmethod but getting the the error

{
“errors”: [
{
“message”: “Could not complete activation handshake with target URL. Please ensure that the receiving server is accepting connections and supports SSL”,
“help”: “For more information on API status codes and how to handle them, read the docs on errors: Build an app with Asana
}
]
}

my webmethod is like following
public static void BasicAsanaHook()
{
string headerVal = HttpContext.Current.Request.Headers[“X-Hook-Secret”];
if (string.IsNullOrEmpty(headerVal))
headerVal = “12345678”;
HttpContext.Current.Response.Headers.Add(“X-Hook-Secret”, headerVal);
}

Thank You.

I could be wrong but from your example it seems like you’re confusing webhooks with OAuth authentication. “X-Hook-Secret” is used to obtain an OAuth token, which you need to do prior to requesting a webhook but is a separate operation. So can you clarify - have you already done the OAuth process and have gotten an OAuth token, or not? If not, you need to authenticate to Asana via OAuth 2.0 before you can request a webhook. Or is it the OAuth process that you’re describing in your example, not the webhook request process?

1 Like

Yes i already got the auth token and i am passing the auth token in the request already. I am using the Authorization Bearer token for that.

here is my request

Your Authorization header needs to say “Bearer” for OAuth, not “Basic”.

The first thing that pops out to me is that there might be a bug in the logic, at least as presented. It reads to me as “If the header is not set, then set it to some arbitrary string, then return it”.

The thing to do here is to pull the value out of the header (it should always be there for the handshake and never there for subsequent webhook responses), then return the value you pulled out to us just as it is. It doesn’t look like you’re actually doing that here, at least not by what you’ve included in the question.

It looks to me like you might benefit from checking out some of our examples, which we’re working on building out (we’re planning on publicizing them a bit more as they get more feature rich and documented). Here’s the section of the code that does this in our example: https://github.com/Asana/devrel-examples/blob/master/python/webhooks/webhook_inspector.py#L144

At that point, if you echo back the webhook exactly, your handshake should succeed and you should start getting webhooks.

Also worth noting is why this header exists. It’s optional but recommended for you to use; you can get webhooks without it. It’s a security precaution you can take on your end: you have a server up and running that can take incoming requests from just about anywhere. How do you know that there’s not an attacker out there spoofing the sort of requests that Asana might be sending you? Webhooks don’t have any inbound authentication; that is, Asana doesn’t have to log in or send an auth token to your server to prove it’s Asana.

That’s the general purpose of the X-Hook-Secret: it’s more or less a random token that Asana stores on our side; then when we respond with webhook events, we calculate a signature in a way that can only be done if we know the secret. You can also calculate this signature client-side (this is optional, but recommended) and if the signatures match, you know it’s Asana.

This is secure because the only way for us to create and store the secret is when you request us to - when you first create the webhook. That’s why the secret is used for the handshake (and why it’s called a handshake, which is a common term in security for exchanging secrets).

  • You authenticate with Asana to create the webhook, so Asana knows it’s you
  • We send you a secret in another request, which you are expecting, since you asked Asana for it with the webhook creation request. You can then store this secret, and we share it on Asana’s side and on your client.
  • When a future incoming request comes, if the same secret we share calculates the same signature on both sides, then you know that the webhook event is really from Asana.

If you look in that example, you can see that we demonstrate this as well. https://github.com/Asana/devrel-examples/blob/master/python/webhooks/webhook_inspector.py#L153