【问题标题】:CakePHP Access Allocation on Role Based specific Data Access基于角色的特定数据访问的 CakePHP 访问分配
【发布时间】:2011-09-16 06:09:26
【问题描述】:

我的项目要求是这样的:

在顶部,将有管理员,他将拥有所有 d 访问权限,第一级

在Administrator下,会有Department Heads,除了Creating Department Heads之外,他们拥有所有的权限

在部门负责人下,将有其他成员,他们将管理分配给他们的部门明智数据。

现在,所有不同的部门负责人都将拥有自己的信息和成员,并且所有部门负责人/成员都可以访问他们自己正在输入/管理的特定记录。

现在,有了 CakePHP 的 ACL 组件,我可以划分角色和他们的访问级别,但所有部门负责人都可以看到其他部门负责人的信息,因为他们将具有相同的访问权限,所有其他成员都可以看到其他成员不同部门的信息,因为他们将具有相同的访问级别。

我的项目复杂性在于 - 尽管它们与其他人具有相同的级别/角色分配,但它们应该仅对其分配或创建的信息/数据可见。

谁能建议我最合适的选择,使用 CakePHP 现有的插件来管理所有这些事情。

我可以通过自定义默认 ACL 组件来工作,但这会花费比预期更多的时间。

任何更好的想法/建议将不胜感激!

【问题讨论】:

  • 为什么不只是在查看个人资料信息时进行检查?您可以使用 Auth 获取当前用户。
  • @JohnP:嗯,这不仅仅是个人资料信息,而且会有很多内容信息和数据,应该是特定于用户的,只有在特定用户登录后才能查看。另外,当部门主管已登录,他可以为他们下的成员创建访问权限。@ 目前,我们正在准备我们的结构,所以在我们实际开始项目工作之前要求确认..
  • 在这些情况下,您始终可以编写一个组件来为您进行检查。或者在运行时允许/拒绝,具体取决于谁登录

标签: cakephp role-based-access-control


【解决方案1】:

在我看来,ACL 并不是那么神奇。例如:ACL 可以管理权限以告诉谁有权添加/编辑/删除产品..但它无法更改查询以根据定义的权限过滤产品(例如“来自部门 A 的用户只能查看 A 部门的产品").. 其实那是个谎言,ACL 可以管理它,但它可能不实用,因为每次添加产品时,您都必须创建一个 ACO,并在 AROS_ACOS 表中设置权限而且由于 AROS 是一个树形结构,所以如果您打算查询数据,它很容易成为一个难题

我会使用group-only ACL 来控制对某些页面/操作的访问并制定如下规则:

  • "部门负责人可以访问页面 “产品列表”和添加/删除/修改 产品”
  • “管理员可以访问 所有页面”
  • "其他用户可以访问 “产品列表”,他们可以添加 产品,但不删除它们”

我会根据连接的用户调整我的查询,因此在“产品列表”页面的控制器中,我会执行以下操作:

  • 如果连接的用户属于部门主管,则选择product.department_id=connected_user.department_id 所在的所有产品
  • 如果连接的用户是管理员,则选择所有产品

如果你有太多的查询并且你不想做成千上万的 if 语句,你可以创建一个组件、一个行为或者extend the find() method in the app_model。这个想法是捕获所有查询并检查查询中使用的模型之一是否具有名为“department_id”的字段,如果有,则将model.department_id=connected_user.department_id 条件添加到查询中。

我为一个可以用多种语言查看的网站做到了这一点,每种语言都有自己的用户、数据、日志等,并且有一个管理员可以查看所有信息......这对我来说非常有用 = )

祝你好运!

已编辑: 我使用的行为是:

<?php 
class LocalizableBehavior extends ModelBehavior { 

    /** 
     * Filter query conditions with the correct `type' field condition. 
     */ 
    function beforeFind(&$model, $query) 
    {
        /**
         * Condition for the paginators that uses joins
        */
        if(isset($query['joins']) && !empty($query['joins'])){
            foreach($query['joins'] as $key => $joinTable){
                if(ClassRegistry::init($joinTable['alias'])->hasField('lang')){
                    $query['joins'][$key]['conditions'][] = $joinTable['alias'].".lang = '".$_SESSION['lang']."'";
                }
            }
        }

        /**
         * condition for the normal find queries
        */
        if($model->hasField('lang') && $model->name != "User"){
                $query['conditions'][$model->name.'.lang'] = $_SESSION['lang'];
        }
        return $query;
    }

} 
?>

真的很简单,我更改查询以添加条件以匹配当前语言 ($_SESSION['lang'])。在控制器中,我需要做的就是附加 LocalizableBehavior 并照常使用 find 方法:

$this->Products->find('all');

【讨论】:

  • 感谢您分享的想法和信息。它对我有很大帮助,并且会继续您的建议,您可以与我分享一些文件吗?就像组件/行为一样,如果你已经创建了 n 使用的..
  • 嗯...这种行为方法似乎很有趣,谢谢分享
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 2015-11-20
  • 2014-09-24
  • 2010-09-11
  • 2017-10-19
  • 2011-04-25
相关资源
最近更新 更多