|
View:
New views
15 Messages
—
Rating Filter:
Alert me
|
|
|
Calling Controller Methods from inside begin or auto.Hello,
So I have a site I'm building that requires authentication, but only to selected pages. By default I want to require that an authenticated user is found, but in certain controllers I want to disable this. I was originally thinking about doing this by creating a auth_required() method call in a base controller class and overriding this as needed. Then I would write my authentication routine inside the Root controller. Something like this: sub begin : Private { my ($self, $c) = @_; # I created the get_user method. my $u = $c->get_user() if ($self->auth_required()) { # Do auth stuff. } } However the issue here is that when calling $self->auth_required() this will always call the Root.pm's auth_required method instead of the specific controllers. Is there a way from inside a begin method to get the controller that is actually going to be used to display the page? If not is there another way to do the above without having to write the auth handling at the top of every method used to display pages? -- Derek Wueppelmann _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Calling Controller Methods from inside begin or auto.* monkey <dwueppel@...> [2009-09-29 14:35]:
> Is there another way to do the above without having to write > the auth handling at the top of every method used to display > pages? Chained dispatch. Do an auth check early in the chain, then the actions down the chain don’t need to do it. Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/> _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.On Tue, 2009-09-29 at 14:39 +0200, Aristotle Pagaltzis wrote:
> * monkey <dwueppel@...> [2009-09-29 14:35]: > > Is there another way to do the above without having to write > > the auth handling at the top of every method used to display > > pages? > > Chained dispatch. Do an auth check early in the chain, then the > actions down the chain don’t need to do it. Thanks, I was hopeing for something that wouldn't require adjusting the existing methods I currently have. It may not be possible, but that's what I was hoping for. -- Derek Wueppelmann _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.Aristotle Pagaltzis schrieb:
> * monkey <dwueppel@...> [2009-09-29 14:35]: >> Is there another way to do the above without having to write >> the auth handling at the top of every method used to display >> pages? > > Chained dispatch. Do an auth check early in the chain, then the > actions down the chain don’t need to do it. Here I have a question: What is the recommended way to leave a chain - eg. to show a login form? detach? Exceptions (with "die") don't work, since all Catalyst actions are wrapped in evals. _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Calling Controller Methods from inside begin or auto.* Bernhard Graf <catalyst4@...> [2009-09-29 15:45]:
> What is the recommended way to leave a chain - eg. to show a login form? > > detach? Yup. Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/> _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.On Tue, 2009-09-29 at 14:39 +0200, Aristotle Pagaltzis wrote:
> * monkey <dwueppel@...> [2009-09-29 14:35]: > > Is there another way to do the above without having to write > > the auth handling at the top of every method used to display > > pages? > > Chained dispatch. Do an auth check early in the chain, then the > actions down the chain don’t need to do it. So I found a different way to do this. It's pretty close to my original method I had mentioned, but instead of calling $self->auth_required I changed it to: $c->action->class->auth_required() Which has the desired effect. Now all I need to do is if a controller does not require authentication in order to be viewed I override the auth_required method in that controller to return 0 instead of the default 1. -- o) Derek Wueppelmann (o (D . dwueppel@... D). ((` http://www.monkeynet.ca ( ) ` _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.On Wed, Sep 30, 2009 at 5:23 AM, Derek Wueppelmann <dwueppel@...> wrote:
Does that approach provide you with enough fine-grained access control? I suppose you can check the action name in auth_required(). There are a number of existing modules to consider, for example: Catalyst::Action::Role::ACL Catalyst::Plugin::Authorization::ACL I've also used an approach where I check for roles in each controller's auto method, and I've also used method attributes to indicate the access level required for each action (which has the benefit where I can require *every* dispatched action to have an access level specified or be blocked). I also do not detach to a login page, rather I always redirect. Not sure I remember the details of that choice, but one reason might have been I didn't want a URL for one resource to return a 200 yet not return the response for that URL and instead return a login form. -- Bill Moseley moseley@... _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.On Wed, 2009-09-30 at 06:53 -0700, Bill Moseley wrote:
> Does that approach provide you with enough fine-grained access > control? > I suppose you can check the action name in auth_required(). It actually does. Basically either the entire class requires auth or not, and if I need to occasionally require auth to specific methods that's easy enough to take care of on a case by case basis. > There are a number of existing modules to consider, for example: > > Catalyst::Action::Role::ACL > Catalyst::Plugin::Authorization::ACL In order to use these I would have to rewrite significant portions of the code. At this point it's not worth while doing. > I've also used an approach where I check for roles in each > controller's auto method, and I've also used method attributes to > indicate the access level required for each action (which has the > benefit where I can require *every* dispatched action to have an > access level specified or be blocked). > > I also do not detach to a login page, rather I always redirect. Not > sure I remember the details of that choice, but one reason might have > been I didn't want a URL for one resource to return a 200 yet not > return the response for that URL and instead return a login form. I'm actually doing forwards to my login page right now. So that when a user logs in they can still see the page they were originally trying to view. I capture the URL they were attempting to view in the login process. -- o) Derek Wueppelmann (o (D . dwueppel@... D). ((` http://www.monkeynet.ca ( ) ` _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.On Wed, Sep 30, 2009 at 7:30 AM, Derek Wueppelmann <dwueppel@...> wrote: -- I'm actually doing forwards to my login page right now. So that when a And then redirect back to that original page after login? I pass that data via the cache or session. $c->cache->set( $key, { orig_url => $url, message => 'Auhorization is required', }); $c->res->redirect( $c->uri_for( '/login', { info => $key } ) ); Catalyst docs show an example using auto. BTW - shouldn't the redirect be an absolute-URI? sub auto : Private { my ( $self, $c ) = @_; if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication $c->res->redirect( '/login' ); # require login return 0; # abort request and go immediately to end() } return 1; # success; carry on to next action } RFC3986 has: absolute-URI = scheme ":" hier-part [ "?" query ] And 2616: Location = "Location" ":" absoluteURI Bill Moseley moseley@... _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.On Wed, Sep 30, 2009 at 8:09 AM, Bill Moseley <moseley@...> wrote:
My typical recipe is via parameter, rather than session. This is more flexible, and allows me to pass URLs to people with more definitive results. You do, however, have to whitelist the URLs prior to redirection. The very basic recipe is just something to compare the URI base: my $redir = URI->new( $redir_url ); $redir->base eq $c->req->uri->base; -J _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.Am Mittwoch, den 30.09.2009, 16:30 +0200 schrieb Derek Wueppelmann:
> On Wed, 2009-09-30 at 06:53 -0700, Bill Moseley wrote: > > > Does that approach provide you with enough fine-grained access > > control? > > I suppose you can check the action name in auth_required(). > > It actually does. Basically either the entire class requires auth or > not, and if I need to occasionally require auth to specific methods > that's easy enough to take care of on a case by case basis. > > > There are a number of existing modules to consider, for example: > > > > Catalyst::Action::Role::ACL > > Catalyst::Plugin::Authorization::ACL > > In order to use these I would have to rewrite significant portions of > the code. At this point it's not worth while doing. > > > I've also used an approach where I check for roles in each > > controller's auto method, and I've also used method attributes to > > indicate the access level required for each action (which has the > > benefit where I can require *every* dispatched action to have an > > access level specified or be blocked). > > > > I also do not detach to a login page, rather I always redirect. Not > > sure I remember the details of that choice, but one reason might have > > been I didn't want a URL for one resource to return a 200 yet not > > return the response for that URL and instead return a login form. > > I'm actually doing forwards to my login page right now. So that when a > user logs in they can still see the page they were originally trying to > view. I capture the URL they were attempting to view in the login > process. You should redirect to your login page rather than displaying it under a different url. I store the previous url in the session and redirect to it after a successful login, works like a charm. -- best regards, Alex *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"* T-Systems Austria GesmbH Rennweg 97-99, 1030 Wien Handelsgericht Wien, FN 79340b *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"* Notice: This e-mail contains information that is confidential and may be privileged. If you are not the intended recipient, please notify the sender and then delete this e-mail immediately. *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"* _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Calling Controller Methods from inside begin or auto.* Bill Moseley <moseley@...> [2009-09-30 16:00]:
> I also do not detach to a login page, rather I always redirect. > Not sure I remember the details of that choice, but one reason > might have been I didn't want a URL for one resource to return > a 200 yet not return the response for that URL and instead > return a login form. I detach. My login action sets status 403 and pragma no-cache (etc) when it’s not requested directly. I’d love to be able to just send 401 instead and let the user agent take care of everything (which would transparently and securely deal with POSTs sent with expired auth credentials) – unfortunately the HTTP Auth UI in browsers is universally shoddy. If I felt the need, I could also check for browser vs automated agent and send either form + 403 to browsers and just a 401 to other clients. Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/> _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.On Wed, Sep 30, 2009 at 10:13 AM, Aristotle Pagaltzis <pagaltzis@...> wrote:
Looking at my code I also return 401 for API requests. I have a note in the code that there was problems returning 403 on some browsers although maybe that was just old IE when the content body was too short and it would display its own message. And looking at old svn logs I found another reason I redirect -- which might be how my code grew over time. At one point I added a "remember me" feature. So I have code in the controller's auto() which is basically "return unless $c->test_role( @roles );" That test_role() method first checks if logged in, and if not logged in then does the redirect. But, before doing the redirect it attempts an automatic login via the "remember me" feature. The problem there was then the action's auto() and begin() methods were not run with the user logged in, which was important for other reasons. I would have expected to do the "remember me" login earlier (e.g. in root's auto() ) and avoided that issue, but mabye I had a reason otherwise. Anyway, the redirect does allow the login action to be called as a normal request (with login's auto and begin methods run). Granted, now there's $c->go to do a full dispatch, but redirect seems cleaner at the expense of a redirect. -- Bill Moseley moseley@... _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Calling Controller Methods from inside begin or auto.* Bill Moseley <moseley@...> [2009-09-30 20:10]:
> The problem there was then the action's auto() and begin() > methods were not run with the user logged in, which was > important for other reasons. Ah. The only `begin`, `end` and `default` actions I have are in my root controller, and the only responsibilities they have are setting up and tearing down auth and rendering the stash. Everything else is done via Chained: all other controllers have sub base : Chained PathPart('whatever') ... { ... } even if it is empty (which is the case as often as not), and all actions in each controller chain off its `base` action. That `base` may itself chain off another action in another controller instead of `/`. With this structure, having `auto` etc run before or after auth or whatever is never an issue. I also do all my auth checks piecemeal along the chain, thus, without complicated chains of conditionals in my code, dispatch determines for me how specifically to perform a complex auth check. And if I need to extract logic from several actions without affecting the URI structure I can add a `PathPart('') CaptureArgs(0)` action into the chain and voilà. I really enjoy working with this structure. It’s declarative and very DRY, no hairy logic, clear, simple, explicit. I ♥ Chained. Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/> _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
|
|
Re: Re: Calling Controller Methods from inside begin or auto.I move this off list because I'm not sure you want to show
On Wed, Sep 30, 2009 at 8:11 PM, Aristotle Pagaltzis <pagaltzis@...> wrote: With this structure, having `auto` etc run before or after auth Shifting topics here. I'm not quiet so in love with the chained because it is sometimes confusing for new programmers and is a bit more challenging to build urls in the templates. We do used chained actions as I believe you describe, but not everywhere. Often the more complex auth checks happen at the end of the action chain so it doesn't alway buy us that much. But, that may be just the way our URLs work. That said, I value your comments. Could you show an example of what you describe -- maybe one that has more complex auth requirements? What I have liked is a combination of using auto() in the root and attributes on the actions. Every dispatch method runs auto, so it's a way to ensure that every action is tested. It's not a big conditional check as the action attributes link to methods that handle the tests. Someone can't throw in a : Local method any bypass checks. But, it's not perfect by any means (there's always ways to mess up the auth checks). So, If you ♥ chained that much I'll belive you have something great and I'd love to see more real-world examples. Thanks, -- Bill Moseley moseley@... _______________________________________________ List: Catalyst@... Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@.../ Dev site: http://dev.catalyst.perl.org/ |
| Free embeddable forum powered by Nabble | Forum Help |