PHP复杂的基于角色的访问控制列表

时间:2012-09-11 12:51:28

标签: php security acl role-base-authorization

我已经制作了实现这个自定义ACL系统所需的数据库和php代码。现在我必须'授权'当前用户,这就是我需要你的建议。

系统基于对系统用户和系统模块的灵活权限分配。它还有一些预定义的,比如用户组,也可以制作完全自定义的组。全局规则也可以应用于ACL之上,但它的优先级低于分配权限的组或用户。

更好地拍照:

预定义组:

  1. 有限(无法访问)
  2. 基本用户
  3. 超级用户
  4. 管理员
  5. 访客(自定义组的样本)
  6. 以下是访问级别(名称/值对):

    • disallow / 0
    • allow / 1
    • deny / 2
    • 允许if owner / 3

    注意:'允许'在'禁止'上具有更高的优先级,因此如果您在A组上有用户X'禁止',但在某个访问中有B组'允许',那么他最终会'允许'。另一方面,如果用户X通过成为“管理员”组的成员而具有“完全访问权限”,但如果他只是在某个访问权限上“拒绝”,则他最后没有访问权限,这意味着“拒绝”优先于'允许'。

    在顶级,您可能会遇到以下情况:

    • “管理员”*“1”,表示管理员对系统具有完全访问权限
    • “访客”*“0”,表示访客不得进行任何操作

    我的问题是如何处理这类支票?想象一下,我们有一个简单的授权机制。我们会$_SESSION['user']中有一些索引,例如$_SESSION['user']['login'] = true;$_SESSION['user']['id'] = $row['user_id'],对吧?

    现在,如果你想在你的脚本上实现这个机制,你将如何做到这一点?

    我可能会首先检查全局访问规则。然后我会查看用户是否已登录。如果是,只需获取所有组,然后查看权限表以查看为其组分配了哪些权限及其用户ID,然后将其存储在用户会话中。然后,当模块说这是我需要运行的权限时,我会查看用户是否有足够的权限访问所请求的模块。

    看起来很复杂!任何帮助或建议都非常感谢! :)

    修改

    我没有使用任何框架。其实我用,但这是我自己的。所以,这里没有预先制作的ACL!

    更新

    您是否了解优先(覆盖/替换?)ACL的有效方法?

    Deny最高,然后是Allow,然后是Disallow。此外,User已分配的ACL最高,然后是Group ACL,最后是Global ACL。

    以下是我最终提出的建议:

    有一个Array,就像这样:

    $_SESSION['ACL'][$module][$action] = $access_level; // 0, 1, 2, 3
    

    首先,我会查找所有全局规则*,并将它们放在数组上:

    // The current user can see the map, applied by a global rule
    $_SESSION['ACL']['map']['render'] = 1;
    
    // All the other permissions are disallowed by default
    $_SESSION['ACL']['*']['*'] = 0;
    
    // He can edit his preferences, (Owner)
    $_SESSION['ACL']['user']['*'] = 3;  
    

    然后,我将寻找基于组的ACL:

    // User could access the Analyze module, all the methods 
    // with Permission Name "report". Applied by being a member 
    // of "Moderator" Group
    $_SESSION['ACL']['analyze']['report'] = 1;
    
    // User NOT allowed to access "groups" module, let say
    // it reserved for "admin" group! - To see the ACLs' Overwriting!
    $_SESSION['ACL']['groups']['*'] = 0;
    

    毕竟,我会寻找用户指定的ACL:

    // User have Full Access to the "groups" module.
    // It's gonna replace the last ACL, applied by "Moderator" group
    // Note that the order of processing ACLs is IMPORTANT!
    $_SESSION['ACL']['groups']['*'] = 1;
    

    我想这会完美,任何想法?

    现在相当不错:)

2 个答案:

答案 0 :(得分:2)

以下是我在MVC环境中处理它的方法,创建一个具有以下结构的表:

(id, group_id(int), user_id(int), controller(varchar), action(varchar)) 

然后我在group和user_id上使用-1表示通配符,在控制器和操作上使用*。因此,在您的示例中,管理员可以执行任何操作(1,4,-1,)。或者让Power Users可以修改用户(2,3,-1,用户,*)。或者,如果您想给一个人(user_id为34)一个权限,无论他们在哪个组(3,-1,34,用户,更新)。如果您想将0-3存储为允许,禁止,只需添加一列。然后,您只需检查正在调用的控制器和操作,并找到适用于该人员组及其特定权限的任何权限。

答案 1 :(得分:1)

只需创建权限/组表:

id, group/permission name

然后,为用户创建多对多的表链接组:

id, user_id, group_id

如果您只是使用群组权限,则不需要访问级别。

然后,在您的代码中,只需检查该组的用户:

function checkAccess($pageLevelRequired)
{
  // run query based on current user session id
  // run your query to check if the current user belongs to the group required to view this page.
}

有意义吗?