Recipe 21.1 Authenticating
21.1.1 Problem
You want to
verify the username and password supplied by users who are
authenticating themselves.
21.1.2 Solution
Get the password with $r->get_basic_auth_pw,
and the username with $r->connection->user.
Indicate success by returning OK. Indicate failure by calling
$r->note_basic_auth_failure and returning
AUTH_REQUIRED.
package Your::Authentication::Package;
use Apache::Constants ':common';
sub handler {
my $r = shift;
return OK unless $r->is_main; # skip for subrequests
my ($res, $sent_pw) = $r->get_basic_auth_pw;
if ($res != OK) {
$r->note_basic_auth_failure;
return $res;
}
my $user = $r->user;
# check username and password, setting $failed if they don't match
if ($failed) {
$r->note_basic_auth_failure;
return AUTH_REQUIRED;
}
return OK;
}
Install the handler for a directory or set of files with:
# the realm
AuthName "Holiday Photos"
# next line shouldn't be changed
AuthType Basic
PerlAuthenHandler Your::Authentication::Package
require valid-user
21.1.3 Description
The realm is what the user sees when their browser prompts for a
username and password. If you set the realm to "Holiday Photos", the
user is prompted to "enter username and password for Holiday Photos".
You need at least one require directive to trigger
the call to the authentication handler.
When you invoke $r->get_basic_auth_pw, Apache
processes any authentication information sent by the client.
Therefore you can't call $r->user before you
call $r->get_basic_auth_pw (well, you can, but
you won't get anything back).
The call to $r->get_basic_auth_pw returns two
values, a status code and a password. If the status is OK, the
browser agreed to authenticate and provided information. If the
status is DECLINED, either the area isn't protected by basic
authentication or there's no AuthType specified in
httpd.conf. If the status is SERVER_ERROR,
there's no realm defined for this area. If the status is
AUTH_REQUIRED, the browser mangled or omitted basic authentication.
If you decide to return AUTH_REQUIRED, first call
$r->note_basic_auth_failure to ensure Apache
sends realm information to the browser.
The status code returned from
$r->get_basic_auth_pw tells you whether the
browser knows to authenticate these pages. When the browser sends no
authentication information, you respond "no password, no access." To
do this, note the authentication failure and return the AUTH_REQUIRED
that $r->get_basic_auth_pw gave you.
We invoke $r->is_main to learn whether we're
the main request. Apache often makes subrequests, and there's no
point in doing the (potentially slow) authentication lookup for the
subrequests. This doesn't result in less security, since if the
authentication fails for the main request, the content handler isn't
run. This avoids messy problems like recursion and multiple attempts
to parse POST data.
21.1.4 See Also
The Apache.pm manpage; Writing Apache Modules with Perl
and C; Recipe 13.3 in mod_perl Developer's
Cookbook
|