2013-03-22 17 views
2

我正在使用ZF 1.12.2,並且我想爲我的Zend_Acl特權創建一個黑名單,因爲我的限制比允許的要少。我將我的ACL資源名稱放在我的控制器名稱和我的控制器操作名稱上的特權上。如何在Zend_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

你可以將代碼添加插件,你正在檢查訪問。 'controller :: action'這個部分基本上。 – 2013-03-25 12:15:45

+0

@roko新增了我的重寫isAllowed方法 – danronmoon 2013-03-25 13:04:23

回答

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'); 

只知道應用的任何繼承,因爲這可能會導致意外的行爲。

希望這會有所幫助。

+0

對不起,這不起作用。檢查'$ acl-> isAllowed('user',null,'bogusPrivilege')'返回false。 – danronmoon 2013-03-23 11:06:05

0

您的isAllowed方法,使得如果不使用模塊化的方法(HMVC),你應該使用isAllowed(role, resource, privilege)第二參數可以使用控制器作爲第二個參數和動作爲第三PARAM事情複雜

太多的檢查像這樣:$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)); 
+0

我確實喜歡在重寫子類方法中初始的空資源和資源檢查。但是,使用Zend_Acl檢查特權的存在是另一回事。是否可以調整Zend_Acl以允許黑名單方法來授予特權,並允許其他任何方式拒絕對角色的訪問?我真的想避免重複自己是Zend_Acl中存在的代碼。 – danronmoon 2013-03-25 14:20:43

+0

我對你的方法有點困惑。你如何將角色映射到特權以及'$ this - > _ privileges'是什麼?黑名單(被拒絕)對角色的行爲? 如果您將角色映射到特權是正確的,那麼您的方法也應該可行。 你的方法會和Zend_Acl做類似的事情,我仍然不確定你爲什麼不允許Zend_Acl檢查這些東西。而這又是如何讓它重複自己? – 2013-03-25 14:38:40

相關問題