An Authenticating Script for Apache

We’ll start by observing that web servers aren’t the only things that can issue Authorization: headers. Scripts can do that too. Example 12.1 is a simple Perl script that challenges for a name and password, just as an authenticating web server does.

Example 12-1. Scripting the Name/Password Challenge

use MIME::Base64;

if ( ! defined $ENV{HTTP_AUTHORIZATION} )    # if no Authorization: header
  {     
  print "HTTP/1.0 401 Authentication
";     # issue authorization challenge
  print "WWW-Authenticate: Basic realm="subscribers"

";
  return;
  }

print "HTTP/1.0 200 Ok
";                   # needed for ISAPI Perl or mod_perl
print "Content-type: text/html

";         # the standard header
$ENV{HTTP_AUTHORIZATION} =~ m/Basic (.+)/i;  # get MIME-encoded credentials
print "Hello " . decode_base64($1);          # print "Hello Aladdin:open sesame"

We’ve introduced another CPAN module here. MIME::Base64 converts back and forth between plain text and the Base64 encoding used by the HTTP basic authentication protocol. If you put this code in a file called auth.pl, put that file into the /cgi-bin directory of an Apache web server, and ask your browser to fetch /cgi-bin/auth.pl, you’ll provoke an authentication dialog. Type in the credentials Aladdin and open sesame and you’ll get the reponse Hello Aladdin:open sesame.

If that doesn’t work, define the symbol SECURITY_HOLE_PASS_AUTHORIZATION and rebuild Apache. What? Open a security hole? Well, here’s what the Apache source code says about allowing scripts to see the Authorization: header:

/*
* You really don't want to disable this check, since it leaves you
* wide open to CGIs stealing passwords and people viewing them
* in the environment with "ps -e".  But, if you must...
*/

On an Apache server that hosts multiple CGI-capable sites, it’s probably a good idea to hold Authorization: headers close to the vest. Apache wisely defaults to this behavior. But if you run your own Apache server on a dedicated machine that you control, it’s reasonable to pass the Authorization: header through to your scripts. IIS, by the way, always does so.

Here’s how this protocol works. The initial request sends no Authorization: header, so the script responds with a challenge, then exits. Why does it exit? The code following the credentials check is protected. When the browser retries the request, the script sees an Authorization: header and the protected code runs.

Clearly we need to do more than just check for the presence of an Authorization: header. We’ll want to look up the credentials somewhere and decide whether to authenticate the user. Having done so, the protected code will be in a position to do more. It could, for example, look up the value of the company field in a requested docbase record and compare that with the list of companies subscribed to by the authenticated user. But before we build that piece, let’s look at why this script won’t work the same way in IIS and how to fix that.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.27.202