Apache-AppSamurai

 view release on metacpan or  search on metacpan

lib/Apache/AppSamurai.pm  view on Meta::CPAN

    unless (scalar(keys %{$sessconfig})) {
	$self->Log($r, ('error', "GetSessionConfig(): No Session configuration found for $auth_name!"));
	return undef;
    }

    ## TODO    - This section of session autoconfig/defaults is pretty
    ##           inflexilbe and too tightly tied to HMAC_SHA and CryptBase64.
    ##           It should be abolished or moved out and into a generalized
    ##           pre-config module that can be called ONCE (at startup)

    # Use files for storage and locking by default
    (exists($sessconfig->{Store})) || ($sessconfig->{Store} = "File");
    (exists($sessconfig->{Lock})) || ($sessconfig->{Lock} = "File");

    # If files are being used, paths must be set
    if ($sessconfig->{Store} eq 'File' && !exists($sessconfig->{Directory})) {
	$self->Log($r, ('error', "GetSessionConfig(): ${auth_name}SessionDirectoy must be defined for the File session store"));
	return undef;
    }
    if ($sessconfig->{Lock} eq 'File' && !exists($sessconfig->{LockDirectory})) {
	$self->Log($r, ('error', "GetSessionConfig(): ${auth_name}SessionLockDirectoy must be defined for the File session lock"));
	return undef;
    }

    # Use HMAC_SHA and CryptBase64 for session creation and serialization
    # by default.
    (exists($sessconfig->{Generate})) || ($sessconfig->{Generate} = "AppSamurai/HMAC_SHA");
    (exists($sessconfig->{Serialize})) || ($sessconfig->{Serialize} = "AppSamurai/CryptBase64");
   
    # Check/clean ServerPass if present (else assume ServerKey set)
    if (exists($sessconfig->{ServerPass})) {
	# Set the key (note - GetServerKey logs the error, if any)
	($sessconfig->{ServerKey} = $self->GetServerKey($r)) || (return undef);
    }

    # We have to have a ServerKey at this point, in hex form.
    if (($sessconfig->{Generate} =~ /HMAC/i) || ($sessconfig->{Serialize} =~ /Crypt/i)) {
	unless (CheckSidFormat($sessconfig->{ServerKey})) {
	    # Bad server key format
	    $self->Log($r, ('error', "GetSessionConfig(): You must a valid ${auth_name}ServerPass or ${auth_name}ServerKey!"));
	    return undef;
	}
	
	# For speed, SerializeCipher should be set in the config
	if (!$sessconfig->{SerializeCipher}) {
	    # Attempt to load CryptBase64 module
	    unless (eval "require Apache::AppSamurai::Session::Serialize::CryptBase64") {
		$self->Log($r, ('error', "GetSessionConfig(): Could not load CryptBase64 while attempting to auto-select ${auth_name}SerializeCipher value: $!"));
		return undef;
	    }
	    # Use CryptBase64 cipher detection utility (Slower)
	    unless ($sessconfig->{SerializeCipher} = &Apache::AppSamurai::Session::Serialize::CryptBase64::find_cipher()) {
		# None found.  (Note - Check @allowedciphers in CryptBase64.pm
		# for supported ciphers)
		$self->Log($r, ('error', "GetSessionConfig(): Could not auto-detect a suitable ${auth_name}SerializeCipher value (Please configure manualy): $!"));
		return undef;
	    }
	}
    }
    
    # Set a 1hr Timeout if neither Timeout or Expire are set
    unless ($sessconfig->{Timeout} || $sessconfig->{Expire}) {
	$sessconfig->{Timeout} = 3600;
    }
    
    return $sessconfig;
}


# Compute/check server key from server pass, returning key.
sub GetServerKey {
    my ($self, $r) = @_;
    my $auth_name = ($r->auth_name()) || (die("GetServerKey(): No auth name defined!\n"));
    my $dirconfig = $r->dir_config;
    my $serverkey = '';
    
    if (exists($dirconfig->{$auth_name . "SessionServerPass"})) {
	my $serverpass = $dirconfig->{$auth_name . "SessionServerPass"};
	
	unless ($serverpass =~ s/^\s*([[:print:]]{8,}?)\s*$/$1/s) {
	    $self->Log($r, ('error', "GetServerKey(): Invalid ${auth_name}SessionServerPass (must be use at least 8 printable characters"));
	    return undef;
	}
	
	if ($serverpass =~ /^(password|serverkey|serverpass|12345678)$/i) {
	    $self->Log($r, ('error', "GetServerKey(): ${auth_name}SessionServerPass is $1...  That is too lousy"));
	    return undef;
	}
	
	unless ($serverkey = HashPass($serverpass)) {
	    $self->Log($r, ('error', "GetServerKey(): Problem computing server key hash for ${auth_name}SessionServerPass"));
	    return undef;
	}

    } elsif (exists($dirconfig->{$auth_name . "SessionServerKey"})) {
	$serverkey = $dirconfig->{$auth_name . "SessionServerKey"};

    } else {
	$self->Log($r, ('error', "GetServerKey(): You must define either ${auth_name}SessionServerPass or ${auth_name}SessionServerKey in your Apache configuration"));
	return undef;
    }
    
    # Check for valid key format
    unless (CheckSidFormat($serverkey)) {
	# Not good, dude.  This should not happen
	$self->Log($r, ('error', "GetServerKey(): Invalid server session key (CheckSidFormat() failure) for $auth_name"));
	return undef;
    }

    return $serverkey;
}


# Apply the configured BasicAuthMap to the passed in credentials
# BasicAuthMap allows for flexibly parsing a single line of authentication
# data into multiple credentials in any order.  (Keep those users happy...)
# Returns an array with the parsed credentials in order, or an empty set on
# failure.
sub ApplyAuthMap {
    my ($self, $r, $pass, $amc) = @_;
    my $auth_name = ($r->auth_name) || ('');
    my ($o, $m, $i, @ct);
    my @creds = ();

lib/Apache/AppSamurai.pm  view on Meta::CPAN

	}
    }
    
    return $keytext;
}

# Initiate a new session and return a session key.  Takes the $r request (for
# record keeping), the username, and an optional "alter list" to be used
# to change cookies and/or headers sent from the proxy to the backend server.
sub CreateSession {
    my ($self, $r, $username, $alterlist) = @_;
    (defined($alterlist)) || ($alterlist = {});    
    my (%sess, $sid, $sessconfig, $kt);
    
    # Extract the session config
    ($sessconfig = $self->GetSessionConfig($r)) || (die "CreateSession(): Unable to get session configuration while creating new session");
    
    # Create a session auth key to send back to send back as the cookie
    # value, and to use the HMAC-SHA and optional session file encryptor.
    # FetchKeysource returns "" by default, resulting in a fully randomized
    # key.
    $kt = $self->FetchKeysource($r);
    if (defined($kt)) {
	$sessconfig->{key} = CreateSessionAuthKey($kt);
    } else {
	$self->Log($r, ('warn', "CreateSession(): Failed to generate session authentication key: Session creation denied"));
	return undef;
    }
    
    # Check for valid looking key
    unless (CheckSidFormat($sessconfig->{key})) {
	$self->Log($r, ('warn', "CreateSession(): Bad session authentication key returned!  Session creation denied"));
	return undef;
    }

    # Run against the unique session tracker if configured.  (*Don't make
    # the same session twice)
    if ($sessconfig->{Unique}) {
	unless ($self->CheckTracker($r, 'SessionUnique', $sessconfig->{key})) {
	    $self->Log($r, ('warn', "CreateSession(): SessionUnique detected duplicate session authentication key!  Session creation denied"));
	    return undef;
	}
    }

    # Wrapped this in an eval, since Apache:Session dies on failures
    eval { tie(%sess, 'Apache::AppSamurai::Session', undef, $sessconfig); };
    if ($@) {
	$self->Log($r, ('error', "CreateSession(): Unable to create new session: $@"));
	return undef;
    }
    $sid = $sess{_session_id};

    # Make sure we received a good session ID.
    (CheckSidFormat($sid)) || (($self->Log($r, ('error', 'CreateSession(): Invalid Session ID Format on new Session'))) && (return undef));
    $self->Log($r, ('notice', "LOGIN: username=\"$username\", session=\"$sid\""));
    
    # Store some basics
    $sess{'username'} = $username;
    $sess{'ctime'} = time();
    
    # Track last access time if Timeout is set
    if ($sessconfig->{Timeout}) {
	$sess{'atime'} = $sess{'ctime'};
	$sess{'Timeout'} = $sessconfig->{Timeout};
    }

    # Set hard expiration time if Expire is set
    if ($sessconfig->{Expire}) {
	$sess{'etime'} = $sess{'ctime'} + $sessconfig->{Expire};
	$sess{'Expire'} = $sessconfig->{Expire};
    }

    # Apply passback cookies to response, and pull in updated alterlist
    if (defined($alterlist->{cookie})) {
	$alterlist = $self->AlterlistPassBackCookie($alterlist, $r);
    }

    # If present, save Authorization header to detect future changes,
    # then prepend an alterlist rule to delete the header to prevent
    # pass though to the backend server.  (If needed, a separate
    # alterlist rule to add an Authorization header should be set
    # by a auth module.)
    if ($r->headers_in->{"Authorization"}) {
	$sess{'Authorization'} = $r->headers_in->{"Authorization"};
	# Stick it in front in case we have an existing add
	# header from an auth module
	unshift(@{$alterlist->{header}}, 'delete:Authorization:');
    }

    # Save current alterlist to session
    $self->AlterlistSave($alterlist, \%sess);
    
    # Release session
    untie(%sess);
    
    # Return the session auth key
    return $sessconfig->{key};
}

# Destroy a session, rendering it forever useless.  Takes a request hash ref
# and a session hash ref as args.  (Session must be tied when DestroySession
# is called.)
sub DestroySession {
    my ($self, $r, $sess) = @_;

    # Call the delete method for the the tied hash.  Wrapped in eval goodness
    # since Apache::Session will die on error.
    eval { tied(%{$sess})->delete; };
    if ($@) {
        $self->Log($r, ('warn', "DestroySession(): Unable to destroy session: $@"));
        return undef;
    }

    return 1;
}


## TRACKER - A system to store persistant and shared data for various
## uses. This is yet more code that could be refactored and busted into
## external modules to allow for adding arbitrary stateful checks of
## all sorts of things, (like the authentication handlers).
## For now, only a small set of tracker types are provided,
## and all are defined in this module.

lib/Apache/AppSamurai.pm  view on Meta::CPAN

sub CheckTrackerAuthUnique {
    my $trak = shift;
    my $ch = HashAny(@_);
    my $time = time();

    # If defined, the jig is up!
    if ($trak->{$ch}) {
	die("CheckTrackerAuthUnique(): RULE VIOLATION: credkey=$ch\n");
    } else {
	# Set value to 
	$trak->{$ch} = 'ts' . $time . ":cnt1";
    }
        
    return 1;
}

# Check given tracker hash ($_[0]), make sure we have not seen the same
# session authentication key (cookie) before.  Stores a hash of session key
# string to minimize security risk.
sub CheckTrackerSessionUnique {
    my $trak = shift;
    my $ch = HashAny(@_);
    my $time = time();

    # If defined, the jig is up!
    if ($trak->{$ch}) {
	die("CheckTrackerSessionUnique(): RULE VIOLATION: sesskey=$ch\n");
    } else {
	# Set value to 
	$trak->{$ch} = 'ts' . $time . ":cnt1";
    }
        
    return 1;
}

# Check the last access time stamp, and update if needed, for a given session.
# Does NOT update the time if a fixed timeout has been set.
# Returns undef if the atime is more than the session's timeout age
# or if etime is set and is over the session's expire age.
sub CheckTime {
    my ($self, $sess) = @_;
    my $time = time();
    my $tdiff;
    my $ret = undef;

    # All sessions require at least a floating or fixed timeout!
    ($sess->{atime} || $sess->{etime}) or return undef;

    # Check the hard timeout first, if it exists.
    # This short circuits further checking since the hard timeout is king!
    if ($sess->{etime}) {
	if ($time >= $sess->{etime}) {
	    return undef;
	} else {
	    $ret = $sess->{etime};
	}
    }

    if ($sess->{atime}) {
	$tdiff = $time - $sess->{atime};
	if ($tdiff < $sess->{Timeout}) {
	    # We are still valid.  Update the time if we are over 60 seconds
	    # stale.
	    if ($tdiff >= 60) {
		$sess->{atime} = $time;
	    }
	    $ret = $sess->{atime};
	} else {
	    return undef;
	}
    }

    return $ret;
}


# The Alterlist functions manipulate and apply a list of transforms to apply to
# the headers and cookies of the client request before sending the request
# through to the backend server.  $self->{alterlist} is a hash containing
# one or more of the following container arrays:
#
# header
# ------
# @{$self->{alterlist}->{header}} - One or more header transforms, with the
#  syntax:
#                  ACTION:NAME:VALUE
#  ACTION - add, replace, or delete
#  NAME - Header name (or regex match for delete)
#  VALUE - New value of header for add or replace, else optional regex filter
#          for delete  (Prefix pattern with ! for negation)
#
# cookie
# ------
# @{$self->{alterlist}->{cookie}} - One or more cookie transforms, with the
#  syntax:
#                  ACTION:NAME:VALUE
#  ACTION - add, replace, delete, or passback
#  NAME - Cookie name (or regex match for delete)
#  VALUE - New value of cookie, or regex filter for delete action (Prefix
#          pattern with ! for negation)
# 
# Note - delete rules with optional value match pattern will delete only values
#        of a multi-value cookie that match the value pattern
#
# The special "passback" action passes cookies back to the web browser on
# login, This allows us to gather cookies from backend servers on login, but
# have the web browser maintain them.
#
# More containers can be added without modifying the generic functions.

# Load Alterlist rules from session and return a ref to the loaded alterlist
sub AlterlistLoad {
    my ($self, $sess) = @_;
    my ($sk,$rk);
    my $alterlist = {};

    # All alterlist save value start with al-
    foreach $sk (keys %{$sess}) {
	($sk =~ /^al\-([\w]+)$/) || (next);
	$rk = $1;
	@{$alterlist->{$rk}} = split("\n", $sess->{$sk});

lib/Apache/AppSamurai.pm  view on Meta::CPAN


 PerlSetVar BobAuthBasicLoginUrl C<https://bob.org/login>

For AuthName C<Bob>, set the C<LoginUrl> for the C<AuthBasic> authentication
module to C<https://bob.org/login>

See L<Apache::AppSamurai::AuthBase> for general authentication module
information.  If you need an authentication type that is not supported
by the authentication modules shipped with AppSamurai, and is not
available as an add on module, please review L<Apache::AppSamurai::AuthBase>
and use the skeletal code from AuthTest.pm, which is included under
/examples/auth/ in the AppSamurai distribution.

=head2 SESSION CONFIGURATION

Each Apache::AppSamurai instance must have its local (proxy server side)
session handling defined.
L<Apache::Session|Apache::Session> provides the majority of the session
framework.  Around Apache::Session is wrapped
L<Apache::AppSamurai::Session|Apache::AppSamurai::Session>, which
adds features to allow for more flexible selection of sub-modules.

Most Apache::Session style configuration options can be passed directly to the
session system by prefixing them with C<authnameSession>.

Module selection is slightly different than the default supplied with
Apache::Session.  Plain names, without any path or ::, are handled
exactly the same: Modules are loaded from within the Apache::Session
tree.  Two additional alternatives are provided:

=over 4

=item *

I<AppSamurai/MODULE> - Load I<MODULE> from under the
B<Apache::AppSamurai::Session> tree instead of the B<Apache::Session> tree.

=item *

I<PATH::MODULE> - Load I<PATH::MODULE> literally.  Note - Since :: is required
to be present, a root module name will not work.

=back

The most common configuration options follow.  See
L<Apache::AppSamurai::Session|Apache::AppSamurai::Session> and
L<Apache::Session|Apache::Session> for
more advanced options, like using a database for storage.

B<NOTE> - "Session" is shown prepending each of these directives, Inside
the L<Apache::AppSamurai::Session|Apache::AppSamurai::Session> and
L<Apache::Session|Apache::Session> documentation, "Session" is omitted.

=head3 SessionI<Expire> C<SECONDS>

(Default: 0)
The maximum session lifetime in seconds.  After a user has been logged in this
long, they are logged out.  (Ignores weather the user is idle or not.)


=head3 SessionI<Timeout> C<SECONDS>
(Default: 3600 (1 hour)).

The maximum time a session can be idle before being removed.  After a user has
not accessed the protected application for this many seconds, they are logged
out.

=head3 SessionI<Store> C<NAME>

(Default: File)
The session storage module name. "File" is the default, which maps to
B<Apache::Session::Store::File|Apache::Session::Store::File>
(Note - See the top of this section,
L</SESSION CONFIGURATION>, for details on the three ways to specify a path
for this option and the following options that point to a module.)

=head3 SessionI<Lock> C<NAME>

(Default: File)
The session locking module name.  "File" is used by default, which maps to
B<Apache::Session::Lock::File|Apache::Session::Lock::File>

=head3 SessionI<Generate> C<NAME>

(Default: AppSamurai/HMAC_SHA)
The session ID generator module name. "AppSamurai/HMAC_SHA" is used by default,
which maps to
L<Apache::AppSamurai::Session::Generate::HMAC_SHA|Apache::AppSamurai::Session::Generate::HMAC_SHA>
This special module takes a server key and a session authentication key and
returns a HMAC code representing the local ("real") session ID.  (Input and
output are all SHA256 hex strings that are passed in using the sessionconfig
hash.)

As this is tied closely into the current Apache::AppSamurai code, please do
not use an alternate serializer without first reviewing the related code.

=head3 SessionI<Serialize> C<NAME>

(Default: AppSamurai/CryptBase64)
The session data serializer module.  "AppSamurai/CryptBase64" is used by
default, which maps to
L<Apache::AppSamurai::Session::Serialize::CryptBase64|Apache::AppSamurai::Session::Serialize::CryptBase64>
This special module uses server key and a session authentication key to
encrypt session data using a block cipher before Base64 encoding it.
(All keys are 256 bit hex strings.)

Base64 allows for storage in file, database, etc without worrying about binary
data issues.  In addition, this module allows for safer storage of data on
disk, requiring both the local server key and the secret session key from the
user before unlocking the data.

L<Crypt::CBC|Crypt::CBC> is used with a support block cipher module to perform
encryption/decryption.  (See the next section for information on
configuring a cipher.)

As this is tied closely into the current Apache::AppSamurai code, please do not
use an alternate serializer without first reviewing the related code.

=head3 SessionI<SerializeCipher> C<CIPHER_MODULE>

(Default: undef)

lib/Apache/AppSamurai.pm  view on Meta::CPAN

 # PerlModule ModPerl::Registry

 # Load the main module and define configuration options for the 
 # "Example" auth_name
 PerlModule Apache::AppSamurai
 PerlSetVar ExampleDebug 0
 PerlSetVar ExampleCookieName MmmmCookies
 PerlSetVar ExamplePath /
 PerlSetVar ExampleLoginScript /login.pl

 # Defaults to All by may also be Any
 #PerlSetVar ExampleSatisty All
 
 # Optional session cookie domain (Avoid unless absolutely needed.)
 #PerlSetVar ExampleDomain ".thing.er"

 # Require secure sessions (default: 1)
 #PerlSetVar ExampleSecure 1

 # Set proprietary MS flag
 PerlSetVar ExampleHttpOnly 1

 # Define authentication sources, in order
 PerlSetVar ExampleAuthMethods "AuthRadius,AuthBasic"

 # Custom mapping of xxxxxx;yyyyyy Basic authentication password input
 # to specific and separate individual credentials. (default: undef)
 PerlSetVar ExampleBasicAuthMap "2,1=(.+);([^;]+)"

 
 ## Apache::AppSamurai::AuthRadius options ##
 # (Note - See L<Apache::AppSamurai::AuthRadius> for more info)
 PerlSetVar ExampleAuthRadiusConnect "192.168.168.168:1645"
 PerlSetVar ExampleAuthRadiusSecret "radiuspassword"

 
 ## Apache::AppSamurai::AuthBasic options.##
 # (Note - See L<Apache::AppSamurai::AuthBasic> for more info)
 
 # Set the URL to send Basic auth checks to
 PerlSetVar ExampleAuthBasicLoginUrl "https://ex.amp.le/thing/login"
 
 # Always send Basic authentication header to backend server
 PerlSetVar ExampleAuthBasicKeepAuth 1
 
 # Capture cookies from AuthBasic login and set in client browser
 PerlSetVar ExampleAuthBasicPassBackCookies 1
 
 # Abort the check unless the "realm" returned by the server matches
 PerlSetVar ExampleAuthBasicRequireRealm "blah.bleh.blech"
 
 # Pass the named header directly through to the AuthBasic server 
 PerlSetVar ExampleAuthBasicUserAgent "header:User-Agent"

 
 ## Session storage options ##
 # (Note - See L<Apache::AppSamurai::Session> and L<Apache::Session> for
 # more information.)
 
 # Inactivity timeout (in seconds)
 PerlSetVar ExampleSessionTimeout 1800

 # Use the File storage and lock types from Apache::Session
 PerlSetVar ExampleSessionStore "File"
 PerlSetVar ExampleSessionLock "File"

 # File storage options (Relevant only to File storage and lock types)
 PerlSetVar ExampleSessionDirectory "/var/www/session/sessions"
 PerlSetVar ExampleSessionLockDirectory "/var/www/session/slock"

 # Use the Apache::AppSamurai::Session::Generate::HMAC_SHA generator
 PerlSetVar ExampleSessionGenerate "AppSamurai/HMAC_SHA"

 # Use the Apache::AppSamurai::Session::Serialize::CryptBase64
 # data serializer module with Crypt::Rijndael (AES) as the block
 # cipher provider
 PerlSetVar ExampleSessionSerialize "AppSamurai/CryptBase64"
 PerlSetVar ExampleSessionSerializeCipher "Crypt::Rijndael"

 # Set the server's encryption passphrase (for use with HMAC session
 # generation and/or encrypted session storage)
 PerlSetVar ExampleSessionServerPass "This is an example passphrase"

 
 ## Tracker storage options ##
 
 # Cleanup tracker entries that have not changed in 1 day 
 PerlSetVar ExampleTrackerCleanup 86400

 # Block further login attempts from IPs that send 10 failures with
 # no more than 60 seconds between each subsequent failure
 PerlSetVar ExampleIPFailures "10:60"

 # Force at least one credential to be unique per-login.  (Requires
 # token or other non-static authentication type.)
 PerlSetVar ExampleAuthUnique 1

 # Prohibit a new session from using the same session ID as a previous
 # session.  (Only relevant for non-random sessions that use the
 # Keysource directive to calculate a pseudo-cookie.)
 PerlSetVar ExampleSessionUnique 1

 
 ## Special AppSamurai directory options ##
 
 # (These will vary widely depending on your specific setup and requirements.)
 <Directory "/var/www/htdocs/AppSamurai">
  AllowOverride None
  deny from all
  
  <FilesMatch "\.pl$">
   SetHandler perl-script
   Options +ExecCGI
   AuthType Apache::AppSamurai
   AuthName "Example"
    
   PerlHandler Apache::Registry
   #*FOR MODPERL2 USE:
   #PerlResponseHandler ModPerl::Registry
   
   allow from all

lib/Apache/AppSamurai.pm  view on Meta::CPAN

   AuthName "Example"

   PerlHandler Apache::AppSamurai->login
   #*FOR MODPERL2 USE:
   #PerlResponseHandler Apache::AppSamurai->login

   allow from all
  </Files>

  <Files LOGOUT>
   SetHandler perl-script
   AuthType Apache::AppSamurai
   AuthName "Example"

   PerlHandler Apache::AppSamurai->logout
   #*FOR MODPERL2 USE:
   #PerlResponseHandler Apache::AppSamurai->logout

   allow from all
  </Files>
 </Directory>
   
 <Directory "/var/www/htdocs/AppSamurai/images">
  Options None
  allow from all
 </Directory>

 # Protected/proxied resource config 1: Form based
 <Directory "proxy:https://ex.amp.le/thing/*">
 #*FOR MODPERL2 USE:
 #<Proxy "https://ex.amp.le/thing/*">
 
  AuthType Apache::AppSamurai
  AuthName "Example"
  PerlAuthenHandler Apache::AppSamurai->authenticate
  PerlAuthzHandler Apache::AppSamurai->authorize
  Order deny,allow
  Allow from all
  require valid-user
 
 </Directory>
 #*FOR MODPERL2 USE:
 #</Proxy>


 # Protected/proxied resource config 2: Basic auth
 <Directory "proxy:https://ex.amp.le/thaang/*">
 #*FOR MODPERL2 USE:
 #<Proxy "https://ex.amp.le/thaang/*">

  AuthType Basic
  AuthName "Example"
  PerlAuthenHandler Apache::AppSamurai->authenticate
  PerlAuthzHandler Apache::AppSamurai->authorize

  # Add some local overrides to this directory.  (Has
  # no affect on other directories/locations)

  # Switch from an inactivity timeout to a hard expiration
  PerlSetVar ExampleSessionExpire 3600
  PerlSetVar ExampleSessionTimeout 0

  # In lieu of cookies, calculate the session key using the
  # basic auth header from the client, and an argument called
  # "Sessionthing" from the request URL.  (NOTE - Keysource
  # should be used with care!  Do not use it unless you are
  # sure of what you are doing!!!)
  PerlAddVar ExampleKeysource header:Authorization
  PerlAddVar ExampleKeysource arg:Sessionthing

  Order deny,allow
  Allow from all
  require valid-user

 </Directory>
 #*FOR MODPERL2 USE:
 #</Proxy>


 # Do not allow forward proxying
 ProxyRequests Off
 
 # Proxy requests for /thing/* to  https://ex.amp.le/thing/*
 RewriteRule ^/thing/(.*)$ https://ex.amp.le/thing/$1 [P]

 # Similar for /thaang/*
 RewriteRule ^/thaang/(.*)$ https://ex.amp.le/thaang/$1 [P]

 # Redirect requests to / into our default app
 RewriteRule ^/?$ /thing/ [R,L]

 # Allow in AppSamurai requests to proxy server
 RewriteRule ^/AppSamurai -

 # Capture logout URL from app and send to a pseudo page mapped to logout() 
 RewriteRule ^/thing/logout\.asp$ /AppSamurai/LOGOUT

 # Block all other requests
 RewriteRule .* - [F]

 #*FOR MODPERL2 YOU MUST UNCOMMENT AND PUT THE FOLLOWING INSIDE
 # RELEVANT VirtualHost SECTIONS (For most Apache2 setups, this would be
 # the "<VirtualHost _default_:443>" section inside ssl.conf)
 #
 ## Enable rewrite engine inside virtualhost
 #RewriteEngine on
 ## Inherit rewrite settings from parent (global)
 #RewriteOptions inherit
 ## Enable proxy connections to SSL
 #SSLProxyEngine on


=head1 EXTENDING

Additional authentication modules, tracking features, and other options
can be added to Apache::AppSamurai.  In the case of authentication modules,
all that is required is creating a new module that inherits from
L<Apache::AppSamurai::AuthBase|Apache::AppSamurai::AuthBase>.

Other features may be more difficult to add.  (Apache::AppSamurai could
use some refactoring.)



( run in 1.878 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )