Domanda

I have a question about the rbac system. I think I've pretty well understood it but I need more informations about a special case.

I would like to do the autorisations on groups instead of users. I mean for instance the group "HR" has permission to create a person. Then any person who join this group would have it as well.

Let me give you more informations.

A part of my database: enter image description here

And this a part of what my group hierarchy could be: enter image description here

So what I'm looking for, this would be a must, is a system where each group has some autorizations. People get the autorizations of their group and of their parents group (for instance people in "Forsys" has the autorizations of "Forsys", "R&D" and "Administration").

The solution I see at the moment is using bizrule. But I'm not sure write php code in database is a good idea and then if I update the group hierarchy (R&D inherits of RH instead of Administration) I would have to modify bizrule in database. I tried it and it works well but as you can see it require a lot of code.

$user = User::model()->with("people","people.groups")->findByPk(Yii::app()->user->id);
foreach($user->people[0]->groups as $group)
  if($group->id == 2)
     return true;
return false;

It's just for see if a user is in a group (without checking parent groups and hierarchy)

Another possibility could be create a new table "group_auth" where we would say for instance:

-Group_2 has role "managePerson"

-Group_3 has operation "deleteUser" ...

And then everytime a user is added in or removed of a group we would update his autorizations in the auth_assigment table.

I'd like to hear other opinions on this subject. All comments will be appreciated :)

Thank you for reading and sorry for my English if you had difficulties to understand me.

Michaël S.

È stato utile?

Soluzione

Do users ever get their own authorization items? If not, seems like you could in essence swap out the userid column in auth_assignment and name it / treat it as groupID instead. That way you wouldn't need to worry about keeping user auth assignments in sync with your group roles.

A couple of places you'd probably need to make some changes: - by default CWebUser passes in the logged in userid for use in bizrules. Might be good to change that our with your own override that passes in groupId/groupIds instead. - you'd need to override CDbAuthManager and rework some of how things work there

We've done something similar on a project I've worked on (we were handling multi-tenant RBAC custom permissions), which required custom CDbAuthManager overrides. It gets a bit tricky if you do it, but there is an awful lot of power available to you.

Edit: Understood about your users sometimes needing to have additional authorizations. What if your group has a 'roles' field with different roles serialized in it (or some other method of having multiple roles stored for that group, could also be a relationship).

Then, on user login (for efficiency), you'd store those roles in session. Probably the easiest way to handle things would be to write a custom checkAccess for your WebUser override: https://github.com/yiisoft/yii/blob/1.1.13/framework/web/auth/CWebUser.php#L801

as that will make things simpler to do your custom checking. Then I'd probably do something like:

if(Yii::app()->user->hasGroupAccess() || Yii::app()->user->checkAccess('operation/task/role')) {
    ....
}

In your WebUser hasGroupAccess method, you could loop over all group roles and send those to checkAccess as well.

Think that will work?

Altri suggerimenti

What I use to check access for groups when it's in another table, or somewhere else in the application I give the user the role per default. By using this:

return array(
    'components'=>array(
        'authManager'=>array(
            'class'=>'CDbAuthManager',
            'defaultRoles'=>array('authenticated', 'R&D', 'Administration'),
        ),
    ),
);

Under: Using Default Roles

By using this, every user gets these assignments. Now, I create a business rule to make sure that the checkAccess('group') will return the correct value.

For example in your case the business rule for R&D would be:

return (
    count(
        Person::model()->findByPk(Yii::app()->user->id)->groups(array('name'=>'R&D'))
    ) > 0
) ? true : false;

So what this does is:

  • find the logged-in person by primary key
  • look into groups (from the user) for the group with name R&D
  • if there is a group: return true (else return false)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top