NAME
CGI::Auth - Simple session-based password authentication for CGI applications
SYNOPSIS
require CGI::Auth;
my $auth = new CGI::Auth({
-authdir => 'auth',
-formaction => "myscript.pl",
-authfields => [
{id => 'user', display => 'User Name', hidden => 0, required => 1},
{id => 'pw', display => 'Password', hidden => 1, required => 1},
],
});
$auth->check;
DESCRIPTION
CGI::Auth
provides password authentication for web-based applications. It uses server-based session files which are referred to by a parameter in all links and forms inside the scripts guarded by CGI::Auth
.
At the beginning of each script, a CGI::Auth
object should be created and its check
method called. When this happens, check
checks for a 'session_file' CGI parameter. If that parameter exists and has a matching session file in the session directory, check
returns, and the rest of the script can execute.
If the session file parameter or the file itself doesn't exist, check
presents the user with a login form and exits the script. The login form will then be submitted to the same script (specified in -formaction
). When check
is called this time, it verifies the user's login information in the userfile, creates a session file and provides the session file parameter to the rest of the script.
CREATING AND CONFIGURING
Before anything can be done with CGI::Auth
, an object must be created:
my $auth = new CGI::Auth( \%options );
Parameters to new
The new
method creates and configures a CGI::Auth
object using parameters that are passed via a hash reference that can/should contain the following items (optional ones are indicated):
-cgi
-
(optional)
This parameter provides
CGI::Auth
with a CGI object reference so that the extra overhead of creating another object can be avoided. If your script is going to use CGI.pm, it is most efficient to create the CGI object and pass it toCGI::Auth
, rather than both your script and Auth having to create separate objects.Note: As of version 2.4.3,
CGI::Auth
can now be used withCGI::Simple
. This hasn't been tested thoroughly yet, so use caution if you decide to do so. -admin
-
(optional if
-formaction
given)This parameter should be used by command-line utilities that perform administration of the user database. If Auth is given this parameter, it will only allow command-line execution (execution from CGI will be aborted).
-authdir
-
(required)
Directory where Auth will look for its files. In other words, if
-sessdir
,-userfile
,-logintmpl
,-loginheader
or-loginfooter
are scalars and do not begin with a slash (i.e., are not absolute paths), this directory will be prepended to them. -sessdir
-
(optional, default = 'sess')
Directory where Auth will store session files. These files should be pruned periodically (i.e., nightly or weekly) since a session file will remain here if a user does not log out.
-userfile
-
(optional, default = 'user.dat')
File containing definitions of users, including login information and any extra parameters. This file will be created, edited and read by
CGI::Auth
and its command-line administration tool. -logintmpl
-
(optional, excludes
-loginheader
and-loginfooter
if present)Template for use with
HTML::Template
. The template can be given in one of three ways:An
HTML::Template
object reference,A hash containing parameters for
HTML::Template->new
, orA filename (then
-logintmplpath
can be the path parameter).
The template must contain a form for the user to fill out, and it is recommended that the form not contain any elements with names beginning with 'auth_', since these are reserved for
CGI::Auth
fields.A sample template file (
login.html
) is included in the extra subdirectory of this package.For a list of what should be included in the template, see "Template Variables" and "Template Loops" below.
-logintmplpath
-
(optional, default = [])
List of search path(s) for
HTML::Template
files (the 'path' option). This is used only if-logintmpl
is a filename. Otherwise, the path option must be passed toHTML::Template->new
directly. -loginheader
-
(optional, default = 'login.head' or a simple default header)
Header for login screen.
NOTE:
-loginheader
and-loginfooter
are ignored if-logintmpl
is provided. -
(optional, default = 'login.foot' or a simple default footer)
Footer for login screen.
NOTE:
-loginheader
and-loginfooter
are ignored if-logintmpl
is provided. -formaction
-
(optional if
-admin
given)URL of calling script. This is used by the login screen as the form's "action" property.
-authfields
-
(required)
Array of hashes defining fields in user database. This requires at least one field, which must be 'required' and not 'hidden'. Any other fields can be used to authenticate the user or to contain information about the user such as groups, access levels, etc. Once a user has logged on, all of his fields are available through the
data
method. However, any fields that are marked 'hidden' will be crypted and not readable by the script.Each field in the
-authfields
anonymous array is a hash containing 4 keys:'id' ID of the field. This must be unique across all fields. 'display' Display string which is presented to the user. 'hidden' Flag (0 or 1) that determines whether this field is hidden on the login screen and encrypted in the user file. 'required' Flag (0 or 1) indicating whether this field must be given for authentication.
Here is an example of a simple username/password scheme, with one extra data parameter:
-authfields => [ {id => 'user', display => 'User Name', hidden => 0, required => 1}, {id => 'pw', display => 'Password', hidden => 1, required => 1}, {id => 'group', display => 'Group', hidden => 0, required => 0}, ],
-timeout
-
(optional, default = 60 * 15, 15 minutes)
The timeout value in seconds after which an unused session file will expire.
-cgiprune
-
(optional, default = false)
Whether to allow calls to prune in CGI mode. If your CGI scripts need (or want) to delete old session files, this will have to be set to true. I can't think of any particular reason not to allow this, but it isn't allowed by default.
-md5pwd
-
(optional, default = false)
Whether to use an MD5 hash for hidden fields in the user data file. If false, the Perl built-in
crypt
is used twice (via theDoubleCrypt
sub below), so hidden fields are restricted to 16 characters. If true, MD5 hashes are used, and there is no length restriction for hidden fields.If this option is changed, the user data file will have to be recreated using MD5 hashes, so it's best to make this decision at the beginning.
Using MD5 hashes will result in a slight performance hit when logging in. This will probably not be noticeable at all.
Template Variables
These template variables are required. The names of these are case-insensitive by default. See HTML::Template for more information.
Message
-
A message to the user, such as "Login failed", "Session expired", etc...
NOTE: This variable might be left blank when the form is created. So don't depend on it having a value.
Form_Action
-
The 'action' property of the form that submits the authentication information.
Button_Name
-
The 'name' property of the submit button on the form. The tag for the button should look something like this:
<input type=submit name="<TMPL_VAR Name=Button_Name>" value="Submit">
The 'value' property of the submit button can be anything.
Template Loops
These loops must exist in the template. The names of these are case-insensitive by default. See HTML::Template for more information.
Auth_Fields
-
Provides variables for each required Auth field. These are the fields which will be filled in by the user when logging in. The following variables are provided:
Display_Name
-
The display name of the field, e.g., "User Name" or "Password".
Input_Name
-
The 'name' property of the text input for the field.
Input_Type
-
The type, 'text' or 'password', of the input, depending on whether this field is hidden or not.
PUBLIC METHODS
There are two groups of public methods in CGI::Auth. The CGI-mode methods are called from CGI scripts for the purposes of authenticating a user and managing sessions. The command-line methods are used only in command-line scripts, such as the authman.pl sample userbase manager script. The latter methods will abort execution if they are run in a CGI environment.
Initialization Methods
These are used for creating a CGI::Auth
object.
new
-
Constructor. It accepts as a parameter a hash reference holding named options. For a list and descriptions of these options, see "Parameters to
new
". init
-
Performs processing of options passed to
new
. This should not be called directly.
CGI-mode Methods
These methods are called from CGI scripts.
check
-
Ensures authentication. If the session file is not present or has expired, a login form is presented to the user. A call to this method should occur in every script that must be secured, before the script prints anything to the browser.
endsession
-
Deletes the session file so that the user must log in again to gain access.
Returns 1 if session file deleted successfully, 0 if an error occurred ($! will contain the error), or -1 if the session file did not exist.
setdata
-
Sets auth data fields.
data
-
Returns a given data field. The field's ID is passed as the parameter, and the data is returned. The special field 'sess_file' returns the name of the current session file in the
-sessdir
directory. formfield
-
Returns the session file parameter as a hidden input field suitable for inserting in a <FORM>, e.g.:
'<input type=hidden name="auth_sessfile" value="DBEEL87CXV7H">'
urlfield
-
Returns the session file parameter as a field suitable for tacking onto the end of an URL (such as in a link), e.g.:
'auth_sessfile=DBEEL87CXV7H'.
Command-line Methods
These methods are used for user maintenance. They cannot be run under a CGI environment. Use them only in command-line programs as an administrator (or as a user with write access to the user data file).
adduser
-
The parameters are an ordered list of data values for the @authfields. For example:
$auth->adduser('KAM', 'smokey'); # Branchname, Password
listusers
-
Prints a list of users in the user file.
viewuser
-
Prints details for one user. The parameter is the user's 'field 0' value.
deluser
-
Deletes a user. The parameter is the user's 'field 0' value.
prune
-
Prunes the session file directory by deleting session files that have expired. This can be called in CGI mode if '-cgiprune' is set to true.
PRIVATE METHODS
There are also some private methods. Use of them by unauthorized dirrty scripts is a federal offence in some jurisdictions, carrying a maximum sentence of yearly noogies by yours-truly. This may or may not be legal in your country.
GetUserData
-
Fetches a user's auth data from the user file. The data fields are returned as a list, in the order in which they appear in the data file.
PrintLoginForm
-
Prints the login form using either an
HTML::Template
or a header and footer.This is called by
check
when the user is not authenticated.This method hands off either to
PLF_template
or toPLF_headerfooter
. PLF_template
-
Prints the login form using an HTML::Template. It uses the value of the logintmpl property to get the template.
-
Prints the login form using a header and footer. It uses the values of the loginheader and loginfooter properties.
FormFields
-
Returns HTML code for placing existing CGI parameters on a form so that the login process is transparent to the calling script.
For any single-valued parameters, it creates a hidden
<input>
control, and for any multi-valued parameters, it creates a hidden (i.e.,style="display: none"
)<select>
control with all of its values. CreateSessionFile
-
Creates a session file in the session file directory.
OpenSessionFile
-
Opens the session file and returns the user's id (field0) if successful.
The return value is one of three things:
Field 0 value from session file if successful,
0 if the session has expired, or
undef if the session file doesn't exist or can't be opened.
HELPER FUNCTIONS (not members)
Feel free to use and abuse these. They just do dirty little jobs.
DenyCGI
-
Exits if run as CGI. This could be made a little more intelligent. The command-line methods call this function as their very first act.
DoubleCrypt
-
Performs two crypt calls with the same salt, so that the limit of characters in passwords is doubled from 8 to 16. It's probably a good idea to use an MD5 hash or some other, more sophisticated alternative.
MD5Crypt
-
Performs an MD5 hash on the password given and returns the hash as a 24-byte Base64 string of the hash. Requires the Digest::MD5 module.
This is used instead of DoubleCrypt if the -md5pwd option is set.
NOTE ON SECURITY
Any hidden fields such as passwords are sent over the network in clear text, so anyone with low-level access to the network (such as an ISP owner or a lucky/skilled hacker) could read the passwords and gain access to your application. CGI::Auth
has no control over this since it is currently a server-side-only solution.
If your application must be fully secured, an encryption layer such as HTTPS should be used to encrypt the session so that passwords cannot be snooped by unauthorized individuals.
It would be adequate to use HTTPS only for the login process, and avoid the overhead of encryption during the rest of the session. But I expect that this would require modification of this module.
SEE ALSO
BUGS
CGI::Auth
doesn't use cookies, so it is left up to the script author to ensure that auth data (i.e., the session file) is passed around consistently through all links and entry forms.
AUTHOR
C. Chad Wallace, cmdrwalrus@canada.com
If you have any suggestions, comments or bug reports, please send them to me. I will be happy to hear them.
COPYRIGHT AND LICENCE
Copyright (c) 2001, 2002, 2003 C. Chad Wallace. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.