So I decided to use digest HTTP authentication for my REST API. I googled it and found an entry in the PHP manual with an example of how to do it. So I copy the script, put it in index.php on my server, open the page in the browser, after entering my credentials the browser asks for them again and I'm stuck in an infinite loop of entering credentials. The script is included below and can be found here.
Example #7 Digest HTTP Authentication example
<?php
$realm = 'Restricted area';
//user => password
$users = array('admin' => 'mypass', 'guest' => 'guest');
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Text to send if user hits Cancel button');
}
// analyze the PHP_AUTH_DIGEST variable
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset($users[$data['username']]))
die('Wrong Credentials!');
// generate the valid response
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response)
die('Wrong Credentials!');
// ok, valid username & password
echo 'Your are logged in as: ' . $data['username'];
// function to parse the http auth header
function http_digest_parse($txt)
{
// protect against missing data
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($needed_parts));
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
}
?>
I also tried basic authentication and that worked perfectly.
Example #6 Basic HTTP Authentication example
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
} else {
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
?>
It seems like $_SERVER['PHP_AUTH_DIGEST']
is always empty.
Is there something wrong with the script or is my environment funky and if so how do I fix it?
EDIT: There is nothing wrong with the script. The fault lies with the server. If anyone knows what could possibly cause this, please let me know.
Digest authentication is another authentication type specified in HTTP 1.1. Unlike basic authentication, digest authentication does not require the password to be transmitted. Rather, the client takes the username and password and uses the MD5 hashing algorithm to create a hash, which is then sent to the SQL Server.
After receiving user authentication details in PHP, it compares the form data with the user database by executing a query by using the connection object. The query binds the username entered by the user via HTML form. Then, it verifies the password hash with the entered password to return the authentication results.
Only "Basic" and "Digest" authentication methods are supported.
Digest access authentication is one of the agreed-upon methods a web server can use to negotiate credentials, such as username or password, with a user's web browser. This can be used to confirm the identity of a user before sending sensitive information, such as online banking transaction history.
Digest authentication is a separate Apache module that's often not installed on servers - especially with cheap hosting companies. It needs to be enabled to make use of it though.
http://httpd.apache.org/docs/current/mod/mod_auth_digest.html
It depends on your distribution how to install it, if you're using Linux. On my Ubuntu Linux it was enough to create a symbolic link of the module from the deactivated modules folder to the activated modules one run sudo a2enmod auth_digest
on the shell. That, and restarting Apache, of course.
I don't know about Windows.
Do you have mod_headers loaded within Apache (I assume your server run Apache)?
You might figure it out by using the following command line (which execution might require privileges):
httpd -M | grep head
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With