mgomes / api_auth

HMAC authentication for Rails and HTTP Clients
MIT License
480 stars 147 forks source link

Requests from v1.3.2 client don't authenticate against a v1.4.1 server #128

Closed halloffame closed 8 years ago

halloffame commented 8 years ago

We are having trouble upgrading our APIs because it seems the suggested 1.3 to 1.4 migration path doesn't actually work.

I ran some tests to confirm, here are the results:

VERSION 1.3.2 (API server)
Verifies requests signed by client version 1.3.2  : true
Verifies requests signed by client version 1.4.1  : false
Verifies requests signed by client version 1.4.1* : false
Verifies requests signed by client version 1.5.0  : false
Verifies requests signed by client version 1.5.0* : false

VERSION 1.4.1 (API server)
Verifies requests signed by client version 1.3.2  : false (this should be true right?)
Verifies requests signed by client version 1.4.1  : true
Verifies requests signed by client version 1.4.1* : true
Verifies requests signed by client version 1.5.0  : true
Verifies requests signed by client version 1.5.0* : true

VERSION 1.5.0 (API server)
Verifies requests signed by client version 1.3.2  : false
Verifies requests signed by client version 1.4.1  : true
Verifies requests signed by client version 1.4.1* : true
Verifies requests signed by client version 1.5.0  : true
Verifies requests signed by client version 1.5.0* : true

VERSION 2.0.1 (API server)
Verifies requests signed by client version 1.3.2  : false
Verifies requests signed by client version 1.4.1  : false
Verifies requests signed by client version 1.4.1* : true
Verifies requests signed by client version 1.5.0  : false
Verifies requests signed by client version 1.5.0* : true

* with_http_method = true
halloffame commented 8 years ago

I tracked it down to this change. It looks like the RackRequest.request_uri method went from returning @request.url to @request.fullpath. Since that is what gets passed into headers.parse_uri when generating the canonical_string, I think that is what is causing the issue.

halloffame commented 8 years ago

Sorry, that test script was faulty 😞. It looks like the headers.parse_uri method strips out the host, but only if the host is actually valid. In my tests I didn't include the host and path info, so request.url was returning "://::0", which didn't match the regular expression in parse_uri so the host wasn't getting parsed out. I updated the tests and now v1.4 validates v1.3 requests. Well done after all 👏 .