This is just a note to say that it's worth testing this on a server where php runs in cgi mode. Securesite (which is very similar) has a weakness that it cannot work under php-cgi. So, I imagine the same is the case here. Once that is confirmed it would be helpful to document the fact for new users.

#12 httpauth_cgi.patch967 bytesdecafdennis
Members fund testing for the Drupal project. Drupal Association Learn more


decafdennis’s picture

Assigned: Unassigned » decafdennis

Hmm I wouldn't think the way PHP is installed would affect sending and receiving some headers.

But I'll look into the matter, thanks for your comment!

greggles’s picture

Here is the issue from securesite

Perhaps it will give some clues.

NaX’s picture

Their has been a workaround found for the CGI problem thanks to moshe weitzman. Have a look at the last few posts on this issue.

I am going to try to get the workaround into securesite later this week. The only complication is that it requires patching the .htaccess file.

decafdennis’s picture

Title: test/confirm with php in cgi mode » Authentication broken in php cgi mode
Category: task » bug

Thanks, I'll take a look at it!

moshe weitzman’s picture

no patch to .htaccess. just add a few lines to settings.php. i am not running httpautgh on and soon i had to tweak it a bit.

decafdennis’s picture

I've just finished my virtualized Gentoo install, so I can test under CGI mode myself.

decafdennis’s picture


no patch to .htaccess. just add a few lines to settings.php.

How exactly, I can't get it to work with $_SERVER['Authentication'], I need the .htaccess fix.

i am not running httpautgh on and soon

Are you, or are you not?

i had to tweak it a bit.

Tell me!


decafdennis’s picture

Oops didn't close that last blockquote there.

moshe weitzman’s picture

you are probably right. the server admins at likely made changed in their .conf file so that i didn't need to do anything in .htaccess

i am indeed using this on i had to patch the init function so the auth would fire on specified paths (like seduresite). i only use this to protect rss feed paths. otherwise, users should login using regular html box. so i am not using the (neat) callback feature which typically fires on 403 error ... i use this module because securesite was getting too complex for my taste.

decafdennis’s picture

Thanks for your clarification. It pleases me you're using httpauth on, it always motivates to hear from people who're using your stuff.

Alright, I'll probably solve the .htaccess issue by asking the user if he/she wants to have the file changed automagically.

I submitted a feature request to httpauth that will allow authentication to be fired regardless of whether a 403 error was returned. This will be an optional feature.

Please: can somebody with the sufficient permissions close the blockquote tag after "a bit." in #8? Thanks.

decafdennis’s picture

Priority: Normal » Critical

Note to self: fix this soon!

Will need porting to 5.x too.

decafdennis’s picture

Version: 4.7.x-1.x-dev » 5.x-1.x-dev
967 bytes

I applied the attached patch to all branches. You can either wait a few hours for the package update script to update the development package, or apply the patch yourself by running patch < httpauth_cgi.patch in the httpauth directory.

You will also need to add the following line to the .htaccess file in your Drupal root directory, just under RewriteBase /drupal (might have a # in front of it) but above # Rewrite old-style URLs ...:

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Works for me. Please tell me if it fixes everybody's problems, then I can find a user-friendly solution for the .htaccess fiddling.


karlrees’s picture

I still can't get this to work. I'm starting from a clean 5.1 install, and the only things I've done is enable the HTTP Authentication module and add the line from above to .htaccess. Is there something else I should be doing?

decafdennis’s picture

Are you getting a username and password prompt?

karlrees’s picture

Yes. It just repeats.

So, I've been doing a little debugging here and it appears that either the HTTP_AUTHENTICATION environment variable is not being set, or that PHP can't access it. Either way, I'm only able to access the HTTP:Authentication string if I put it on the query string. In other words, here is my .htaccess:

RewriteEngine on
RewriteCond %{HTTP:Authorization} .*
RewriteRule authenticate.php authenticate.php?login=%{HTTP:Authorization}

And here is my php test file (authenticate.php):

// split the user/pass parts
 $d = base64_decode(substr($_GET['login'],6) );
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', $d);

// open a user/pass prompt
if ($_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';
 } else {
   echo "<p>Hello, </p>".$_SERVER['PHP_AUTH_USER'];
   echo "<p>You entered as your password: </p>".$_SERVER['PHP_AUTH_PW'];

I figured this out from this page, by the way:

decafdennis’s picture

Thanks, I will try the same thing on my virtualized PHP-CGI-box, the environment variable should be set.

If the variable is not set, there is something larger at hand, maybe.

decafdennis’s picture

Can you do the same test again, with the following alterations:

Add RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] to .htaccess just after de RewriteCond but before the RewriteRule

Add echo "<pre>"; var_dump($_GET); var_dump($_SERVER); at then end of authenticate.php.

Please send me the output, so I can see what variables are being set exactly.

karlrees’s picture

Well, I tried dumping the environment variables, and sure enough, .htaccess isn't having any effect on them. I did a little more digging, and apparently there is a server setting somewhere that prevents .htaccess from changing environment variables (see, e.g., comments to I use HostGator. I guess I'll shoot them off an email to see if they can change their settings, or maybe even resort to hacking up a version that will authenticate using the _GET trick.

Anyway, here was the output:

You entered as your password: 

array(1) {
  string(18) "Basic a2FybDoxMjM0"
array(37) {
  string(28) "/usr/local/bin:/usr/bin:/bin"
  string(31) "[omitted]"
  string(3) "*/*"
  string(13) "gzip, deflate"
  string(5) "en-us"
  string(10) "Keep-Alive"
  string(56) "PHPSESSID=5e459520f186f7e1a1f08c8647f71aec; cprelogin=no"
  string(17) ""
  string(3) "x86"
  string(82) "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; InfoPath.1)"
  string(24) "login=Basic a2FybDoxMjM0"
  string(3) "200"
  string(17) "/authenticate.php"
  string(11) ""
  string(5) "62566"
  string(48) "[omitted]authenticate.php"
  string(13) ""
  string(27) "[omitted]"
  string(17) ""
  string(2) "80"
  string(151) "Apache/1.3.37 (Unix) mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 FrontPage/ mod_ssl/2.8.28 OpenSSL/0.9.7a PHP-CGI/0.1b"
  string(7) "CGI/1.1"
  string(8) "HTTP/1.1"
  string(3) "GET"
  string(24) "login=Basic a2FybDoxMjM0"
  string(17) "/authenticate.php"
  string(17) "/authenticate.php"
  string(30) "/usr/local/cpanel/cgi-sys/php5"
  string(17) "/authenticate.php"
  string(48) "[omitted]authenticate.php"
  string(13) "/cgi-sys/php5"
  string(17) "/authenticate.php"
  array(1) {
    string(24) "login=Basic a2FybDoxMjM0"
  string(4) "1234"
  string(4) "karl"

decafdennis’s picture

OK, I guess I'll change it so that it rewrites the HTTP:Authorization variable to the query string ($_GET) instead of to an environment variable (<code>$_SERVER). My only doubt is whether this poses a security threat... though I don't think the rewritten URL (including the query string containing as good as a plain password) is logged anywhere.

karlrees, thank you, you're being very helpful!

decafdennis’s picture

OK I changed some code. Please test it using the following in .htaccess:

  # Rewrite HTTP authorization information to the query string
  RewriteCond %{HTTP:Authorization} ^Basic
  RewriteRule ^(.*)$ $1?HTTP_AUTHORIZATION=%{HTTP:Authorization} [QSA]

Note that the development package may take up to 12 hours to be updated to the new code.

karlrees’s picture

Sorry it took so long to find time to test it. It appears to work fine if I use the following code in .htaccess:

RewriteCond %{HTTP:Authorization} ^Basic
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ $1&HTTP_AUTHORIZATION=%{HTTP:Authorization} [QSA]
RewriteCond %{HTTP:Authorization} ^Basic
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*)$ $1?HTTP_AUTHORIZATION=%{HTTP:Authorization} [QSA]	

I'm not sure if this is the cleanest code, but this is the only way to make it so ?authenticate will work. Plus, it's more compatible if other stuff is put in the query string.

decafdennis’s picture

Great that we at least solved the problem!

Only the rewriting of the query string... Drupal does the following, which works if an existing query string is present:

RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

Actually the QSA is what should nicely append the existing query string. I'll run some tests.

karlrees’s picture

Okay, so I never really got this working the first time around. I had some bug where the query string would keep growing appending the last segment of the drupal path to itself (so, for example, if I tried going to admin/content?authenticate, I'd wind up at admin/content//content instead).

I'm sure there's a better workaround somewhere, and I'm not sure that my workaround won't cause problems for other people, but here's my eventual solution.

This is in .htaccess

 # Rewrite HTTP authorization information to the query string
  RewriteCond %{HTTP:Authorization} ^Basic
  RewriteRule ^(.*)$ $1?HTTP_AUTHORIZATION=%{HTTP:Authorization} [L,QSA]

I only changed two lines in the httpauth_redirect() function. I know, I should make a patch, but I'm lazy. Here's the relevant changes:

  // Get the current query string (if available) and add session information for clients that don't support cookies.
  // *** added "authenticate"
  if ($query = drupal_query_string_encode($_GET, array('q', 'HTTP_AUTHORIZATION', 'authenticate'))) {
		$query .= '&'. strip_tags(SID);
  else {
    $query = strip_tags(SID);
  // *** use the server name + script name instead of q from the query string	
  //drupal_goto($_GET['q'], $query);
  drupal_goto("http://".$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME'], $query);

Hopefully this helps other people out there.

decafdennis’s picture

Status: Active » Fixed

I tested your .htaccess fix and it appears to work as advertised when using CGI or FastCGI.

It's now documented in the README.txt file. (I forgot to properly mention the issue# and your name in the commit message, sorry karlrees!)

The changes to httpauth_redirect() aren't necessary anymore, since I removed that function completely.

Thanks for all your help, everybody!

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.