NAME

Liz::Authenticate - generic module for Apache access authentication


SYNOPSIS

 <Directory /export/home/local/www/intranet>
 AuthName          xxLINK Intranet
 AuthType          Basic
 PerlAuthenHandler xxLINK::Intranet
 Require           valid-user
 </Directory>

 sub Intranet { Liz::Authenticate::handler( @_ ) }

or:

 <Directory /export/home/local/www/liz>
 AuthName          Private Liz
 AuthType          Basic
 PerlAuthenHandler xxLINK::Liz
 Require           valid-user
 </Directory>

 sub Liz { Liz::Authenticate::handler( shift,\&handlerLiz ) }

 sub handlerLiz {
 my( $user,$password,$filename ) = @_;
 return 'Not Liz' if $user ne 'liz';
 return 'Not really Liz' if $password ne 'zippo';
 }


DESCRIPTION

The Liz::Authenticate module allows for configurable HTTP basic authentication using Liz::SQL compatible databases or any other storage of authentication data.

When using it together with Liz::SQL compatible databases, it provides a basic interface for keeping a user name, password, text info, numerical ID and options with an authentication record.

The module provides a number of primitives that can be further customised for any need necessary, or it can be used with the standard ``subscriber.lp'' Liz::Perl maintenance script.


Basic mode of operation

The Liz::Authenticate module is almost never called directly. Instead, a call to the Liz::Authenticate module is embedded in a subroutine of a client module, which provides certain types of information with regards to the configuration. This subroutine is referenced in the Apache server configuration (handler).

Using your own Authentication

By specifying a reference to a subroutine, it is possible to completely create your authentication method. This subroutine should expect to receive three parameters: the user name, the password specified and the filename for which authentication is needed. It should return an empty string if the authentication is successful, or a string filled with the reaseon for denial of access. Whatever happens inside that subroutine, is entirely up to the developer. For more info, see handler.

Standard Authentication

If no authentication subroutine is specified, then standard authentication is used. This uses the name of the subroutine from which Liz::Authenticate is called as the name a Liz::SQL table to check for authentication information. Most of this module's methods and subroutines apply to using this mode of authentication.

User Directories

It is optionally possible to restrict users to private subdirectories within the secured directory tree. Any attempt of a user to access a file from an other user's private directory, will cause an automatic redirect of the user to their own directory. See handler for more information.


Initialization

Initialization and storage of authentication information is entirely up to the developer if a custom authentication routine is used.

If standard authentication is used, any SuperUser Access will automatically create the necessary Liz::SQL compatible table(s) that are needed.


Password Encryption

Passwords in the Liz::Authenticate module are by default encrypted with the Liz::Password routine. For each client package that uses the Liz::Authenticate module it is possible to specify your own routine that performs the password encryption.

Whenever an authentication must be done, the package for which autentication is to be done, is checked for the existence of the routine ``Password''. If it exists, it is expected to receive the uncrypted password and return the the crypted version of the password. For example:

 sub Password { crypt(shift,'xx') }

Please note that it is very unwise to change the method of password encryption after user records have already been entered, because the existing crypted password will never match using the new encryption method.


SuperUser Access

For each client package that uses the Liz::Authenticate module it is possible to specify your own superuser name and password that supercedes the default superuser name and password.

Whenever an authentication must be done, the package for which autentication is to be done, is checked for the existence of the routine ``SuperUser''. If it exists, it is expected to return two parameters: the superuser name and the crypted version of the password to check against. For example:

 sub SuperUser { 'superusername','0980hjlkbkjkty' ) }

Please note that the password string must be returned in crypted format. This is done to prevent anybody with read access to the Perl module to also gain access to the superuser access immediately also.


BASIC METHODS

The basic functionality of the Liz::Authenicate module is to act as a ModPerl Authenticate Handler (PerlAuthenHandler).


handler

Generic Authentication handler for use within client modules. A client (sub)module should supply the routine ``handler'' which in turn calls the handler routine in this package, passing the reference of a routine that does the actual check.

If no handler is given, check an xxAS compatible table as specified by the calling subroutine.

Input Parameters

 1 reference to routine that does the actual check or package::table specification
   (default: use callers package to create new object, use caller's
             subroutine as name of table to query and look for fields
             "username" and "password")
 2 relative directory to which the user should be limited
   (default: no limitation; otherwise directory, should be specified relative
             to the DOCUMENT_ROOT, with the string '$user' as indicator
             of the directory name to limit to, e.g. '/private/$user'.)
Output Parameters

 1 action to be performed by Apache
Note

The check routine should expect three input parameters: the username to check, the password given by the user and the name of the file for which access should be checked. It is expected to return the reason for denial of access (as a string) or to return undef if access should be granted.

Note

The environment variable $ENV{'REMOTE_USER_ID'} will be set with the value of the field ``userID'' in the table if the user is authenticated and allowed access. This is usually the ID of a contact in an OCASet, which allows quick retrieval of any extra information of the user.

If more than one record in the table matches the username, then the userID's will be joined by comma's in the environment variable $ENV{'REMOTE_USER_ID'}.

Example

Using the default access check handler of Liz::Authenticate and no user restriction to a specific directory.

 in Apache server configuration:

 <Directory /export/home/local/www/intranet>
 AuthName          xxLINK Intranet
 AuthType          Basic
 PerlAuthenHandler xxLINK::Intranet
 Require           valid-user
 </Directory>

 in xxLINK.pm:

 sub Intranet { Liz::Authenticate::handler( shift ) }
Example

Same as above, but now with an access restriction of users to subdirectories of '/private':

 in xxLINK.pm:

 sub Intranet { Liz::Authenticate::handler( shift,'','/private/$user' ) }
Example

Using a custom access check routine.

 in Apache server configuration:

 <Directory /export/home/local/www/liz>
 AuthName          Private Liz
 AuthType          Basic
 PerlAuthenHandler Client::Access
 Require           valid-user
 </Directory>

 in Client.pm:

 sub Access { Liz::Authenticate::handler( shift,\&_Access )
 sub _Access {
 # Obtain the parameters
 # Allow access if it is a graphics file
 # Disallow access if wrong user
 # Disallow access if wrong password
 my( $user,$password,$filename ) = @_;
 return if $filename =~ m#\.(gif|jpe?g|png|bmp)$#io );
 return 'Not client' if $user ne 'client';
 return 'Not really client' if $password ne 'zippo';
 }
 }

Note here that the access routine is embedded within the actual handler to prevent it from being called elsewhere.

Example

Same as above, but now with a specific user restriction to subdirectories of '/member'.

 in Client.pm, Access changed to:

 sub Access { Liz::Authenticate::handler( shift,\&_Access,'/member/$user' )


new

Create a Liz::Authenticate object for external usage.

Input Parameters

 1 package::table for which to create object
Outpur Parameters

 1 instantiated Liz::Authenticate object
Example

 $access = Liz::Authenticate->new( 'Recron::MemberAccess' );


xxAS SUBROUTINES AND METHODS

The following subrouutines and methods are intended as an upgrade solution to the old PHP-based xxLink Authoring System (xxAS). The xxAS system used one database with a table for each different client authentication need.

In the Liz/ModPerl environment and its persistent database connections, it makes much more sense to put access tables in the client database, thus allowing access to the same database for user access authentication as well as other things in that client database on the same persistent database connection.


xxAS

This subroutine performs the standard xxAS authentication for a given user name, password, package and identification name. It should only be called in those situations where a ``normal'' xxAS authentication is not enough, but it is still handy to use the standard xxAS authentication structure (as opposed to devising a completely new authentication method).

Input Parameters

 1 user name
 2 password
 3 package name::identification name
Output Parameters

 1 reason for failed authentication
   (undef: authenticated ok)
 2 object with which xxAS compatible authentication was performed
Example

Configuration in httpd.conf:

 PerlAuthenHandler      Client::MemberAccess

In Client.pm:

 sub MemberAccess {
   Liz::Authenticate->handler( shift,\&ZipDirCheck );

   sub ZipDirCheck {

 #  Obtain the parameters
 #  Do "normal" xxAS authentication
 #  Return with error if there is a reason to fail
 #  Return it's ok if we don't need to do an extra check

     my ($user,$password,$filename) = @_;
     my ($reason,$object) =
      Liz::Authenticate::xxAS( $user,$password,'Client::MemberAccess' );
     return $reason if $reason;
     return unless $filename =~ m#/zip/#i;

 #  Obtain the extra info of the user
 #  Return with error if the right option is not set
 #  Return indicating ok

     my ($info,$options) = $object->UserInfo( $user );
     return "Sorry, no zip directory access for $info" if $options =~ m#1#;
     return;
   }
 }


Object

This subroutine returns the Liz::SQL object that was used for the last xxAS compatible authentication.

Output Parameters

 1 the last Liz::Authenticate object
Example

 ($info,$options,$ID,$maintainer) = Liz::Authenticate::Object->UserInfo;
 if( $maintainer ) {
   print "allow extra options for maintainers\n";
 }


Package

Return the name of the package for which standard authentication is being performed.

Output Parameters

 1 the package for which we're authenticating
Example

 <PRINT "join( '::',Liz::Authenticate::Object->Get( qw(Package Table) ) )">


Table

Return the name of the table token for which standard authentication is being performed.

Output Parameters

 1 the table token for which we're authenticating
Example

 <PRINT "join( '::',Liz::Authenticate::Object->Get( qw(Package Table) ) )">


Count

Return the number of users that are currently available.

Output Parameters

 1 the number of users in the table
Example

 $users = Liz::Authenticate::Object->Count;


Users

Return a list of users in the indicated xxAS compatible database matching the optionally specified wildcard and/or numeric limitation.

Input Parameters

 1    name of table to be checked
      (default: field "TABLE")
 2    additional query to be performed
      (default: none)
 3    ordinal number of first user to be returned
      (default: 1 )
 4    number of users to be returned
      (default: rest)
 5    return users in form "username\tuserID"
      (default: just return user name)
Output Parameters

 1..N the names of the users that matched


UserID2Name

Convert a userID to a username\tuserID combination that can be used to obtain information from. Usually needed for being able to link an OCASet::Contact to a Liz::Authenticate user.

Input Parameters

 1 userID to search name for
 2 name of table to be checked
   (default: field "TABLE" in object)
Output Parameters

 1 username\tuserID string
   (undef if not found)
Example

 $user = $object->UserID2Name( $ID ) if $ID;


UserInfo

Returns the user info of the current user after a successful xxAS compatible authentication when called as a subroutine. Handy for doing additional checks on the user.

Sets or returns the user info of a particular user in an xxAS compatible table when called as a method.

Input Parameters

 1 name of user to be checked
   (default: current user, can be specified as a "username\tuserID" pair)
 2 name of table to be checked
   (default: field "TABLE" in object)
 3 new extra information
   (default: no change)
 4 new options
   (default: no change)
 5 new password
   (default: no change)
 6 new userID
   (default: no change)
Output Parameters

 1 current/old extra information
 2 current/old options
 3 current/old userID
 4 current maintainer flag
Example

 ($info,$options,$ID,$maintainer) = Liz::Authenticate::UserInfo;

or:

 $object = Liz::Authenticate::Object;
 ($info,$options,$ID,$maintainer) = $object->UserInfo( $user );


UserAdd

Add a new user to the indicated table with the specified information.

Input Parameters

 1 name of user to be added
 2 name of table in which to add user
   (default: field "TABLE" in object)
 3 information associated with user
   (default: none)
 4 options associated with user
   (default: none)
 5 password of user
   (default: none)
 6 userID of user
   (default: 0)
Example

 $object = Liz::Authenticate::Object;
 $object->UserAdd( $username,'',$info );
 if( $error = $object->Error ) {
   print "Error: $error\n";
 }


UserDelete

Deletes the indicated user from the indicated xxAS compatible table.

Input Parameters

 1 name of user to be deleted
   (can be specified as a "username\tuserID" pair)
 2 name of table to be checked
   (default: field "TABLE" in object)
Example

 $object = Liz::Authenticate::Object;
 $object->UserDelete( $user );


UserExists

Returns the number of indicated users that exist in the indicated xxAS compatible table. Can be either 0 (none), 1 or more than one if only a user name is checked and multiple user names with different userID's exist in the table.

Input Parameters

 1 name of user to be checked
   (can be specified as a "username\tuserID" pair)
 2 name of table to be checked
   (default: field "TABLE" in object)
Output Parameters

 1 number of users matching the name and optionally ID
Example

 $object = Liz::Authenticate::Object;
 print "User $user exists\n" if $object->UserExists( $user );


AUTHOR

Elizabeth Mattijsen ( lizperl@INC.nl )


COPYRIGHT

(C) 1998-2000 International Network Consultants


HISTORY

Version 0.67, 6 May 2000

Added extra handling in handler of cases in which the protection is not set to OK already: specifically for URL with directory names and no trailing slash.

Version 0.66, 3 December 1999

Put module name between quotes to fix obscure bug in Perl 5.005x under ModPerl in method xxAS.

Version 0.65, 14 October 1999

Adapted method handler to use the new xxAS subroutine.

Added new subroutine xxAS to perform xxAS style authentication.

Changed to new source typography.

Version 0.64, 30 September 1999

Now no longer puts Exporter in ISA: it is not needed.

Added check for the validity of the request object in handler.

Version 0.63, 16 August 1999

Fixed problem in handler which would cause an internal server error if the table did not exist.

Version 0.62, 9 July 1999

Changed CREATE TABLE in method handler to use the new Liz::SQL 'create' method.

Version 0.61, 23 June 1999

Changed from using method ``Exists'' to ``Count'' in method handler to check whether a table exists, which is much faster.

Version 0.6, 5 April 1999

Added quite some general documentation under the DESCRIPTION header.

Added method UserID2Name which converts a userID to a username\tuserID combination. Needed for those situation where only the userID is known.

It is now possible to specify a method of password encryption for each package that uses the Liz::Authenticate module.

The previously undocumented SUPERDUPER feature, has now been changed to ``SuperUser'' and can be customised for each package that makes use of the Liz::Authenticate module.

Method Users now allows specification of a flag to return usernames with userIDs in a TAB-delimited format (``username\tuserID'').

Methods UserDelete and UserExists now allow the username to be specified as a string containing the username and userID, seperated by a TAB delimiter (``username\tuserID'').

Support added for multiple usernames with different userID's and different passwords.

Version 0.54, 3 April 1999

Changed table definition to that multiple email addresses are allowed as long as the associated userID is different. This should not matter with older tables, so that a database version change is not needed.

Version 0.53, 4 February 1999

Changed second parameter of method Users to ``additional query'' to allow for more flexibility.

Added method Count as a local method, because the inherited method looked at the wrong table.

Version 0.52, 5 January 1999

Fixed problem with images that were redirected for maintainers.

Version 0.51, 4 January 1999

Method UserExists added: allows simple checking whether a particular user exists.

Method new added: allows external access to tables.

Methods Package and Table added for obtaining information for which we are authenticating.

Now also sets field ``PACKAGE'' with the name of the package for which we are authenticating.

Fixed problem with creating new tables.

Version 0.5, 31 December 1998

Added support for generic Package::Table specification and the option to limit the user to a specific directory in method handler.

Added more configuration examples to method handler.

Version 0.4, 14 October 1998

Support for userID added.

Probably fixed problem with the Object subroutine also, by always fully qualifying $Liz::Authenticate::OBJECT.

Version 0.31, 6 October 1998

Reduced memory footprint by using fully qualified global variables.

Version 0.3, 19 July 1998

New method/subroutine Object added: returns the object created with the xxAS compatible authentication.

New method Users added: obtain complete or partial listing of users in an xxAS compatible table.

New method UserInfo added: obtain or change information in a xxAS compatible table. Can also be called as a subroutine: then only returns information of the current user.

New method UserAdd added: add a named user to the indicated table.

New method UserDelete added: delete a named user from the indicated table.

Auto-creation of xxAS compatible table added if the super user.

Version 0.2, 17 July 1998

Documentation extended.

The filename for which access should be checked, is now also passed to the handler routine of Client library.

The default handler now always allows access to files with the extension .gif, .jpg, .jpeg, .png and .bmp. Since graphics are usualy not that important on a protected site, it does not really make sense to check access for every little button on a grpahics intensive site. This should reduce the number of database connections needed significantly.

Version 0.1, 10 July 1998

First version of this true Perl module.