[Catalyst] Authentication and architecture

Yuval Kogman nothingmuch at woobling.org
Tue Dec 20 08:17:11 CET 2005


On Tue, Dec 20, 2005 at 02:19:00 +0100, Jon Molin wrote:
> On 12/19/05, Yuval Kogman <nothingmuch at woobling.org> wrote:
> >
> > On Mon, Dec 19, 2005 at 19:46:47 +0100, Jon Molin wrote:

Storing sessions in a database is probably not a good idea unless
you have a huge number of page hits - the overhead (especially of
Store::CDBI as opposed to Store::DBI) is humungous.

> I've added ACL and these, so I'll always end up at the login, untill I get
> it working:
> __PACKAGE__->deny_access_unless( "/", sub {0});

This will *always* deny access - the subroutine is unconditional.

If you want to permit access only to logged in users, make it

	sub { $_[0]->user_exists }

Which will mean "access to / (all actions) is denied unless a user
exists (and is logged in)".

> __PACKAGE__->allow_access_if( "/member", sub { 1 } );
> __PACKAGE__->allow_access_if( "/page/default", sub { 1 } );
> __PACKAGE__->allow_access_if( "end", sub { 1 } );

This looks sensible

> I suspect this is where I'm having problems now. Making it understand where
> to go when it realises the user hasn't access to anything but the login and
> register. Now I get this:

Okay, so what you want is to handle the access denied event, and use
it to redirect.

	package MyApp;

	sub access_denied : Private {
		my ( $self, $c ) = @_;
		
		$c->detach("/member/login");
	}

> And try accessing page/default (just a dummy hello catalyst page) I get the
> page I request, as expected since there's no longer a rule restricting it.
> In http://dev.catalyst.perl.org/wiki/Faq_ref#au.1 did I see an example using
> begin (guess it's the depricated way) and adding that code and keeping sub
> {1} gives me the login page for all pages, like it claims to do.

Ouch, that is a very old doc... =(

> What I can't understand is how to tell Authorization::ACL where to go when
> login is required, I'd suspect it defaults to to /login but since that seems
> like a loaded path must my guess be wrong.

ACL doesn't know about login, etc.

Login is required when a user is not logged in.

	if ( $c->user_exists ) { warn "user is logged in" }

(user_exists is a method of C::P::Authentication).

You can leverage the ACL plugin to automatically check that the user
exists before each action:

	__PACKAGE__->deny_access_unless( "/", sub { my $c = shift; $c->user_exists });

ACL will run this test every time an action under "/" is accessed,
and will deny access unless that condition is true.

When you create a more specific rule, like "/member", it will be
evaluated earlier.

	__PACKAGE__->allow_access_if( "/member", sub { 1 });

will be evaluated before the user_exists rule, and will always
explicitly allow access to all actions under /member.

When access is denied you have to handle the condition. An
'access_denied' private action will be called if it exists, much
like auto (inherited across controllers), so a top level
access_denied : Private action will get all the info.

I'll add some extra arguments to the access denied action, so that
it knows what action triggered it.

You can also override the acl_access_denied and acl_access_allowed
plugin methods if you need some extra flexibility.

-- 
 ()  Yuval Kogman <nothingmuch at woobling.org> 0xEBD27418  perl hacker &
 /\  kung foo master: /me kicks %s on the nose: neeyah!!!!!!!!!!!!!!!!!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.rawmode.org/pipermail/catalyst/attachments/20051220/9ab33666/attachment.pgp


More information about the Catalyst mailing list