[Melbourne-pm] Apache auth and one time passwords.

Rick Measham rickm at isite.net.au
Wed Mar 9 20:10:07 PST 2005

Daniel Pittman wrote:
> I have a couple of web based systems that I would like to protect with a
> one time password tool, and being lazy, I want to use the work someone
> else has done to achieve this.

As you're the one who introduced me to perl-based apache authentication, 
  I feel I should reply :)

The attached solution is a simple hack on something I've done here at 
work. Normally I select the user from the database. In this case, I 
delete them. That way, if they exist I get a positive response from the 
delete and I cache them so they can keep accessing the site until their 
session expires (you'll notice I refresh the session on each request).

The solution does not rely on cookies, but instead relies on the browser 
not forgetting it's auth details for the site :)

N.B. The attached code ran perfectly in my head, but has not been tested 
on any other version of perl/apache.

Rick Measham

-------------- next part --------------
package Auth::OTP;
use strict;
use Apache::Constants qw(:common);
use Cache::FileCache;
use DBI;

require '/etc/httpd/lib/perl/config.pm';
my $DBH = DBI->connect(
) or die $DBI::errstr;

my $CACHE = Cache::FileCache->new({
	namespace          => 'namespace',
	username           => 'otp',
	default_expires_in => $config::session_expire,

sub handler {
     my $r = shift;
     # get user's authentication credentials
     my($res, $sent_pw) = $r->get_basic_auth_pw;
     return $res if $res != OK;
     my $user = $r->connection->user;
     my $reason = authenticate($r, $user, $sent_pw);
     if($reason) {
        $r->log_reason($reason, $r->filename);
        return AUTH_REQUIRED;
     return OK;

sub authenticate {
	my ($r, $user, $password) = @_;

	return 'No Database Connection' unless $DBH and $DBH->isa('DBI::db'); # No auth if we can't get to the DB!
	# Check the cache for the user:
	if ($user eq $CACHE->get($password)) {
		$CACHE->set($password => $user);
		return '';
	my ($ok) = $dbh->do(sprintf(
	return ($dbh->errstr) if $dbh->errstr;
	return ("Unknown user") unless $ok > 0;
	$CACHE->set($password => $user);
	return '';


More information about the Melbourne-pm mailing list