|
Hi,
I wrote a listener that checks the ACL for the current user to forward to a forbidden page when the rights are insufficient. This works perfectly but now I have a problem. If the routing matches a route but controller or action does not exist these 404 errors are not shown. This is due to the ACL check which uses controller as resource and action as privilege. This check fails because the wrong controller is not set as a ACL resource or the wrong action is not set as a ACL privilege. So I get a forward to the forbidden page. Any dispatching errors for missing controller or action can not be thrown any more. But since these dispatching errors are only thrown while dispatching I cannot add my ACL check there. Can someone follow this problem and provide me with a solution? Regards, Ralf -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
|
Hi Marc,
Marc Tempelmeier schrieb am 11.09.2012 08:56: > in ZF1 I solved this with checking if the route is dispatchable and if not screw the whole ACL check. I didn´t check if there is something like that in ZF2 though. I did not find any isDispatchable method yet though I think it is not there. So I am still looking for a solution. Regards, Ralf -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
|
You effectively have 2 options:
First, and I am sure least favorite option from a framework perspective: Put your acl check in an onDispatch() method inside of the routed controller (that means at least a controller was dispatched). Inside of this method, you could do whatever check you need. At this point, you'd make sure to call parent::onDispatch() as it is responsible for calling the appropriate action. This is all assuming you're extending the AbstractActionController. THE BETTER SOLUTION: Is to get familiar with Event system, write a listener and listen in on a particular event. I think this list is up to day and complete (but I am not sure, best to check in IRC with Rob or Evan): http://akrabat.com/zend-framework-2/a-list-of-zf2-events/ also: http://akrabat.com/zend-framework-2/an-introduction-to-zendeventmanager/ the actual event manager: http://framework.zend.com/manual/2.0/en/modules/zend.event-manager.event-manager.html Hope this helps get you started, Ralph On 9/11/12 9:12 AM, Ralf Eggert wrote: > Hi Marc, > > Marc Tempelmeier schrieb am 11.09.2012 08:56: >> in ZF1 I solved this with checking if the route is dispatchable and if not screw the whole ACL check. I didn´t check if there is something like that in ZF2 though. > > I did not find any isDispatchable method yet though I think it is not there. > > So I am still looking for a solution. > > Regards, > > Ralf > -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
|
Hi Ralph,
thanks for your reply. I am also working on the better solution you suggested but with that solution I got stuck. This is my listener (a little shortened): -------------------------------------------------------------------- class RouteListener implements ListenerAggregateInterface { public function attach(EventManagerInterface $events) { $this->listeners[] = $result = $events->attach( MvcEvent::EVENT_DISPATCH, array($this, 'checkAcl'), 100 ); } public function checkAcl(EventInterface $e) { $acl = $e->getApplication()->getServiceManager() ->get('User\Acl\Service'); $routeMatch = $e->getRouteMatch(); $response = $e->getResponse(); if (!$acl->isAllowed( $routeMatch->getParam('controller'), $routeMatch->getParam('action') )) { $routeMatch->setParam('controller', 'user'); $routeMatch->setParam('action', 'forbidden'); } } } -------------------------------------------------------------------- So, the checkAcl() is processed before the dispatching. But at that stage the dispatcher did not identify any missing controller or action. So file not found errors are not thrown because the forbidden error comes first. When I clear out the 100 or change it to any negative value then the FnF error is thrown, but the ACL check does not work. Any user with insufficient rights can access all other pages he isn't allowed to. I looked into the code and I think the dispatching process is done within the Zend\Mvc\DispatchListener::onDispatch() method. Correct my if I am wrong. Since there is no isDispatchable() method any where to check I don't see any chance to do an ACL check before the dispatching takes place. Do you have another idea? Regards, Ralf -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
|
Hi again,
to clarify my last message. The ACL check does work for unknown actions. It just doesn't work correctly for any unknown controllers. Currently I am thinking about using the controller loader to try to load the controller and only do the ACL check when the controller can be loaded. But with this approach the controller loader would be used twice. Once in my checkAcl() method and once again in the Zend\Mvc\DispatchListener::onDispatch() method. Regards, Ralf -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
|
Administrator
|
-- Ralf Eggert <[hidden email]> wrote
(on Saturday, 15 September 2012, 11:17 AM +0200): > to clarify my last message. The ACL check does work for unknown actions. > It just doesn't work correctly for any unknown controllers. > > Currently I am thinking about using the controller loader to try to load > the controller and only do the ACL check when the controller can be > loaded. But with this approach the controller loader would be used > twice. Once in my checkAcl() method and once again in the > Zend\Mvc\DispatchListener::onDispatch() method. I just had another idea. Use an initializer. Initializers allow you to operate on instances when they are first created by the service or plugin manager. As such, you could attach an initializer to the ControllerManager, and run your ACL check then -- at that point, you'll know you have a valid controller. It would look something like this: 'controllers' => array( 'initializers' => function ($controller, $controllers) { $services = $controllers->getServiceManager(); $aclService = $services->get('WhateverYouNamedYourAclService'); // At this point, you have your controller and acl service, // so you likely have the ability to do a check. If the // check fails, raise an exception here. } ) The above could be in a Module's getControllerConfig() method, or as a standalone initializer class somewhere. -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
|
Hi Matthew,
thanks for this new idea. > I just had another idea. Use an initializer. I tried to build this but noticed that the initializer is only processed for existing controllers. But the acl check problems I have have to do with not existing controllers. Currently I used this listener method: ----------------------------------------------------------------- public function checkAcl(EventInterface $e) { $routeMatch = $e->getRouteMatch(); $controllerLoader = $e->getApplication()->getServiceManager() ->get('ControllerLoader'); try { $controller = $controllerLoader->get( $routeMatch->getParam('controller') ); } catch (\Exception $exception) { return; } $acl = $e->getApplication()->getServiceManager() ->get('User\Acl\Service'); if (!$acl->isAllowed( $routeMatch->getParam('controller'), $routeMatch->getParam('action')) ) { $routeMatch->setParam('controller', 'user'); $routeMatch->setParam('action', 'forbidden'); } } ----------------------------------------------------------------- Now the ACL check is not processed for not existing controllers. The only issue with this is the double check with the controller loader. The only other solution I currently see is adding another event trigger within Zend\Mvc\DispatchListener::onDispatch() after the try-catch block which checks existance of requested controller and before the dipatching. Regards, Ralf -- List: [hidden email] Info: http://framework.zend.com/archives Unsubscribe: [hidden email] |
| Powered by Nabble | Edit this page |
