note 81768 added to features.http-auth
| From: | AlexTM-alextm84 at gmail dot com | Date: | Wed, 12 Mar 2008 23:56:36 +0000 |
| Subject: | note 81768 added to features.http-auth | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-136991@lists.php.net to get a copy of this message | ||
I have written this code to use the Digest
authentication with PHP on both APACHE
and IIS_ISAPI.
This code fixes the differences between
the two modules.
I hope this will help.
AlexTM - Alessandro Cosci
<?php
session_start();
$realm = 'My Realm';
$logged = false;
//user => password
$users = array('user1' => 'psw1', 'user2' => 'psw2');
// ...
// We need to test which server authentication variable to use
// because the PHP ISAPI module in IIS acts different from CGI
if(isset($_SERVER['PHP_AUTH_DIGEST']))
{
$auth_data = $_SERVER['PHP_AUTH_DIGEST'];
$isapi = false;
}
elseif(isset($_SERVER['HTTP_AUTHORIZATION']))
{
$auth_data = $_SERVER['HTTP_AUTHORIZATION'];
$isapi = true;
}
else
$auth_data = "";
/* The $_SESSION['error_prompted'] variabile is used to ask
the password again if none given or if the user enters
a wrong auth. informations. */
if (
($auth_data == "") ||
(isset($_SESSION['error_prompted']) &&
$_SESSION['error_prompted']==true)
)
{
$uniqid = uniqid(""); // Empty argument for backward compatibility
$_SESSION['error_prompted'] = false;
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'" qop="auth" nonce="'.$uniqid.'"
opaque="'.md5($realm).'"');
die("You're not allowed to access this page.");
}
else
{
// We need to retrieve authentication informations from the $auth_data variable
if(!$isapi)
{
// CGI doesn't add backslashes to the authentication informations
// and doesn't prepend the "Digest " string before username.
// Furthermore it doesn't enclose the "qop" field between double quotes
preg_match('/username="(?P<username>.*)"' .
',\s*realm="(?P<realm>.*)"' .
',\s*nonce="(?P<nonce>.*)"' .
',\s*uri="(?P<uri>.*)"' .
',\s*response="(?P<response>.*)"' .
',\s*opaque="(?P<opaque>.*)"' .
',\s*qop=(?P<qop>.*)' .
',\s*nc=(?P<nc>.*)' .
',\s*cnonce="(?P<cnonce>.*)"/i', $auth_data, $digest);
}
else
{
// ISAP adds backslashes to the authentication informations
// and prependa the "Digest " string before username.
// Furthermore it encloses the "qop" field between double quotes
preg_match('/digest\susername="(?P<username>.*)"'
',\s*realm="(?P<realm>.*)"' .
',\s*nonce="(?P<nonce>.*)"' .
',\s*uri="(?P<uri>.*)"' .
',\s*response="(?P<response>.*)"' .
',\s*opaque="(?P<opaque>.*)"' .
',\s*qop=(?P<qop>.*)' .
',\s*nc=(?P<nc>.*)' .
',\s*cnonce="(?P<cnonce>.*)"/i', stripslashes($auth_data),
$digest);
// Sometimes ISAPI uses qop="auth", and sometimes it uses qop=auth
$digest['qop'] = str_replace("\"", "",
$digest['qop']);
}
if (!isset($users[$digest['username']]))
{
$_SESSION['error_prompted'] = true;
die('Username not valid!');
}
else
{
// This is the valid response expected
$A1 = md5($digest['username'] . ':' . $realm . ':' .
$users[$digest['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$digest['uri']);
$valid_response =
md5($A1.':'.$digest['nonce'].':'.$digest['nc'].':'.
$digest['cnonce'].':'.$digest['qop'].':'.$A2);
if ($digest['response'] != $valid_response)
{
$error_message = 'Wrong Credentials!';
$_SESSION['error_prompted'] = true;
}
else
{
// Ok, valid user/password
echo 'You are logged in as: ' . $digest['username'];
$logged = true;
}
}
}
?>
----
Server IP: 80.241.173.254
Probable Submitter: 79.12.202.29
----
Manual Page -- http://www.php.net/manual/en/features.http-auth.php
Edit -- https://master.php.net/note/edit/81768
Del: integrated -- https://master.php.net/note/delete/81768/integrated
Del: useless -- https://master.php.net/note/delete/81768/useless
Del: bad code -- https://master.php.net/note/delete/81768/bad+code
Del: spam -- https://master.php.net/note/delete/81768/spam
Del: non-english -- https://master.php.net/note/delete/81768/non-english
Del: in docs -- https://master.php.net/note/delete/81768/in+docs
Del: other reasons-- https://master.php.net/note/delete/81768
Reject -- https://master.php.net/note/reject/81768
Search -- https://master.php.net/manage/user-notes.php