Zend_ACL限制?

时间:2010-06-29 17:10:12

标签: zend-framework zend-acl

我正在考虑使用Zend_ACL。但是,对我而言,您似乎创建了角色,然后将这些角色授予他们可以访问或无法访问的控制器和操作。

然而,对我而言似乎相当有限。我之前创建了一个用户权限系统,我存储了user_id,模块,控制器和他们可以访问的操作,但我从来没有给他们一个组。因此,每个模块,每个控制器的每个用户,每个操作基于他们可以访问的内容。

原来如此!我想知道我是否希望减少群组的限制,我应该为用户提供一个组并默认设置这些组权限。然后加载我的用户特定角色并覆盖默认组设置的角色:那你们会怎么做?

5 个答案:

答案 0 :(得分:3)

您绝不仅限于使用角色系统来表示Zend_Acl中的群组。

例如:

在一个应用程序中,我有我的基本用户对象,实现Zend_Acl_Role_Interface,在这种情况下返回一个特定于用户的字符串。为简单起见,我们只需说user-1之类的内容,其中数字部分是用户的唯一ID。

初始化用户对象时,它会将自身添加到ACL中,其中特定于用户的角色继承自更通用的角色(类似于组)。

if(!$acl->hasRole($this)) {
    $acl->addRole($this, $this->role); // Let's say role == 'member' here
}

这允许您设置父角色的一般规则(或角色,您可以将数组作为第二个参数传递给addRole,以拥有多个父级。另外,请记住角色在树的所有方向都有一个沿袭,所以在这种情况下,父角色本身也可能有父角色。)

因此,为了说明这里的灵活性,让我们假设这个基本的ACL设置(这是理论上的,我只是为了这个答案的目的而写它):

$acl->addRole('guest');
$acl->addRole('member', 'guest');

$acl->allow('guest', 'comments', 'read');
$acl->allow('member', 'comments', 'write');

$user = $My_User_Model->find(1);
$acl->allow($user, 'comments', 'moderate');



$acl->isAllowed($user, 'comments', 'read'); // true
$acl->isAllowed($user, 'comments', 'write'); // true
$acl->isAllowed($user, 'comments', 'moderate'); // true

$acl->isAllowed('member', 'comments', 'moderate'); // false

等等......

Zend Framework组件的优点在于,您并不仅限于以特定方式使用它们。是的,虽然这有时令人生畏,并且往往需要花费更多的时间投入初始规划和实施,但从长远来看,这是很好的。

另外,就个人而言,我不喜欢将ACL权限直接映射到控制器/动作构造。但这是一个完全不同的对话。

答案 1 :(得分:1)

当我开始使用Zend_Acl时,我问very similar question。我的帖子用代码列出了我的解决方案它可能对你有帮助。 :)

答案 2 :(得分:0)

你走在正确的轨道上。

没有严格定义的“组”或“用户”的概念。

你只有角色。您可能拥有“编辑器”这样的角色,可以访问某些资源(如特定操作,甚至某些“文章”对象)。您可能还有像user_1234这样的角色,可能有其他规则。

您可以为ID为1234的用户提供这两个角色。

答案 3 :(得分:0)

回复上述内容(我的回答很长)

是的,我不是那样做的忠实粉丝。我宁愿为特定用户加载一个数组:

$item['Movie'] = 1;
$item['Movie']['manage']['edit'] = 0;

然后执行一个插件,将这些权限(从数据库加载到数组中)加载当前模块/控制器/操作并检查。

if (isset($item[$module]) && $item[$module] == 1) {
   if (isset($item[$module][$controller][$action]) && $item[$module][$controller][$action] == 0) {
       return false;
   }
   return true;
} else { 
 return false;
}

然后在我的bootstrap中,如果它为false,则抛出异常。 (请记住,这是针对我网站的管理区域,而不是前端,所以我不会对一般用户访问感到讨厌。

此外,我将该数组传递给视图,并在链接上执行简单的if语句:

<?php if ($this->userPermission['Movie']['manage']['edit'])) { ?>
<a href="/administration/Movie/manage/edit/id/1">Edit Movie</a><?php } ?>

缺点是如果该方法改变了控制器,我必须编辑模板。但是我从我读过的教程中看不到Zend_ACL视图的含义,所以我不确定它与我在那里做的有很大不同。

答案 4 :(得分:0)

感谢您的反馈,但我决定创建自己的。如果有人有兴趣:

public function verify($controller=NULL, $action='index', $module='administration') {

    if ((isset($this->object[$module]['all']) && is_string($this->object[$module]['all'])) || isset($this->object[$module][$controller][$action]) || (isset($this->object[$module][$controller]) && is_string($this->object[$module][$controller]))) {
        return true;
    }
}

public static function check($values) {

    $module         = $values['module']     ? $values['module']     : 'administration';
    $controller     = $values['controller'] ? $values['controller'] : 'index';
    $action         = $values['action']     ? $values['action']     : 'index';
    $user_id        = $values['user_id'];

    $db    = Zend_Registry::get('dbAdapter');
    $query = $db->prepare(" 
        SELECT * 
        FROM `".self::table_name."` 
        WHERE 
            (
                (`module` = :module AND `controller` = :controller AND `action` = :action) OR
                (`module` = :module_2 AND `controller` = :controller_2 AND `action` = '') OR 
                (`module` = :module_3 AND `controller` = '' AND `action` = '')
            )
        AND enabled = 1 
        AND user_id = :user_id      
        ");

    $query->bindValue('module',         $module);
    $query->bindValue('module_2',       $module);
    $query->bindValue('module_3',       $module);
    $query->bindValue('controller',     $controller);
    $query->bindValue('controller_2',   $controller);
    $query->bindValue('action',         $action);
    $query->bindValue('user_id',        $user_id);

    $query->execute();
    $item = $query->fetch(PDO::FETCH_OBJ);
    $query->closeCursor();

    if (is_object($item)) {
        return $item;
    } else {
        throw new exception("Could not load user permission for this page ($module, $controller, $action)");
    }
}

并在视图中:

    <?php if ($this->user_permissions->verify('movie')) { ?>
        <li class="parent">
            <img src="/design/images/icon/dvd.png" /> <span class="highlighter"><a href="/administration/movie/index">Movie</a></span>
            <?php if ($this->user_permissions->verify('movie', 'add')) { ?>
                 | <a href="/administration/movie/add">Add</a>
            <?php } ?>
            <?php if ($this->user_permissions->verify('movie', 'featured')) { ?>
                <ul>
                    <li>
                        <img src="/design/images/icon/order.png" /> <a href="/administration/movie/featured">Order Featured</a>
                    </li>
                </ul>
            <?php } ?>
        </li>
    <?php } ?>