5ubliminal@twitter

401 HTTP Authentication With PHP As CGI : 5ubliminal's TellinYa

<a href="http://www.tellinya.com/art2/357/">401 HTTP Authentication With PHP As CGI : 5ubliminal's TellinYa</a>
5ubliminal's YAMS
I'm too lazy for my shoes, too lazy for my clothes, too sexy…

I guess you know the song. I was looking today for an alternative method to build an universal admin login method and plug it in my site framework. The ideal method would be the same for any site, user friendly and easy for me to handle in the background. It should remeber the password and fit into any control panel I decide to build. Not to mention cross-browser compatibility!

After thinking and thinking… what is better than the default authentication method hardcoded in the HTTP Protocol?

HTTP Authentication Opera Dialog Box

It's simple, it can contain a message where I marked it, it can remeber passwords, can take username and password and everybody knows how to use it. It rules my lazy world! Well, you might think it's a breeze getting this to work and it should be as stated here. Yeah! Sure!

It's PHP Issue Squashing time!

Last night I spent 1 whole freaking hour trying to figure out what was wrong with my flawless piece of code (that compacted PHP code = multiple files into one, comments stripped and spaces removed.) just to learn that PHP takes # along // as single line comments. I've been coding in PHP for about 5 years and never have I noticed that # is also a comment.

Today I got another treat. HTTP 401 Auth does not work in PHP CGI Mode and that's how I use it. The expected fields: PHP_AUTH_USER, PHP_AUTH_PW are not filled in and they don't get filled in as supposed to. So, guess what…

Research time!

Everybody is bitching (with every right to do so) about this problem in the PHP dev community. But the fix is rather simple. It involves some .htaccess handling and tuning to pass the Authentication http header to the PHP script. It all looked simple now but there's another problem I faced.

Instead of getting REDIRECT_HTTP_AUTHORIZATION as a $_REQUEST['REDIRECT_HTTP_AUTHORIZATION'] variable I was getting REDIRECT_REDIRECT_HTTP_AUTHORIZATION. Wtf? I researched and others saw enev more then two REDIRECT_ in the variable.

To-do list!

  1. Push new header in using .htaccess
  2. Fix new header name by keeping just one REDIRECT_ in the variable name
  3. Decoding and validating login

Step1: .htaccess patch for php CGI Authentication to work:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^admin\. #[optional host restriction]
RewriteCond %{HTTP:Authorization} !^$ #must exist
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

The optional host restriction allows you to assign the Auth info only for a subdomain starting with e.g.: admin. It's optional and removable. This code pushes in an extra header: HTTP_AUTHORIZATION. Which get REDIRECT_ appended to it for whatever reason.

Step2+3: Fixing HTTP headers and Asigning login details:

<?
//-- Imbecil FIX for REDIRECT_ naming redundancy !
function fixServerRedirectHeaders(){
    foreach($_SERVER as $Key=>$Value){
        if(!preg_match("/^REDIRECT_REDIRECT_/",$Key)) continue;
        //-- Drop the old index!
        unset($_SERVER[$Key]);
        //-- Let's remove consecutive REDIRECT_
        while(preg_match("/^REDIRECT_REDIRECT_/",$Key)){
            $Key = substr($Key,9);
        }
        //-- Reassign value
        $_SERVER[$Key] = $Value;
    } reset($_SERVER);
    //-- Let's FIX PHP CGI Problems - 7 chars is min.: Basic[space]base64_encoded_auth_data
    $AuthString = $_SERVER['HTTP_AUTHORIZATION'];
    if(strlen($AuthString<=7)){ $AuthString = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; }
    //-- No auth info. Let's bail!
    if(strlen($AuthString)<=7) return false;
    //-- We keep everything coming after Basic[space]
    $AuthString = base64_decode(substr($AuthString, 6));
    //-- Let's translate auth info to PHP friendly format
    list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', $AuthString);
    return true; //-- To brag we fixed it!
}
//-- Call the function to apply the fix (rinse and repeat)
fixServerRedirectHeaders();
//-- Now validate $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] against whatever
//-- and allow / deny access! Keep a counter and time-ban the abusive!
?>

From here on it's up to you!

You can now handle the login process and act as you wish. Combine with mySql for authentication. Good luck! I'm sure from here on your admin login screen will be the easiest task of any control panel.

PS: There's a small problem with this method. You can't logout! So what? I don't use cPanels in public spaces and neither should you:)

6 Comments Posted By Readers :

Add your comment
#1 max from India
Posted on Tuesday, 07 October, 2008
hi,

i am using lighttpd web server & enabled digest authentication...I want to process 401 WWW-Authenticate request in my java script ....

But it seems it is getting redirected to browser ...with login pop-up....

Any alternative in implementing digest authentication
#2 5ubliminal web
Posted on Tuesday, 07 October, 2008
JavaScript is client-side, 401 auth is server side. It's impossible.
#3 max from India
Posted on Tuesday, 07 October, 2008
things get possible if u really want to make them
#4 5ubliminal web
Posted on Tuesday, 07 October, 2008
Trust me on this one. JS is client-side!
#5 max from India
Posted on Tuesday, 07 October, 2008
k. can you give me some alternate solution of open source digest authentication library...

Or as lighttpd is open source i can change that 401 to something else so that i can process it...

I found few PHP implementations but my embedded application wont be able to have PHP support
#6 5ubliminal web
Posted on Wednesday, 08 October, 2008
401s can be handled in any server-side coding language.
Just Google for ASP versions and so on. If server's won't support them … I'm clueless.
5ubliminal's TellinYa.com SEM & SEO Blog © 2007 - All rights reserved unless mentioned otherwise .
Rendered On : [Wednesday, 10 March, 2010 - 22:24:38 GMT]   No Ajax / Flash Used Here
" 401 HTTP Authentication With PHP As CGI : 5ubliminal's TellinYa "
Close
Tellinya.com is relocating to blog.5ubliminal.com. This blog is no longer maintained and comments are no longer accepted / answered.