[cgiapp] Security, Authentication and Authorization for CGI::App

Michael Peters mpeters at plusthree.com
Thu Mar 4 17:56:45 EST 2010


On 03/04/2010 10:56 AM, Brad Van Sickle wrote:

> The way I handle that today is:
> 1) Authentication is pretty simple, I have a "Security" application that
> provides the login form, processes the login, hands out the session and
> then redirects the user to the actual app.

Simple and pretty standard. Another way is to separate out the session 
from the auth cookie. Session holds various things about what the user 
has done, etc. The auth cookie holds things like user id and 
groups/roles. You can make this auth cookie tamper proof by using a 
hash, etc. Then you don't have to hit your database every time you want 
to find out who the user is or what groups he's a part of.

This is how mod_auth_tkt works and it's really nice because then you can 
use the same auth scheme in your proxies as you do in your backend.

> 2) Runmode authorization is a little trickier, but still manageable.  I
> check the user's session in prerun and if they are not authenticated,
> redirect to a "not authorized" runmode that redirects them back to the
> security app (login page) Any module that needs to set security on
> specific runmodes, inherits prerun and does "if" checks against the
> runmode/usertype to make sure they are authorized.  Anyone trying to go
> somewhere they shouldn't is redirected to that same "not authorized"
> runmode.

I usually generalize this by putting my prerun checking in my base class 
and each sub class tells the base class which run modes are restricted 
to which roles. Sometimes I make this a method that child classes 
override or sometimes I make it a parameter that's passed to new() in 
either a startup script or a C::A::Dispatch table.

> 3) Data authorization is the part I'm least happy with.  I often find
> myself pulling keys (groupID, organizationID, etc..) out of the user
> profile, doing an "if" check on user type, and then dynamically setting
> WHERE clauses on my DB queries according to what user type I'm dealing
> with and what information they are allowed to see.  It's cumbersome and
> hard to manage.

Unfortunately this is where things fall apart for just about everyone. 
It's the business rules of your application. Even if you could simplify 
the definition of these roles (in like an LDAP db or something) it would 
still be your application's job of putting these permissions into effect.

> 3) As I mentioned, my data authorization scheme is very hard to manage
> and I'd love to find a better way.  I just don't have any ideas about
> what that "better way" is.  Obviously it's easier to do some query
> alteration to display different data than to write entirely new
> applications or modules to cater to different user types/access levels,
> but when requirements change, new user types are added, etc... it can be
> a considerable amount of work to alter all the "if" checks on the
> queries accordingly.

I've sometimes heard that if you have a lot of if/else clauses then your 
not using OO enough. I'm not sure I totally agree, but maybe if you have 
classes that handle your different data access entities (like an ORM) 
then maybe you should have a different subclass for each role? Obviously 
this has problems if someone has multiple roles, but it's at least 
something to think about.

-- 
Michael Peters
Plus Three, LP


More information about the cgiapp mailing list