2
votes

I try to write a C++-application and I have to do HTTP Digest Authentication. The problem is not primarily about C++, but about the fact, that the connection is not being established. The website I try to access is the following: httpbin.org/digest-auth/auth/user/passwd .

Consider the following server response to a simple GET /digest-auth/auth/user/passwd:

HTTP/1.1 401 UNAUTHORIZED Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Content-Type: text/html; charset=utf-8 Date: Mon, 08 Sep 2014 15:10:09 GMT Server: gunicorn/18.0 Set-Cookie: fake=fake_value Www-Authenticate: Digest realm="[email protected]", nonce="2a932bfb1f9a748a7b5ee590d0cf99e0", qop=auth, opaque="2d09668631b42bff8375523e7b27e45e" Content-Length: 0 Connection: keep-alive

A1 is then computed to be user:[email protected]:passwd and is hashed to 4de666b60f91e2444f549243bed5fa4b which I will refer to as HA1. A2 is computed to be GET:/digest-auth/auth/user/passwd and hashed to b44272ea65ee4af7fb26c5dba58f6863 which I will refer to as HA2.

With this information, the response is computed as HA1:nonce:1:ac3yyj:auth:HA2, where HA1 and HA2 are the values we have just computed and nonce is taken from the server response above, which is in total: 4de666b60f91e2444f549243bed5fa4b:2a932bfb1f9a748a7b5ee590d0cf99e0:1:ac3yyj:auth:b44272ea65ee4af7fb26c5dba58f6863. The hash of that is 55f292e183ead0810528bb2a13b98e00.

Combining all that information should be sufficient to establish a http-connection using digest authentication. However, the following request is declined by the server and answered with another HTTP/1.1 401.

GET /digest-auth/auth/user/passwd HTTP/1.1 Host: httpbin.org Authorization: Digest username="user", realm="[email protected]",nonce="2a932bfb1f9a748a7b5ee590d0cf99e0",uri="/digest-auth/auth/user/passwd",qop=auth,nc=1,cnonce="ac3yyj",response="55f292e183ead0810528bb2a13b98e00",opaque="2d09668631b42bff8375523e7b27e45e"

Note that the formatting does not show the structure of the request. The block from Authorization to opaque is actually one line.

Feel free to re-do the md5-calculation - but I have redone the calculations manually and got the same hashes as my program did. I used that tool (http://md5-hash-online.waraxe.us/) for the manual computations.

Am I missing something obvious here, probably misinterpreting the standard in a way? Why can't I get authorized?

1
The RFC gives an example of how it should work. Do you get the same answer?Alan Stokes
@AlanStokes: Hello, that is a good suggestion! I fed my program with the data provided in the RFC example and I got the same hash for response as the RFC did. I also sniffed firefox when it connects to httpbin.org and - in my point of view - the request are equal (take a look here: pastebin.com/UkpP1shP )... I am really running out of ideas now.Max Beikirch
@AlanStokes: Interesting - looks like curl has the same problem: try curl -v --digest -u user:passwd http://httpbin.org/digest-auth/user/passwdMax Beikirch
The correct command is: curl -v --digest -u user:passwd http://httpbin.org/digest-auth/auth/user/passwdMax Beikirch
And lwp-request (lwp-request -USse -C user:passwd http://httpbin.org/digest-auth/auth/user/passwd) is failing, too. I think that the server might be misconfigured - but why can firefox and wget successfully authorize?Max Beikirch

1 Answers

0
votes

Finally got it. The authentication itself is completely correct.

The server demands a cookie to be set. Apparently one must show that cookie in the reponse, too. That explains why firefox (being a browser) can authenticate correctly while curl and lwp-request can't albeit sticking to the standard - RFC said nothing about cookies. Why do we have standards, that noone cares for?

Anyway, appending Cookie: fake=fake_value to the header solves the problem.