PerlAuthenHandler
Among other things, mod_perl allows you to write authentication handlers that fit nicely into Apache’s authentication scheme. A Perl authentication handler is a Perl module that decides whether a given user gets access to a resource or not. How you determine whether the user is allowed or denied access is up to you.
The mod_perl documentation comes with a sample that checks the length of the username+space+password supplied by a user and allows the user access only if the length is 14 characters long. Here is what the code looks like:
package MyApache2::SecretLengthAuth;
use strict;
use warnings;
use Apache2::Access ();
use Apache2::RequestUtil ();
use Apache2::Const -compile => qw(OK DECLINED HTTP_UNAUTHORIZED);
use constant SECRET_LENGTH => 14;
sub handler {
my $r = shift;
my ($status, $password) = $r->get_basic_auth_pw;
return $status unless $status == Apache2::Const::OK;
return Apache2::Const::OK
if SECRET_LENGTH == length join " ", $r->user, $password;
$r->note_basic_auth_failure;
return Apache2::Const::HTTP_UNAUTHORIZED;
}
1;
And you hook this handler up in your apache2.conf as:
<Location / >
PerlAuthenHandler MyApache2::SecretLengthAuth
AuthType Basic
AuthName "The Gate"
Require valid-user
</Location>
As the documentation points out, the authentication handler can be configured for any sub section of the site, it doesn’t matter if it is served by a mod_perl response handler or not.
Now obviously in real life, you’d want an authentication handler that does a little more – like verify the password supplied by the user against a database or LDAP . Here is a version that I wrote that uses Perl’s Net::POP3 package to verify user’s credential against a POP 3 server.
package Apache::PopAuth;
use strict;
use warnings;
use Net::POP3;
use Apache2::Access ();
use Apache2::RequestUtil ();
use Apache2::RequestRec ();
use Apache2::Const -compile => qw(OK DECLINED HTTP_UNAUTHORIZED);
sub handler {
my $r = shift;
my ($status, $password) = $r->get_basic_auth_pw;
my $user = $r->user;
return $status unless $status == Apache2::Const::OK;
return Apache2::Const::OK
if valid_user($user, $password);
$r->note_basic_auth_failure;
return Apache2::Const::HTTP_UNAUTHORIZED;
}
sub valid_user {
my($user, $password) = @_;
my $pop = Net::POP3->new('pop.yourdomain.com');
my $status = $pop->login($user, $password);
$pop->quit();
return defined($status);
}
1;
This saves you from having to maintain a separate set of users on your web server and passes on the baton of user management to the POP server. One word of caution – this just proof of concept code and I am not sure on well it will scale outside a small intranet.