Authentication Headers and IIS

After spending more time than I care to admit working on a problem I actually solved in May, I decided I’d better blog this before I forget again.

Using ActivePerl, it is possible to run perl CGI scripts under Microsoft IIS. In a default installation, the extention to use is .plx (not .cgi), which is mapped to run under PerlIS.dll, the “Perl for ISAPI” implementation. Works pretty well. The issue I had was with HTTP Authentication. If you want to handle your own authentication in a CGI script, you can check the Environment variable HTTP_AUTHORIZATION. For example:

binmode(STDOUT, ":utf8");  #you know you should

my $have_authinfo = (defined($ENV{HTTP_AUTHORIZATION}) 
    and (substr($ENV{HTTP_AUTHORIZATION},0,6) eq 'Basic '));

my ($user, $pass) = ('','');
if ($have_authinfo) {
    my $decoded = decode_base64(substr($ENV{HTTP_AUTHORIZATION},6));

    if ($decoded =~ /:/) {
        ($user, $pass) = split(/:/, $decoded);
    } else {
        $have_authinfo = 0;
    }
}

if (!$have_authinfo or !Authorize($user, $pass)) {
    print << "EOF";
HTTP/1.1 401 Authorization Required
WWW-Authenticate: Basic realm="Example.com"
Content-Type: text/plain; charset=utf-8

You must supply valid credentials to access this resource

EOF
    close STDOUT;
    exit 0;
}

#Authorized, continue with web page....

sub Authorize {
    my ($user, $pass) = @_;
    #Do something to authenticate, return true/false
}

Of course, I’m relying on Basic authentication, which you should only do if your script will only be available via HTTPS (as is mine). The whole thing is dependant on $ENV{HTTP_AUTHORIZATION}, which by default won’t actually get passed to your script under IIS and PerlIS.

Fortunately, fixing this is simple, if a bit non-evident. In the IIS Management Console, navigate to the folder containing your script, and select the script. Right-click and choose properties. On the File Security tab of the properties dialog, click the Edit button under “Anonymous Access”. On the next dialog, make sure that “Annonymous Access” is checked and that no other authentication method is checked. By default, Windows Integrated Authentication is selected, which makes IIS snoop around the header, and apparently lose it.

For multiple scripts, put them all in one location (go on, call it cgi-bin), and make the same changes above to the whole folder. New scripts created in this folder should inherit the settings.

Both comments and pings are currently closed.

2 Responses to “Authentication Headers and IIS”

  1. didier cabalé Says:

    you are a my king!!<br/>

    After having turned around of how getting the HTTP_AUTHORIZATION variable, i finally get the answer here. Thank’s a lot!!

  2. Jason Says:

    Glad this was helpful, Didier. I knew I couldn’t be the only person who’d want to do that.