[cgiapp] Q: Authz, but only when user is Authenticated...

Graham TerMarsch cgi-application at howlingfrog.com
Tue Mar 4 15:50:30 EST 2008


With the recent release of CAP::Authz 0.07, I've started going back through my 
existing apps and updating them to use the "authz_runmodes()" instead of my 
custom Authz plugins which did something similar.

While doing this, however, I've run into a scenario that I thought I'd ask for 
some input on...

In most of the apps I'm working with right now, Authz is only useful if I've 
got an Authenticated user; if the user hasn't logged in then there's no point 
in even checking for Authz as I really want to show them a login page first.  
My custom Authz plugins used to check this for me, but I'm trying to find a 
simpler way to get this working with the new version of CAP::Authz so I can 
pitch my custom code.

So, I load up CAP::Authen and CAP::Authz in my App superclass and the prerun 
hooks get invoked in order (authen first, then authz).  However... if they 
both fail (user isn't logged in, so I obviously fail authz), CAP::Authz 
calls "prerun_mode()" last and overrides the rm that was set by CAP::Authen 
to trigger the login screen.

I've got a few possible ideas for working around this, but wanted to find out 
what others are doing...

1) Load CAP::Authz first.  That way, even if Authz fails, CAP::Authen would be 
the last one to call "prerun_mode()" and the user would get shown the login 
page.  This works, but feels counter-intuitive; I'm always thinking that I 
want Authen to run first so I load that plugin first.

2) Add a new "REQUIRES_AUTHEN" option to CAP::Authz, so that if its unable to 
even figure out what the username is then it doesn't even bother doing an 
Authz check.

What are you guys doing when you want similar behaviour?

------

FWIW, some minimal code to show my setup would go like this...

  class MY::App;
  use base qw(CGI::Application);
  use CGI::Application::Plugin::Authentication;
  use CGI::Application::Plugin::Authorization;
  sub cgiapp_init {
    my $self = shift;
    $self->authen->config( ... );
    $self->authz->config( ... );
  }

  class MY::DerivedApp;
  use base qw(MY::App);
  sub setup {
    my $self = shift;
    $self->authen->protected_runmodes( ':all' );
    $self->authz->authz_runmodes( ':all' => 'admin' );
  }

Gist of the setup is that the superclass sets up the global Authen/Authz 
config and the drivers, while each derived app then sets up the list of 
Authen protected runmodes and the Authz requirements for the modes.

-- 
Graham TerMarsch


More information about the cgiapp mailing list