Sean P. Quinlan > SQCAS-0.24 > SQCAS

Download:
SQCAS-0.24.tar.gz

Dependencies

Annotate this POD

CPAN RT

Open  0
Report a bug
Module Version: 0.24   Source  

NAME ^

SQCAS - Centralized Authorization Server

SYNOPSIS ^

  use SQCAS;

DESCRIPTION ^

This system provides a set of tools providing access to a centralized authorization database. While the system is intended to be accessed through web pages served on a mod_perl/Apache server, the basic functionality does not require Apache and could be used as a library of access objects for seperate development.

This module is intended to be usable either functionally or as an abstract base class. It provides the core check_authentication and check_authorization methods as well as the result codes as constants.

As of version .2 all the basic functionality is in place. The automated tests for SQCAS pass, and I've installed the Apache Auth* and Login modules and set up a simple website with protected resources and tested that the minimal functional behavior is in place. See SQCAS/README and SQCAS/Apache/README for details on setting up the database and webserver.

The system requires a client ID to determine the auth* realm for requests, but will try to guess it (when accessed via Apache) by looking up the requests domain if it wasn't provided. If the users IP is provided during authentication, which the Apache tools do automatically, then all authorization requests will require an IP match.

* Where I use Auth* I'm refering to both authorization and authentication.

head2 INTENT

Initially I just want this to work on the same server using mod_perl handlers. Fairly generic auth handlers and a login handler are provided. Although a later project might be to design the included code such that it templates well, the intent is that users would modify them to look & feel appropriate for their own sites (or just tear out the guts and use elsewhere). By version 0.4 the system will include handlers and base modules for new user registration & account maintenance, for admins to grant permissions to users and groups, and for managing groups. Hopefully I'll have completed the documentation by then too! :)

The next phase would be to provide special mod_perl request handlers for remote authentication and authorization requests. The response code in the header will indicate if the user is authorized or not, or if they are allowed to view a given resource or not. Handlers would return XML or YAML containing the requested information, the users ID, the session token and perhaps some digest key to verify the response. I'd also like to configure the system so that any requests not comming through SSL are refused.

On the back end the CAS server requires a set of tables in a relational database. Since this system is intended as a single point of maintenance of user data we can control the schema. It would be nice if this could work with an LDAP server as well as a MySQL (or other DBI supported relational database), or at least be able to be configured to sync changes with an external system like LDAP so that admins could have that information on a user (such as username, password, full name, maybe UID etc) which is used elsewhere for system logins and such is automatically synced.

***

Open question. Currently stuff is fairly well spread out into modules in a layout that made sense to me. However it occurs to me that some (many?) users might not like having to type:

  use SQCAS::Admin::User;
  my $user = SQCAS::Admin::User->new({ID => $id});

To create a new user, but might rather type:

  use SQCAS;
  my $user = SQCAS->new_user({ID => $id});

And leave me to worry about where User.pm really lived, and have the $user object still behave as a user object only. I haven't done that before but it seems feasable even if a bit complex internally?

***

RESPONSE CODES

        500     ERROR
        000     OK
        401     AUTH_REQUIRED
        403     FORBIDDEN

These values are drawn from Apache's response codes, since this system is intended to be generally accessed via the Apache server. All call returns should compare to these response codes (or to Apache::Constants codes, which these will be maintained to match), not to the values. So, if $rc is the result of a call to check_athorization, the correct usage would be: if ($rc == ERROR) { error($message) } elsif ($rc == OK) { do_something({}) }

A note on usage of return ERROR vs error(). error(), which basically calls die(), is used for critical system problems, such as a missing configuration file. The most common usage for error() is when there is a problem with a database call. error()'s should almost never be seen in a well tested production system since they generally occur because some argument was not validated or handled properly (such as quoting names) or someting required by the system was missing. ERROR's are returned to indicate there was a problem executing the method for some reason, such as a required parameter was not provided.

See the documentation for a specific method to determine what values it may return, however the two most commonly returned are OK and FORBIDDEN. If a method is expected to return someting beyond it's result code look in the second and subsequent return values as the first will always be OK if the method suceeded. The one exception to this rule are objects with accessor methods for attributes which return that attributes value if present or undef if not.

FORBIDDEN is a rule-of-thumb default (for the moment anyway) for situations where there were no ERROR's but the method needs to return a 'not OK' condition. For example if validating a users new email address and all the required parameters were provided, all the database calls worked, etc. but the email address provided contained illegal characters, the FORBIDDEN code would be returned.

Any time a staus code other than OK is returned, any relevant messages can be retrieved by calling warning_notes() in list context.

EXPORT

&check_authorization

&check_authentication

%CONFIG

TAG: exceptions

error

gripe

TAG: rvals

ERROR

OK

AUTH_REQUIRED

FORBIDDEN

TAG: all

Yep, everything. ;-}

METHODS ^

check_authorization

This checks the database to see if the user is currently logged in and if they are allowed to use the specified resource.

It expects to be called in an object oriend fashion, getting $self as the first argument. If not called this way, just feed it an anonymous reference. It's not how I want to handle it perminantly, just for getting the first draft working.

PARAMETERS:

 ###
 # COOKIE is the biggest hangup I have ATM in making this function as a truly
 # centralized authorization server. It looks like I can specify the domain
 # name as well as path in HTTP1.1, but I have yet to test this, nor do I
 # know the syntax using set_header. But in theory I can loop over all defined
 # domains that SQCAS services
 # and set the cookie in that domain.
 ###

COOKIE: The session token returned by SQCAS when the user was authenticated and logged in. This is used to get the user information required for checking that user is logged in and that their session has not timed out. ***SECURITY*** It is up to you to make sure that this value is kept private and secure during the session.

RESOURCE: This is the resource definition that will be checked in the database.

CLIENT: The client ID or domain from which this request is being made.

OPTIONS:

MASK: This is the permissions mask that will be checked for the specified RESOURCE. If not defined a read permission request is assumed by default. *** Should this be made a required argument instead?

IP: The remote IP of the user. If this was provided during authentication than it is REQUIRED for authorization and the IP's must match.

TIMEOUT: The timeout for sessions in seconds.

check_authentication

This function is called to verify the username and password provided to the login CGI by the user. It will imediatly return unless both the username and password were provided (well, technically, evaluate to true). It then connects to the database (using DNAcore::Auth) and gets the user ID and password for the supplied username.

Perls crypt function is called using the suplied password as the word and the password from the db as the salt. If the result matches the stored password, access will be granted. A session key is generated using md5_hex and the user ID, remote IP and time are stored in the db on that key.

If authentication fails, the reason is returned. Otherwise the OK Apache constant is returned.

PARAMETERS:

USER: The username.

PASSWORD: The users password.

OPTIONS:

IP: The remote connection IP. If present at authentication will be required to be provided and match during any subsiquent authorization check.

error

Throw a fatal exeption. Returns a stack trace (confess) if called when DEBUG is true. gripe actually does all the work, error just tells gripe to die.

gripe

Generate debug sensitive warnings and exceptions. gripe also writes warnings to a scratch pad in the calling object so that warning_notes method can return all warnings generated. This behavior mirrors that of DNAcore::WWW::Exceptions for objects rather than CGI's.

Suggested debug level usage (as level goes up messages from earlier levels should continue to be sent):

0: Production. Perls warnings should _not_ be turned on and no debug messages should be generated.

1: Basic development level. Perls warnings are turned on. Basic debug messages should be generated. Call confess to die. *

2: Shotgun debugging. Code should now be generating debug messages when entering and/or exiting important blocks so that program flow can be observed. Now calls cluck for warn.

3: Turns on Perls diagnostics. At this level messages should be generated for every pass through loops. This would also be the appropriate level to dump data structures at critical points. It is realistic to expect hundreds of lines of output at _least_ at this level.

4: Autodie - gripe will now throw a fatal exception with confess. Currently this happens the first time called. However it realy should only happen the first time a message not intended to be sent at levels 1-3 only.

* Usually debug statements are created during development or debugging calling gripe with no if $DEBUG statement, and once a piece of code is working properly an if $DEBUG = n> statement is added tp the end, with n set to the appropriate level as described above.

warning_notes

Returns any warnings stored in object from earliers calls to gripe. This is very useful when warnings are not readily seen, such as when object is used from a CGI and the errors are lost to the logs.

HISTORY ^

0.01

Original version; created by h2xs 1.23 with options

  -XAC -n SQCAS
0.1

Initial code port.

0.2

Basic required functionality for check auths in place. Apache auth handlers done as well as simple Login handler. Core tests written and passing, user tests of Apache handlers pass basic required functionality.

0.21

User module functional and all basic methods in place. No automated tests for it yet but that will be my next task before moving on to the Apache handlers for registering a new user and a user view edit account handler. Also started working on the docs.

0.22

Added tests for user object and disable/enable methods. Small additions to docs, like fixing my email address in this package! ;)

0.23

Most of the basic Apache stuff has been worked out. The SQCAS.yaml file was expanded and commented. I made a SQCAS.conf for all our Apache config stuff so admins can just Include it rather than edit the main conf. So far registering a new user & logging are functional if not quite complete or pretty.

0.23

Tried to convert to Apache 2, but I had a horrible time with mod_perl 1.99.whatever it was. I've reverted back and have tests passing again. This version is now in usage in a background role in a project in development at BU. The NewUser page will register new users, and if you add permissions into the database by hand, the $dbi->allowed method will function against it. The apache handlers also function for restricting pages and directory trees based on permissions.

SEE ALSO ^

Mention other useful documentation such as the documentation of related modules or operating system documentation (such as man pages in UNIX), or any relevant external documentation such as RFCs or standards.

If you have a mailing list set up for your module, mention it here.

If you have a web site set up for your module, mention it here.

AUTHOR ^

SeanQuinlan, <seanq@darwin.bu.edu>

COPYRIGHT AND LICENSE ^

Copyright (C) 2004 by Sean Quinlan

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.1 or, at your option, any later version of Perl 5 you may have available.