PHP Based Access Control Lists

I have already created the database and PHP code necessary to implement this custom ACL system. Now I have to "Authorize" the current user and that is where I need your advice.

The system is based on the flexible assignment of authority for both system users and system modules. It also has some predefined, albeit custom groups, capabilities to also create fully customizable groups. A global rule can also be applied on top of an ACL, but it has the lowest priority over groups or users assigned permissions.

To take a better picture:

Predefined Groups:

  • Limited access (no access)
  • Primary user
  • Power User
  • Administrator
  • Visitors (sample custom group)

The following are access levels (name / value pairs):

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

Note: "Allow" has a higher priority on "Deny", therefore, if you have user X "Forbidden" in group "A", but "Allowed" in group "B" with certain access, then it is "Allowed" , finally. On the other hand, if user X has "full access" as a member of the Administrator group, but if he simply "refused" with a certain access, he does not have access at the end, which means "Deny" has a higher priority on " Allow. "

At the top level, you might have something like this:

  • "Administrator" * "1", which means that the administrator has full access to the system.
  • "Visitors" * "0", which means that visitors are not allowed anything

My question is how to handle these checks? Imagine that we have a simple authorization mechanism. We have some indexes in our $_SESSION['user'] like $_SESSION['user']['login'] = true; and $_SESSION['user']['id'] = $row['user_id'] , right?

Now, if you want to implement this mechanism in your script, how do you do it?

I can check global access rules first. Then I would see if the user is already logged in or not. If so, just get all of his groups, then look at the permissions table to find out what rights are assigned to his groups and his user ID, and then save them in a user session. Then, when the module says that these are my necessary permissions to run, I would look to find out if the user has sufficient access to the requested module or not.

It looks pretty complicated! Any advice or help is appreciated! :)

Edit:

I do not use any frameworks. Actually I use, but this is mine. So, there is no pre-prepared ACL!

Update:

Do you have an idea of ​​an efficient way to prioritize (rewrite / replace?) ACLs?

Deny is the highest, then Allow , and then Disallow . Also User assigned ACLs are the highest, then Group ACLs and finally Global ACLs.

Here is what I came up with finally:

There is an Array , for example:

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

First, I would look for all the global rules * and put them in an 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 search for group based ACLs:

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

In the end, I would like to find the ACLs assigned by the user:

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

I think everything will be fine, any ideas?

It works pretty well now :)

+4
source share
2 answers

This is how I process it in MVC environment, create a table with this structure:

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

Then I use -1 for the group and user_id to represent the wildcard and * for the controller and action. Therefore, in your example, the administrator can do anything (1,4, -1,). Or we can say that Power users can change users (2,3, -1, user, *). Or if you want to grant permission to one person (user_id of 34) no matter what group they are in (3, -1.34, user, update). If you want to keep 0-3 for permission, deny, just add a column. Then you simply check which controller and action is invoked and find any permissions that apply to the group (s) and to them specifically.

+2
source

Just create a permissions / groups table:

 id, group/permission name 

Then create tables for many link groups for users:

 id, user_id, group_id 

You do not need access levels if you just use group permissions.

Then in your code, just check the user for the group as follows:

 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?

+1
source

Source: https://habr.com/ru/post/1433576/


All Articles