我正在使用ZF 1.12.2,我想为我的Zend_Acl权限创建一个黑名单,因为我的限制少于允许。我的ACL资源名称基于我的控制器名称和我的控制器操作名称上的权限。
现在,我否认这样的特权:
$acl->deny('user', null, 'User::login');
当我向我的用户控制器添加操作时,我希望隐式地授予用户角色访问权限,除非我明确拒绝它们。因此,如果我在用户控制器上添加编辑操作,则不必执行此操作:
$acl->allow('user', null, 'User::edit');
默认情况下,如果权限不存在,Zend_Acl::isAllowed
将返回false。除非在调用父类之前将其子类化并存储,否则很难知道添加了哪些特权。我一直试图破译Zend_Acl::$_rules
,因为我认为它符合我的需要,我可以避免继承。允许不存在的权限可以传递Zend_Acl::isAllowed
吗?
更新:现在,我的工作子类方法My_Acl::isAllowed
如下所示。 My_Acl::__construct
接受一个数组配置,该数组配置包含要添加的嵌套特权/资源的角色。
public function isAllowed($role = null, $resource = null, $privilege = null)
{
if (null !== $resource) {
if (is_string($resource)) {
$resource_id = $resource;
} else {
$resource_id = $resource->getResourceId();
}
if (!in_array($resource_id, array_keys($this->_resources))) {
return true;
}
}
if (null !== $privilege) {
if (!in_array($privilege, array_keys($this->_privileges))) {
return true;
}
}
return parent::isAllowed($role, $resource, $privilege);
}
答案 0 :(得分:0)
我不是ACL的专家,但据我所知,您可以allow()
使用所有内容,然后根据需要使用deny()
。
//user can do all, by not specifying resources or privileges, all is allowed
$acl->allow('user');
//explicitly deny specific resources and privileges
$acl->deny('user', null, 'User::login');
请注意所应用的任何继承,因为这可能会导致意外行为。
希望这有帮助。
答案 1 :(得分:0)
您的isAllowed
方法中有太多检查会使事情变得复杂
如果你没有使用模块化方法(HMVC),你应该使用isAllowed(role, resource, privilege)
的第二个参数,可以使用controller作为第二个参数,并将action作为第三个参数:$acl->allow('user', 'user', 'edit');
如果您遵循此方法,则需要将控制器添加为资源
//user controller as resource.
$this->add(new Zend_Acl_Resource('user'));
定义任意资源:nullresources
// any resource
$this->add(new Zend_Acl_Resource('nullresources'));
$this->addRole(new Zend_Acl_Role('guest')); // guest role - no login (it's good to have something like this)
$this->allow('guest', 'nullresources');
如果添加任意资源:nullresources
,您可以跳过isAllowed中的一些步骤。
/**
*
* @param string $role
* @param string $resource (module name)
* @param String $privilege (controller name: action name)
* @return Boolean
*/
public function isAllowed($role = null, $resource = null, $privilege = null)
{
/**
* by default, undefined resources are allowed to all
*/
if (!$this->has($resource)) {
$resource = 'nullresources';
}
return parent::isAllowed($role, $resource, $privilege);
}
如果您遵循这种方法,您应该能够以这种方式使用它:
$acl->allow('user', 'user');
$acl->deny('user', 'user', 'login');
修改强>
您还需要更改您正在进行检查的位置,例如,如果您使用插件,则可能是引导程序或某些插件,这是一个示例类
<?php
class My_Acl_AccessCheck extends Zend_Controller_Plugin_Abstract
{
private $_acl = null;
public function __construct(Zend_Acl $acl)
{
$this->_acl = $acl;
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
/**
* get controller name
* @var String $controller
*/
$controller = $request->getControllerName();
/**
* get action name
* @var String $action
*/
$action = $request->getActionName();
/**
* getting the role from the registry and defining some
* role for the null character as guest makes authentication more flexible
* if the roles is not allowed to use the resource then the user is
* redirected to action notAllowed of controller user
*
* Parameter passed for isAllowed: role, ControllerName, ActionName
*/
if(!$this->_acl->isAllowed(Zend_Registry::get('role'), $controller, $action))
{
$request->setModuleName('default')
->setControllerName('user')
->setActionName('notAllowed');
}
}
}
在bootstrap
$this->_acl = new My_Acl();
$frontController = Zend_Controller_Front::getInstance();
$frontController->registerPlugin(new My_Acl_AccessCheck($this->_acl));