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

Brad Van Sickle bvansickle3 at gmail.com
Fri Mar 5 12:44:41 EST 2010


I'd be very interested in checking that out once it's available.  I'm 
not sure I like your philosophy of making each module responsible for 
it's own security, I like to push as much up to the base class as 
possible, but I do love your attention to DB resources.

As someone with a strong operational background I'm consistently shocked 
by how cavalier some developers can be about system resource usage, 
especially in terms of database.

Like you, I strive to hit the database one time at the beginning of a 
request to check session validity and pull any other information I need 
about the user, which I then store in my session object.  One of the 
reasons I've stayed away from the CGI::App authentication and 
authorization modules thus far is because I they don't seem versatile 
enough to allow this.  It seems like they rely on making a lot of DB 
requests themselves, and in addition to that, they don't allow me to 
pull out other miscellaneous information from other tables at the same 
time, resulting in me making yet another DB query to grab any other 
information I may need before I process the request.


Mark Rajcok wrote:
> On Thu, Mar 4, 2010 at 5:56 PM, Michael Peters <mpeters at plusthree.com>wrote:
>
>   
>> On 03/04/2010 10:56 AM, Brad Van Sickle wrote:
>>     
>>> 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.
>>
>>     
>
> Hi Brad, great discussion topic.
>
> I recently wrote an Authorization Plugin (it is on my todo list to get it up
> on CPAN) to handle "runmode authorization".  It uses attribute handles to
> specify which runmodes require authorization:
>
> sub subclass_method_x  :Authz(administrator) {
>  # no authorization logic here
>  ...
> }
> sub authz_administrator {
>   # authorization logic here
> }
>
>
> The plugin adds a prerun hook such that before subclass_method_x is called,
> method authz_administrator() will now automatically get called ("authz_"
> gets prepended to the attribute handle data to form the authorization method
> name).  I normally define authz_administrator() in the same (sub)class as
> subclass_method_x().
> If authz_administrator() determines the user is not authorized, the runmode
> is changed to authz_error() -- which I define in the base class, since I
> normally don't need custom authorization error messages.  However, if a
> custom error is needed, the authz_error() method can be overridden in the
> subclass.
>
> I like this approach for a few reasons:
>
> 1. subclass_method_x() is clearly marked that it requires authorization, and
> which type of authorization.  I prefer this over something like
> CAP::Authorization's authz_runmodes() concept.  If I want to change how
> authorization works for a method, I simply modify the method signature (I
> don't have to scroll up to the setup() method and modify a call to
> authz_runmodes()).
>
> 2. subclass_method_x() doesn't have any authorization checking code --
> that's in another "authorization method", and multiple runmodes can call
> that same "authorization method" when the same authorization logic is needed
>
> 3. I don't have to preconfigure the authorization mechanism in a base class
> (which is the typical CAP::Authorization model).  In fact, the base class
> doesn't have to know anything about authorization -- only the subclass where
> the authorization is needed has to know.  So for instance, in my
> AdminUserManager subclass, there are authorization methods for checking
> different admin privileges.  That's the only subclass that has this logic.
> If I need to change how admin authorization works, the runmodes and the
> authorization logic are all in the same file.  I really like that.  (But, I
> guess it depends on how you view authorization... if you view it as cutting
> across your application, then the base class might then be preferable.)
>
> 4. I can be more efficient and save the results of database queries
> performed in authz_administrator() for later use in subclass_method_x().
> This was one of the main reasons I decided to write an alternative to
> CAP::Authorization.  With CAP::Authorization, database hits were being made
> to authorize, then I would make additional database hits in my runmode to
> obtain more information about the user.  For example, in
> authz_administrator() I often grab the user's name out of the database at
> the same time I'm pulling out user role/privilege info.  I create and save a
> User object for later use in the runmodes.  (I just replied to Nicholas,
> where I requested a similar capability for CAP::Authentication -- then only
> one DB hit would be needed for Auth, Authz, and some other common user
> info.)
>
> As for data authorization (e.g., filtering select queries based on user
> roles), I don't have any good solutions.  I dynamically add WHERE clauses
> (or dynamically modify the SQL statement appropriately) like you, or I
> filter the data after getting back query results.
>
> -- Mark R.
>
> #####  CGI::Application community mailing list  ################
> ##                                                            ##
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://lists.openlib.org/mailman/listinfo/cgiapp    ##
> ##                                                            ##
> ##  Web archive:   http://lists.openlib.org/pipermail/cgiapp/   ##
> ##  Wiki:          http://cgiapp.erlbaum.net/                 ##
> ##                                                            ##
> ################################################################
>
>   


More information about the cgiapp mailing list