Apache::Wyrd::Services::Auth - Cookie-based authorization handler
<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>
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
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.
(format: (returns) name (arguments after self))
All the processes above are handled by the
Form URL (required)
Module for the User object which performs authorization (required). See the
URL to send cookie-less browsers to (required)
Send error back to the Login URL via the given variable (optional)
Login Server URL for key (required when a Login Server is being used)
Login Server URL for login (when a Login Server is being used)
Force the use of a Login Server on an HTTPS connection rather than attempting to authenticate directly through the username and password CGI variables.
URL to redirect to when Login Server is down. (optional, but recommended)
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.
Require a fixed client address for the session (less compatible with some ISPs) (0 for default no, 1 for yes)
The (text) name of the perl object which represents the user for this authentication (see
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.
Barry King <email@example.com>
Methods for getting User/authorization information from the authorization cookie for use when no Auth method is in the handler stack.
Shared-memory encryption key and cypher.
Perl Handler for login services.
Copyright 2002-2007 Wyrdwright, Inc. and licensed under the GNU GPL.
See LICENSE under the documentation for