The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Apache::AppSamurai::AuthBase - Base module for all AppSamurai authentication sub modules.

SYNOPSIS

All Apache::AppSamurai authentication modules should inherit from this base module. This module is never used directly. See Apache::AppSamurai for details on authentication module config and use within AppSamurai.

DESCRIPTION

All Apache::AppSamurai authentication submodules should inherit from Auth::Base. This module provides the a standard framework including config, initialization, basic input validation and filtering, error checking, and logging needed by all AppSamurai auth modules.

Auth modules must each define at least an "Authenticator()" method to accept the username (credential_0) and the mapped credential (password) and return 0 on failure and 1 on success. Other commonly overridden methods are "Configure()" which includes the setup of the $self-{conf} > configuration hash, and "Initialize()" which performs any needed pre-authentication setup work.

METHODS

new()

Runs Configure(), (passing along any arguments), which creates and populates the %{$self->{conf}} hash. Then creates and sets the $self->{init} flag to 0, and creates and clears the @{$self->{errors}} array.

The instance is then returned.

Alternately, if a $self->{conf}{user} and $self->{conf}{pass} exist, $self->Authenticate() is called with those values and the result is returned. (Note - This behavior is not currently used by Apache::AppSamurai).

Configure()

Creates and populates the instance's configuration hash, %{$self->{conf}}. Each auth module has a basic set of default configuration items from Auth::Base, plus any additional items added in its own Configure() method, plus any configuration items passed in when Configure() is called. Arguments take precedence over defaults in the particular auth module, and the auth module's defaults take precedence over those in Auth::Base.

See "EXAMPLES" for an example of overriding Configure() while preserving the Auth::Base defaults.

The following keys are set in Auth::Base, and are also used by methods in Auth::Base for input validation, logging, and other purposes.

UserMin

Minimum characters in username. (Default: 3)

UserMax

Maximum characters in username. (Default: 256)

UserChars

Characters allowed in the username. These are matched with a Perl regex, and character classes like \w and \d are allowed. (Default: \w\d_\-\.)

UserStripWhite

If set to 1, strips any whitespace surrounding the username. (Default: 1)

UserUc

If set to 1, converts the username to all caps before checking. (Default: 0)

UserLc

If set to 1, converts the username to all lower case before checking. (Default: 0)

PassMin

Minimum characters in password. (Default: 4)

PassMax

Maximum characters in password. (Default: 16384)

PassChars

Characters allowed in a password. These are matched with a Perl regex and character classes like "\w" and "\d" are allowed. (Default: \w\d !\@\#\$\%\^\&\*:\,\.\?\-_=\+)

PassStripWhite

If set to 1, strips any whitespace surrounding the password. (Default: 0)

DefaultLogLevel

The "AddError()" method can take two styles of input when adding log lines to the object's errors array. This option sets the logging severity for log lines passed in without a specific severity set. The valid values are the same as those allowed in the Apache LogLevel directive: emerg, alert, crit, error, warn, notice, info, and debug. (Default: error)

Initialize()

Performs initial setup of object instance, returning 1 on success or 0 on failure. Checks the $self->{init} flag for a previous run, and returns 1 of object has already been initialized. Once completed, the $self->{init} flag is set to 1 before returning.

See "EXAMPLES" for a sample overridden Initialize() method.

Authenticator()

Apache::AppSamurai::AuthBase::Authenticator() is just a skeleton and must be overridden for each authentication module. It is called with an object reference and takes the username and password as two scalar inputs. It must return 0 on an authentication failure or any other failure. 1 should only be returned on a clean and successful authentication.

Please carefully test this method in any authentication module before using in production! Also, it is recommended that the last command inside all Authenticator() methods is return 0;. This helps ensure that if there is some sort of unanticipated failure, or unanticipated fall through condition, there is one more obstacle in the way of a potential authentication bypass.

See "EXAMPLES" for a simple example of a Authenticator() method.

Authenticate()

This is called by Apache::AppSamurai to perform the authentication check. It is called with an object reference and takes the username and password as scalar arguments.

The username is validated using "CheckInputUser()", and then the password is validated using "CheckInputPass()". (If either of those fail, an error is added and 0 is returned.)

After validation, "Initialize()" is called if the $self->{init} flag has not been set. (Note - Apache::AppSamurai calls Initialize() separately. This functionality is added as a fail safe, or for testing.)

Finally, the object's "Authenticator()" method is called to perform the actual work of checking the credentials. It's result is returned by Authenticate() to the caller.

Authenticate() should not generally need to be overridden.

CheckInputUser()

Is called with an object ref and expects a scalar username as its only argument. If successful, the validated username is returned. In case of a failure or violation, undef is returned.

CheckInputUser() uses settings out of $self->{conf} as follows:

  • If UserStripWhite is 1, surrounding whitespace is removed.

  • The username is checked against UserChars.

  • The length of the username is checked against UserMin and then UserMax.

  • If UserUc is 1, the username is converted to all caps.

  • If UserLc is 1, the username is converted to all lower case. (Note - UserUc takes precedence if both are set.)

If all conditions are met, the validated and cleaned username is returned.

CheckInputUser() should not generally need to be overridden unless an authentication module needs more extensive filtering.

CheckInputPass()

Is called with an object ref and expects a scalar password as its only argument. If successful, the validated password is returned. In case of a failure or violation, undef is returned.

Note - "password" is used in the descriptions below. This equates the whatever data, (password, passphrase, PIN, whatever), will be passed as an authentication credential to the authentication module.

CheckInputPass() uses settings out of $self->{conf} as follows:

  • If PassStripWhite is 1, surrounding whitespace is removed. (This is generally not a good idea unless the specific authentication system does not support whitespace in the password.)

  • The password is checked against PassChars. Try to allow as many characters as the underlying authentication system can safely support to avoid reducing the strength of the passwords or other authentication data that can be used. (Note - The default PassChars should be decent for most uses, however, it may be loosened or restricted more in future versions.)

  • The length of the password is checked against PassMin and then PassMax. Once again, avoid limiting the maximum password length as much as safely possible.

If all conditions are met, the validated and cleaned password is returned.

CheckInputPass() should not generally need to be overridden unless an authentication module needs more extensive filtering.

AddError()

Adds a new log message to the @{$self->{errors}} array, which is returned to a then processed by Apache::AppSamurai.

AddError() is called using an object reference and expects one of two types of calls:

  • One argument - This should be a single scalar containing the text to be logged. It will be added to the errors using the log level defined in the DefaultLogLevel configuration option.

  • Two arguments - This should be scalar containing the log level to use, followed by a scalar with the message to be logged.

AddError() should not generally need to be overridden.

Errors()

Called using an object reference and returns an array of anonymous arrays containing loglevel, logmessage pairs. If no log messages exist, undef is returned.

Errors() is called by Apache::AppSamurai after using the authentication module's Authenticate() method. It generally does not need to be overridden.

EXAMPLES

Here is an example authentication module based on Auth::Base. Let's call it Apache::AppSamurai::AuthGarbage and have it use the fictitious module Junk::Dumpster to check credentials.

 package Apache::AppSamurai::AuthGarbage;

 use Apache::AppSamurai::AuthBase;
 use Junk::Dumpster;  # Kids, don't try this at home 

 # Inherit the AuthBase wind...
 @ISA = qw( Apache::AppSamurai::AuthBase );
 
 # Override the Configure method to add special config options
 sub Configure {
     my $self = shift;

     # Pull defaults from AuthBase and save.
     $self->SUPER::Configure();
     my $conft = $self->{conf};
     
     # Initial configuration.  Put defaults here before the @_ args are
     # pulled in.
     $self->{conf} = { %{$conft},
                       Crud => 1,
                       Dumpster => 'supadumpy',
                       @_,
                     };
     return 1;
 }

 # Set an Initiate function to do any required setup and initialization
 # (Creating object instances, pre-flight checks, etc.)
 sub Initialize {
     my $self = shift;
 
     # Create Junk::Dumpster instance
     $self->{client} = new Junk::Dumpster(crud => $self->{conf}{Crud});
 
     # Set init flag
     $self->{init} = 1;
     return 1;
 }

 # Make authentication check
 sub Authenticator {
     my $self = shift;
     my $user = shift;
     my $pass = shift;
     my ($response, $error, @tmp, $check, $realm);
     
     # This is silly.  There is no Junk::Dumpster....
     $response = $self->{client}->IsItInDere($user,$pass);
     
     if ($response) {
         # You passed the test!
         return 1;
     } elsif ($!) {        
         # An abnormal failure: Log an error
         $self->AddError('error', "Failure from Junk:Garbage: $!");
         return 0;
     }
 
     # Normal failure fall through.  Log the failure and kick back
     $self->AddError('warn', "Junk::Garbage login failure for \"$user\"");
 
     return 0;
 }

SEE ALSO

Apache::AppSamurai, Apache::AppSamurai::AuthBasic

AUTHOR

Paul M. Hirsch, <paul at voltagenoir.org>

BUGS

See Apache::AppSamurai for information on bug submission and tracking.

SUPPORT

See Apache::AppSamurai for support information.

COPYRIGHT & LICENSE

Copyright 2008 Paul M. Hirsch, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.