DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 6.3 Expiring Passwords

Problem

You want a user's username and password to expire at a particular time or after some specific interval.

Solution

No solution is available with standard Apache features, but a few third-party solutions exist.

Discussion

Refer to HTTP, Browsers, and Credentials. In order for Apache to provide this functionality, it would need to store more than just the valid username and password; it would also have to maintain information about the credentials' expiration time. No module provided as part of the standard Apache distribution does this.

There are several third-party solutions to this problem, including the Perl module Apache::Htpasswd::Perishable and the mod_perl handler Apache::AuthExpire.

There are two slightly different ways to look at this problem, which will influence your choice of a solution. You may want a user's authentication to be timed out after a certain amount of time, or perhaps after a certain period of inactivity, forcing them to log in again. Or you may want a particular username/password pair to be completely expired after a certain amount of time, so that it no longer works. The latter might be used instead of a single-use password, which is impractical to implement in HTTP.

Apache::Htpasswd::Perishable partially implements the latter interpretation of the problem by adding expiration information to the password file. Inheriting from the Apache::Htpasswd module, it adds two additional methods, expire and extend, which set an expiration date on the password and extend the expiration time, respectively.

For example, the following code will open a password file and set an expiration date on a particular user entry in that file:

use Apache::Htpasswd::Perishable;

my $pass = Apache::Htpasswd::Perishable->new("/usr/local/apache/passwords/user.pass")
    or die "Could not open password file.";
$pass->expire('waldo',5); # Set the expiration date 5 days in the future

Such a mechanism is only useful if expired passwords are removed from the password file periodically. This can be accomplished by running the following cron script every day. This will delete those users for whom the expiration date has passed:

#!/usr/bin/perl
use Apache::Htpasswd::Perishable;

my $password_file = '/usr/local/apache/passwords/user.pass';

open (F,$password_file) or die "Could not open password file.";
my @users;
while (my $user = <F>) {
    $user =~ s/^([^:])+:.*$/$1/;
    push @users, $user;
}
close F;

my $pass = Apache::Htpasswd::Perishable->new($password_file) or die
"Could not open password file.";
foreach my $user (@users) {
    $pass->htDelete($user) unless $pass->expire($user) > 0;
}

Apache::AuthExpire, on the other hand, implements timeouts on "login sessions." That is, a user must reauthenticate after a certain period of inactivity. This gives you protection against the user who steps away from her computer for a few moments, leaving herself "logged in."

As previously discussed, HTTP is stateless and so does not really have a concept of being logged in. However, by watching repeated connections from the same address, such a state can be simulated.

To use the expiring functionality offered by Apache::AuthExpire, download the module from CPAN, and install it:

# perl -MCPAN -e shell
cpan> install Apache::AuthExpire

Then configure your Apache server to use this module for your authentication handler.

PerlAuthenHandler Apache::AuthExpire
PerlSetVar DefaultLimit 7200

The given example will time out idle connections after 7200 seconds, which is 2 hours.

See Also

    [ Team LiB ] Previous Section Next Section