0

I'm receiving callbacks from an API we're using (Adobe Sign API). The only method available to authenticate these callbacks is HTTP Basic Auth, using URL encoding (not headers).

Documentation:

callbackInfo (string, optional): A publicly accessible url to which Adobe Sign will do an HTTP GET operation every time there is a new agreement event. HTTP authentication is supported using standard embedded syntax - i.e. http://username:password@your.server.com/path/to/file.

How can I access the username:password@ part of the URL, in order to validate the credentials? It doesn't seem to be available from the Request object (I dumped the entire object to console.error() and can't find the credentials anywhere in there). :(

I'm using Express 4.14.0, npm 3.10.8 & Node.js 7.0.0 (I could upgrade to a newer version if that would help).

Unfortunately, the Adobe Sign support is not helpful at all.

Edit: I already support the HTTP Basic authentication header (Authorization), but once again, it is not provided in this callback. Requests using the header show up in my nginx access logs with the username, but the callback doesn't show any username (which makes sense since the header isn't there). The only credentials available are in the username:password@ part of the URL. I didn't even know this was possible, but apparently it's part of the URL RFC, and still supported today (see section 3.1. Common Internet Scheme Syntax). I'm literally just receiving a simple GET request with no headers at all. Something like https://adobesign:verysecurepassword@myservice.com/callbacks.

For failed authentications, I'm returning a 401 response with the WWW-Authenticate header set to Basic, but it doesn't help in this case (only makes browsers prompt for username/password, but doesn't affect the callback).

Marco Roy
  • 4,004
  • 7
  • 34
  • 50
  • May want to look at this https://gist.github.com/charlesdaniel/1686663. It looks promising. – pizzarob Jan 19 '17 at 00:10
  • @realseanp That is using the `authorization` header, which is simple to implement but doesn't help in this case (the header isn't there; the `username:password` is sent as part of the URL instead) – Marco Roy Jan 19 '17 at 00:14
  • 1
    The HTTP protocol sends Basic Auth `user:pass` in Headers only. Are you sending `WWW-Authenticate` headers for requests to callback url? It is possible that callback url is pinged again with authorization header when first request is responded with HTTP 401. Try this http://stackoverflow.com/a/33905671/1921546 Only the part of url *after* `host:port` is sent prior to headers. If you are sure that this part has `user:pass` check its query parameters. – pii_ke Jan 24 '17 at 22:17
  • @pii_ke Not true; look at the URL RFC in my update. I am also sending the `WWW-Authenticate` header, but it's not helping the callback. The `user:pass` is also not in the query parameters, or any other element of the Request object. – Marco Roy Jan 27 '17 at 02:06
  • Actually, @pii_ke you are right (see answer below). The `username:password@` is sent as a header when I test on my side. So I really don't know what is wrong with Adobe Sign now. :( – Marco Roy Jan 27 '17 at 19:06

1 Answers1

2

That is part of the URL RFC yes, as in a URL can define a username and password, but it's up to the protocol to send it. HTTP doesn't support what you're describing, it only sends HTTP auth via the Authorization header. Something else is broken, perhaps something is stripping the header before it gets to you, perhaps Adobe Sign is sending something unexpected, etc. But there's no mechanism for HTTP to transfer that username / password except in a header. It's just not in the protocol.

Also, you said you dumped the entire request to the console, try dumping the auth header with console.log(req.get('Authorization')); You may not have seen the username / password value in the console as it's combined with a colon and base64 encoded before sending, so you won't see the plain text in your console.

You may also want https://github.com/expressjs/basic-auth-connect to more easily process the authorization request.

Jacob Gillespie
  • 3,981
  • 3
  • 23
  • 33
  • 1
    Thanks, I'll take a look at everything again. It's true that when I send the `username:password@` in the url, it becomes a header in all the clients I tested with. I completely forgot it wouldn't show up in plain text (x_x). So that's part of the problem solved at least. I'm using https://github.com/http-auth/http-auth and it's working great on my side, just not with the callback. Back to square one! – Marco Roy Jan 27 '17 at 19:21