I'm in the midst of writing an app which needs to authenticate with a remote server using digest authentication before it can trade data with it. I was hoping to use drupal_http_request(), but that function does not support this type of authentication.
I initially started to hack the function to see if I could work it in there, but quickly got over my head with the jargon in the relevant RFC. However, from what I understand, it's something that the function should be able to handle easily.
Digest authentication starts when the client makes a request of the server. The server will respond with a 401 Unauthorized response, but will also include a header labelled "WWW-Authenticate," the value of which will contain "Digest" followed by various instructions, including a nonce string. The client then makes a request from the server again, this time including an "Authorization" header which includes the value of the "WWW-Authenticate," as well as a hash created from concatenation of the password and the nonce (…if I'm understanding things correctly). So the switch block at the end of the function's code would have something like this added to it:
case 401: // Unauthorized
if (isset($uri['user']) && !isset($headers['Authorization']) && isset($result->headers['WWW-Authenticate']) && strpos($result->headers['WWW-Authenticate'], 'Digest') === 0) {
// …Hashing voodoo…
$headers['Authorization'] = $result->headers['WWW-Authenticate'] . $voodoo;
$result = drupal_http_request($url, $headers, $method, $data, --$retry);
}
else {
$result->error = $text;
}
I'm thinking this could even be backported into a D6 release since it shouldn't change the functionality of the function for those not trying to connect to servers with digest authentication.
Perhaps if I grow smarter about this sort of thing and/or have some time to waste, I'll sit down and try figuring it out for myself some time, but for this project, I'll probably end up just rolling my own parallel function that uses PHP's curl library.
Comments
Comment #1
Darren OhThere is a good example of digest authentication in this Wikipedia article: http://en.wikipedia.org/wiki/Digest_access_authentication. Also see HTTP authentication with PHP.
Comment #2
marcingy CreditAttribution: marcingy commentedBumping to d8
Comment #3
mauritsl CreditAttribution: mauritsl commentedThere should be an extra option to tell the function which authentication type to use. This is required to prevent the function from trying the basic auth first (and thus sending the plain password over the wire).
This function is already a very big function. Adding multiple authentication methods won't help much. Is the next step to add "Negotiate" and "NTLM" in the same function? It is better to make it pluggable via hooks. Authentication scheme's may then be implemented in other modules. I suggest that only basic authentication goes in core because it is far more common than the others.
Comment #4
mikeytown2 CreditAttribution: mikeytown2 commentedI'm open to a patch for httprl that implements this #1780566: support digest authentication
Comment #5
mikeytown2 CreditAttribution: mikeytown2 commentedMoving back to 7.x as D8 has guzzle in it