Pregunta

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.

¿Fue útil?

Solución

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?

Otros consejos

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top