我有一个名为“ TestController”的控制器,其中有几个动作。对于每个动作,我都会收到一个get Parameter(“ id”)。 像这样:
test/action1/1
test/action1/2
test/action2/1
test/action3/1
...
由于可以轻松修改此参数,因此我想检查此ID的权限。我是否必须在每个动作中都包含此检查方法,还是有其他方法?我知道我无法在构造函数中接收参数,但是这样的方式会很好。
目前,我的解决方案是在插件中添加一个check方法,并在每次这样的操作中调用它:
if(!$this->access()->checkAccess(..., $this->params()->fromRoute('id')) {
//redirect...
}
答案 0 :(得分:2)
您可以使用ACL(或RBAC)进行这些检查。
使用ACL,您可以(必须)声明应用程序的资源,使用该应用程序的角色以及角色如何访问资源。
您可以先在应用程序的Module.php
class Module {
public function onBootstrap(\Zend\Mvc\MvcEvent $event) {
$application = $e->getApplication();
$serviceManager = $application->getServiceManager();
$sharedManager = $application->getEventManager()->getSharedManager();
$router = $serviceManager->get('router');
$request = $serviceManager->get('request');
$matchedRoute = $router->match($request);
if (null !== $matchedRoute) {
$sharedManager->attach(\Zend\Mvc\Controller\AbstractActionController::class, \Zend\Mvc\MvcEvent::EVENT_DISPATCH, function($event) use ($serviceManager) {
$serviceManager->get('ControllerPluginManager')->get('Application\Controller\Plugin\Acl')->doAuthorization($event);
}, 2
);
}
}
}
如您所见,我们将插件Application\Controller\Plugin\Acl
附加到每个dispatch
的{{1}}事件中。
然后您必须实施ACLS。
这是一个简单的例子。 默认情况下,我更喜欢拒绝访问所有资源,然后逐个允许访问它们。您还可以允许访问所有内容,然后拒绝访问单个资源,但是这种方式必须格外小心。如果您全部拒绝并忘记了某些内容,则用户将无法访问应有的内容。如果您允许所有人忘记某件事,那么用户可能会看到他们不应该看到的东西。比后悔更要安全;)
Zend\Mvc\Controller\AbstractActionController
方法namespace Application\Controller\Plugin;
class Acl extends \Zend\Mvc\Controller\Plugin\AbstractPlugin implements \Zend\ServiceManager\ServiceLocatorAwareInterface {
private $serviceLocator;
public function doAuthorization(\Zend\Mvc\MvcEvent $event) {
// Retrieve user role, if you have them or just use guest
$role = 'guest';
$resource = get_class($event->getTarget());
$action = $event->getRouteMatch()->getParams()['action'];
if (!$this->getAcl()->isAllowed($role, $resource, $action)) {
// Handle the access denied
// Could be a redirect to login/home page, or just an 404 page
}
}
public function getAcl() {
// Create the ACL object
$acl = new \Zend\Permissions\Acl\Acl();
// Add your roles
$acl->addRole(new \Zend\Permissions\Acl\Role\GenericRole('guest'));
// Add your resources
$acl->addResource(new Resource(\YourModule\Controller\YourController::class));
// By default, block access to all resources.
$acl->deny();
// Add, one by one, access to resources for all roles
$acl->allow('guest', \YourModule\Controller\YourController::class, ['action1', 'action2'], new \YourModule\Assertion\YourIdAssertion());
return $acl;
}
public function getServiceLocator() {
return $this->serviceLocator;
}
public function setServiceLocator(\Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) {
$this->serviceLocator = $serviceLocator;
}
}
允许您定义以下参数:
最后,在声明哪些角色可以访问特定资源的特定操作之后,您还可以告诉ACL一个“规则”,例如“只有在满足此条件的情况下才可以访问该操作”。这些规则是通过allow
指定的:
Assertions
希望这对您有帮助!