Eventum has a feature to provide RSS feeds of custom filters, which is basically a way to save advanced search parameters into a special URL that you can call out to check on results. Pretty useful feature, and a lot of people use that. However, we can’t simply have an open window into a potential confidential database of issues/bugs/tickets, so the RSS feed script authenticates the user with HTTP Auth, with the usual PHP way of doing things:
<?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 "Hello {$_SERVER['PHP_AUTH_USER']}.";
echo "You entered {$_SERVER['PHP_AUTH_PW']} as your password.";
}
?>
Everything works fine most of the times, but we started getting reports of problems from Microsoft IIS users. It turns out that PHP doesn’t automagically sets up the PHP_AUTH_* variables for you in some cases, and there’s even a quick mention of that on the documentation:
Another limitation is if you’re using the IIS module (ISAPI) and PHP 4, you may not use the PHP_AUTH_* variables but instead, the variable HTTP_AUTHORIZATION is available. For example, consider the following code: list($user, $pw) = explode(‘:’, base64_decode(substr($_SERVER[‘HTTP_AUTHORIZATION’], 6)));
However, that wasn’t true for a Microsoft IIS 6.0 that had configured PHP as a ISAPI module. Instead of getting a $_SERVER[‘HTTP_AUTHORIZATION’] variable like that, he would get this when doing var_dump($_SERVER):
array(30) {
["ALL_HTTP"]=> string(985) "HTTP_CONNECTION:keep-alive
HTTP_KEEP_ALIVE:300
HTTP_ACCEPT_CHARSET:ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_ACCEPT_ENCODING:gzip,deflate HTTP_ACCEPT_LANGUAGE:en-us,en;q=0.5
HTTP_AUTHORIZATION:Basic ********************************************"
}
So instead of simply using the $_SERVER variables, I had to manually handle the HTTP environment variables and get the proper value:
if ((!empty($_SERVER['ALL_HTTP'])) && (strstr($_SERVER['ALL_HTTP'], 'HTTP_AUTHORIZATION'))) {
preg_match('/HTTP_AUTHORIZATION:Basic (.*)/', $_SERVER['ALL_HTTP'], $matches);
if (count($matches) > 0) {
$pieces = explode(':', base64_decode($matches[1]));
$_SERVER['PHP_AUTH_USER'] = $pieces[0];
$_SERVER['PHP_AUTH_PW'] = $pieces[1];
}
}
That will do the trick.