The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Apache::Wyrd::Services::Auth - Cookie-based authorization handler

SYNOPSIS

    <Directory /var/www/restricted/>
      SetHandler perl-script
      PerlHandler Apache::Wyrd::Services::Auth BASENAME::Handler
      PerlSetVar  LoginFormURL   /login.html
      PerlSetVar  NoCookieURL    /cookies.html
      PerlSetVar  LSKeyURL       https://login.someserver.com/login.html
      PerlSetVar  LSLoginURL     https://login.someserver.com/login.html
      PerlSetVar  LSDownURL      /lsdown.html
      PerlSetVar  AuthPath       /
      PerlSetVar  UserObject     BASENAME::User
      PerlSetVar  ReturnError    error_message
      PerlSetVar  AuthLevel      restricted
      PerlSetVar  Debug          0
      PerlSetVar  TieAddr        1
    </Directory>

DESCRIPTION

Auth provides a secure cookies-based login system for a Wyrd-enabled server that might not itself be equipped with SSL. It can do so if provided a connection to an SSL-enabled Apache server with an Apache::Wyrd::Services::LoginServer available on a secure port. It uses a standard SSL channel to circumvent an unauthorized party from obtaining login credentials (username/password) by packet-sniffing.

To do so, it maintains a cookie-based authorization scheme which is implemented using stacked handlers. It handles authorization by login and/or cookie, and passes the user information to handlers down the stack via mod_perl's notes table. The Auth module should be the first handler in a chain of handlers.

The Auth Module first checks for a "challenge" variable under CGI which it expects to contain a username/password pair encrypted via it's own private encryption key (see the use of the Apache::Wyrd::Services::Key object in relation to the Apache::Wyrd::Services::CodeRing object). This challenge is generated by a LoginServer (see below), and is part of the regular login sequence. If this variable is provided, it will attempt to create a user object from it and set a cookie on the browser (auth_cookie) which keeps this user object stored for later use.

If the challenge is not found, it checks for a cookie called auth_cookie, and decrypts it, passing it on in an XML notes item called "user" if it finds it. (The user note is in perl code, stored and retrieved by the next handler via XML::Dumper.)

If the cookie is not found, it checks first to see if cookies are enabled on the browser, and if not, sends the browser to a url to explain the need for cookies. It does this check by reloading the page with a test cookie defined and checking for that cookie in the following request.

If cookies are enabled, it will attempt to set up a login. First, it will establish an encrypted session with a login server via SSL in which it will give the login server it's internal key, encrypted with a random key and that key. If this session fails, it will direct the browser to a page explaining that the login server is down and authorization cannot proceed.

If the session succeeds, it will encode the URL the browser originally requested so that it may be redirected to that URL on successful login. This encoded URL, an authorization URL, and the encrypted key it gave the login server is given to the browser as a GET-request redirection to a login page. On the login page, the encoded URL and the encrypted key are to be used as hidden fields to pass to the login url which is given as the action attribute of the login form. The login form has, at a minimum, a username and password. These are all submitted to the login server via SSL.

The login server will then decrypt the encrypted key, use that key to encrypt the login information, and send that information to the originally-requested URL via the challenge CGI variable. As the Auth object will again be in the stack, it will receive the challenge per the first paragraph of this description.

Under SSL, instead, the Auth module checks for a user with appropriate clearance. Not finding one, it will expect to find the username and password under CGI variables of those names. If found, it will attempt athentication. If this fails, as above, the browser will be redirected to the login URL. Instead of a LoginServer, however, the login form will be expected to attempt the URL it was refused in the first place, and will return the browser to the login page on each subsequent failure until a login succeeds.

Note that under SSL, since CGI variables are scanned for authentication information, any CGI variables being passed prior to authentication will be lost in the subsequent re-direction which checks for browser cookie acceptance. If you wish to avoid this behavior, set the LSForce PerlVar directive to 1.

METHODS

(format: (returns) name (arguments after self))

(RESPONSE) handler (Apache)

All the processes above are handled by the handler subroutine.

PERLSETVAR DIRECTIVES

LoginFormURL

Form URL (required)

UserObject

Module for the User object which performs authorization (required). See the Apache::Wyrd::User module.

NoCookieURL

URL to send cookie-less browsers to (required)

ReturnError

Send error back to the Login URL via the given variable (optional)

LSKeyURL

Login Server URL for key (required when a Login Server is being used)

LSLoginURL

Login Server URL for login (when a Login Server is being used)

LSForce

Force the use of a Login Server on an HTTPS connection rather than attempting to authenticate directly through the username and password CGI variables.

LSDownURL

URL to redirect to when Login Server is down. (optional, but recommended)

Debug

Dump debugging information to the Error Log (0 for default no, 1 for yes). Note that if the log is not secure, this may compromise the users' credentials.

TieAddr

Require a fixed client address for the session (less compatible with some ISPs) (0 for default no, 1 for yes)

UserObject

The (text) name of the perl object which represents the user for this authentication (see Apache::Wyrd::User).

BUGS/CAVEATS/RESERVED METHODS

As with many such schemes, man-in-the-middle attacks are always possible, if rather problematic to implement. Additionally, unless TieAddr is set, a "stolen cookie", i.e. one obtained via packet sniffing or similar technique can be used to gain access until the server's key is regenerated on server restart.

AUTHOR

Barry King <wyrd@nospam.wyrdwright.com>

SEE ALSO

Apache::Wyrd::Interfaces::GetUser

Methods for getting User/authorization information from the authorization cookie for use when no Auth method is in the handler stack.

Apache::Wyrd::Services::Key

Shared-memory encryption key and cypher.

Apache::Wyrd::Services::LoginServer

Perl Handler for login services.

LICENSE

Copyright 2002-2007 Wyrdwright, Inc. and licensed under the GNU GPL.

See LICENSE under the documentation for Apache::Wyrd.