简体   繁体   English

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

[英]PHP complex role-based access control lists

I have already made the database and the php code needed to implement this customized ACL system. 我已经制作了实现这个自定义ACL系统所需的数据库和php代码。 Now I have to 'Authorize' the current user, and that's where I need your advices. 现在我必须'授权'当前用户,这就是我需要你的建议的地方。

The system is based on a flexible permission assignment both to the system users and system modules. 该系统基于对系统用户和系统模块的灵活权限分配。 It has also some predefined, let say user-groups, with the ability to make entirely customized groups also. 它还有一些预定义的,比如用户组,也可以制作完全自定义的组。 A global rule could also apply on top of the ACL, but it has the lowest priority over groups or users assigned permissions. 全局规则也可以应用于ACL之上,但它的优先级低于分配了权限的组或用户。

To picture it better: 更好地描绘它:

Predefined Groups: 预定义组:

  1. Limited (No Access) 有限(无法访问)
  2. Basic User 基本用户
  3. Power User 高级用户
  4. Administrator 管理员
  5. Visitors (Sample of a customized group) 访客(定制组的样本)

Here are the access levels (name / value pairs): 以下是访问级别(名称/值对):

  • disallow / 0 不允许/ 0
  • allow / 1 允许/ 1
  • deny / 2 否认/ 2
  • allow if owner / 3 如果拥有者/ 3允许

Note: 'Allow' has the higher priority on 'Disallow', so if you have user X 'Disallowed' on Group A, but 'Allowed' on Group B on a certain access, so he would 'Allowed' finally. 注意:'允许'在'禁止'上具有更高的优先级,因此如果您在组A上有用户X'禁止',但在某个访问中有B组'允许',那么他最终会'允许'。 On the other hand, if user X has the 'Full Access' by being a member of 'Administrator' Group, but if he just 'Denied' on a certain access, he has not the access at the end, that means 'Deny' has higher priority on 'Allow'. 另一方面,如果用户X通过成为“管理员”组的成员而具有“完全访问权限”,但如果他只是在某个访问权限上“拒绝”,则他最后没有访问权限,这意味着“拒绝”优先于'允许'。

At the top-level you may have something like these: 在顶层你可能有类似这样的东西:

  • "Administrator" * "1", which means Administrators have full access on the system “Administrator”*“1”,表示管理员对系统具有完全访问权限
  • "Visitors" * "0", which means Visitors are not allowed on anything “访客”*“0”,表示访客不得进行任何操作

My question is how to process these kind of checks? 我的问题是如何处理这类检查? Imagine we have a simple authorization mechanism. 想象一下,我们有一个简单的授权机制。 We would have some indexes in our $_SESSION['user'] like $_SESSION['user']['login'] = true; 我们在$_SESSION['user']会有一些索引,比如$_SESSION['user']['login'] = true; and $_SESSION['user']['id'] = $row['user_id'] , right? $_SESSION['user']['id'] = $row['user_id'] ,对吗?

Now, if you wanted to implement this mechanism on your script, how you're gonna do it? 现在,如果你想在你的脚本上实现这个机制,你将如何做到这一点?

I might check for the global access rules at first. 我可能会首先检查全局访问规则。 Then I would look if the user has already logged-in or not. 然后我会查看用户是否已登录。 If yes, just getting all of his groups, and then looking on the permissions' table to see which permissions are assigned to his groups and his user id, and then storing them on the user session. 如果是,只需获取所有组,然后查看权限表以查看为其组分配了哪些权限及其用户ID,然后将其存储在用户会话中。 Then when the module says this is my needed permissions to run, I would look then to see if the user has sufficient access to the requested module or not. 然后,当模块说这是我需要运行的权限时,我会查看用户是否有足够的权限访问所请求的模块。

Looks pretty complex! 看起来很复杂! Any helps or advice are highly appreciated! 任何帮助或建议都非常感谢! :) :)

Edit: 编辑:

I'm not using any frameworks. 我没有使用任何框架。 Actually I use, but it's my own. 其实我用,但这是我自己的。 So, there is no pre-made ACL here! 所以,这里没有预先制作的ACL!

Update: 更新:

Do you have any idea about an efficient way to prioritize (overwrite/replace?) ACLs? 您是否有任何关于优先(覆盖/替换?)ACL的有效方法的想法?

Deny is highest, then Allow and then Disallow . Deny最高,然后是Allow ,然后是Disallow Also User assigned ACLs are highest, then Group ACLs and finally Global ACLs. User分配的ACL也是最高的,然后是Group ACL,最后是Global ACL。

Here is what I came up with that finally: 以下是我最终提出的建议:

There is an Array , like this: 有一个Array ,像这样:

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

First, I would looking for all the Global Rules * , and will put them on the array: 首先,我会查找所有全局规则* ,并将它们放在数组上:

// 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;  

Then, I will look for Group based ACLs: 然后,我将寻找基于组的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;

After all, I would looking for User assigned ACLs: 毕竟,我会寻找用户分配的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;

I guess it would works perfectly, any ideas? 我想它会完美,任何想法?

It Works Pretty Well Now :) 它现在很好用:)

Here is the way I handle it in an MVC environment, create a table with this structure: 这是我在MVC环境中处理它的方式,创建一个具有以下结构的表:

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

Then I use -1 on group and user_id to represent a wildcard, and a * on the controller and action. 然后我在group和user_id上使用-1表示通配符,在控制器和操作上使用*。 So in your example an administrator can do anything (1,4,-1, , ). 因此,在您的示例中,管理员可以执行任何操作(1,4,-1 )。 Or lets say Power Users can modify users (2,3,-1,user,*). 或者让Power Users可以修改用户(2,3,-1,用户,*)。 Or if you want to give a single person (user_id of 34) a permission regardless of what group they are in (3,-1,34,user,update). 或者,如果您想给一个人(user_id为34)一个权限,无论他们在哪个组(3,-1,34,用户,更新)。 If you wanted to store your 0-3 for allow, disallow, just add a column. 如果您想将0-3存储为允许,禁止,只需添加一列。 Then you just check which controller and action is being called and find any permissions that apply to the person's group(s) and to them specifically. 然后,您只需检查正在调用哪个控制器和操作,并找到适用于该人员组及其具体的任何权限。

Just create your permissions/ groups table: 只需创建权限/组表:

id, group/permission name

Then, create your many to many table linking groups to users: 然后,为用户创建多对多的表链接组:

id, user_id, group_id

You don't need access levels if you're just using group permissions. 如果您只是使用组权限,则不需要访问级别。

Then, in your code, just check the user for the group like this: 然后,在您的代码中,只需检查组的用户,如下所示:

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.
}

Make sense? 合理?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM