Skip to content

Instantly share code, notes, and snippets.

@funkatron
Created April 30, 2011 20:08
Show Gist options
  • Save funkatron/949952 to your computer and use it in GitHub Desktop.
Save funkatron/949952 to your computer and use it in GitHub Desktop.
An example of how to manually construct an HTTP Digest authentication header.
<?php
$url = 'http://domain.foo';
$uri = '/assets';
$username = 'testyser';
$password = 'somepassword';
$method = 'GET';
$ht = new HttpRequest($url.$uri, HttpRequest::METH_GET);
$ht->send();
print_r($ht->getRawRequestMessage());
print_r($ht->getRawResponseMessage());
$auth_resp_header = $ht->getResponseHeader('WWW-Authenticate');
$auth_resp_header = explode(',', preg_replace("/^Digest/i", "", $auth_resp_header));
$auth_pieces = array();
foreach ($auth_resp_header as &$piece) {
$piece = trim($piece);
$piece = explode('=', $piece);
$auth_pieces[$piece[0]] = trim($piece[1], '"');
}
print_r($auth_pieces);
// build response digest
$nc = str_pad('1', 8, '0', STR_PAD_LEFT);
$cnonce = '0a4f113b';
$A1 = md5("{$username}:{$auth_pieces['realm']}:{$password}");
$A2 = md5("{$method}:{$uri}");
$auth_pieces['response'] = md5("{$A1}:{$auth_pieces['nonce']}:{$nc}:{$cnonce}:{$auth_pieces['qop']}:${A2}");
$digest_header = "Digest username=\"{$username}\", realm=\"{$auth_pieces['realm']}\", nonce=\"{$auth_pieces['nonce']}\", uri=\"{$uri}\", cnonce=\"{$cnonce}\", nc={$nc}, qop=\"{$auth_pieces['qop']}\", response=\"{$auth_pieces['response']}\", opaque=\"{$auth_pieces['opaque']}\", algorithm=\"{$auth_pieces['algorithm']}\"";
$ht = new HttpRequest($url.$uri, HttpRequest::METH_GET);
$ht->setHeaders(array('Authorization'=>$digest_header));
$ht->send();
print_r($ht->getRawRequestMessage());
print_r($ht->getRawResponseMessage());
@jeiman-zz
Copy link

Hi,
If I have a login form that require digest authentication like below, how to integrate with your authentication code.

Email:
Password:

@sudosoul
Copy link

Thanks for this.
If anyone else comes across this and lacks the HttpRequest library, you should install it as so:
sudo pecl install -f pecl_http-1.7.6

And then add the following to your php.ini file:
extension=http.so

@hargobind
Copy link

Thank you for providing this code example. It was extremely helpful in setting up my own Digest authentication, along with a reading of Understanding HTTP Digest Access Authentication.

I found a flaw in the way you parse the original response header. It's possible that the "WWW-Authenticate" header parameters can contain a = character in their values. Your call to explode() causes the value to be parsed incorrectly where everything after the first = in the value is discarded.

Here's an example, nonce="359211dc26d108:32g/mkd52jp+v2/cGj33Tg=="
Your code would make the value of nonce be 359211dc26d108:32g/mkd52jp+v2/cGj33Tg (the == is missing)

Here's where the flaw is:

foreach ($auth_resp_header as &$piece) {
	$piece = trim($piece);
	$piece = explode('=', $piece);
	$auth_pieces[$piece[0]] = trim($piece[1], '"');
}

Here's a way to make sure the whole value stays intact:

foreach ($auth_resp_header as $piece) {
	$piece = explode('=', trim($piece));
	$key = array_shift($piece);
	$value = trim(implode('=', $piece), '"');
	$auth_pieces[$key] = $value;
}

(Alternatively, you could also use preg_match() to do the parsing if you are comfortable with regular expressions)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment