всем привет
можно ли организовать доступ на основе групп ролей RBAC
ну типа, чтобы не писать кучу отдельных ролей: admin_company1, admin_company2, admin_company3 и т.д.
всем привет
можно ли организовать доступ на основе групп ролей RBAC
ну типа, чтобы не писать кучу отдельных ролей: admin_company1, admin_company2, admin_company3 и т.д.
какая задача?
В принципе в системе проверки доступа нет жёсткого ограничения по типу прав то есть разветвлённость прав доступа может быть любой для лучшего понимания было разделено на роли задачи операции!
то есть этот вариант вполне будет работать:
$auth=Yii::app()->authManager;
$role=$auth->createRole('role1');
...
$role=$auth->createRole('role2');
...
$group=$auth->createRole('group');
$group->addChild('role1');
$group->addChild('role2');
К стати парни хотел бы присоединиться к вашей дискусии, реализовал RBAC на сайте, вот с такой схемой
return array(
'guest' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'Guest',
'bizRule' => null,
'data' => null
),
'1' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'User',
'children' => array(
'guest', // унаследуемся от гостя
),
'bizRule' => null,
'data' => null
),
'2' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'Moderator',
'children' => array(
'user', // позволим модератору всё, что позволено пользователю
),
'bizRule' => null,
'data' => null
),
'3' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'Administrator',
'children' => array(
'moderator', // позволим админу всё, что позволено модератору
),
'bizRule' => null,
'data' => null
),
);
И вроде как здесь уже как бы зашита иерархия, аля то что можно 1-му, то можно и 2-му и 3-му. Но почему то в этом конфиге это ПРИНЦИПИАЛЬНО не работает.
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('1'),
),
//array('allow', // allow authenticated user to perform 'create' and 'update' actions
//'actions'=>array('create','update'),
//'users'=>array('@'),
//),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('create'),
//'users'=>array('admin'),
'roles'=>array('1'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete','update','index','view','create'),
//'users'=>array('admin'),
'roles'=>array('3'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
имеется ввиду
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete','update','index','view','create'),
//'users'=>array('admin'),
'roles'=>array('3'),
если убрать ‘index’,‘view’ то оно не будет доступно, хотя по иерархии должно быть.
во первых у тебя в конфиг фаиле проблема
по идее он должен выглядеть так
return array(
'guest' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'Guest',
'bizRule' => null,
'data' => null
),
'user' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'User',
'children' => array(
'guest', // унаследуемся от гостя
),
'bizRule' => null,
'data' => null
),
'moderator' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'Moderator',
'children' => array(
'user', // позволим модератору всё, что позволено пользователю
),
'bizRule' => null,
'data' => null
),
'administrator' => array(
'type' => CAuthItem::TYPE_ROLE,
'description' => 'Administrator',
'children' => array(
'moderator', // позволим админу всё, что позволено модератору
),
'bizRule' => null,
'data' => null
),
);
а в контроллере
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('user'),
),
//array('allow', // allow authenticated user to perform 'create' and 'update' actions
//'actions'=>array('create','update'),
//'users'=>array('@'),
//),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('create'),
//'users'=>array('admin'),
'roles'=>array('user'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete','update','index','view','create'),
//'users'=>array('admin'),
'roles'=>array('administrator'),/*!!! но наверно тут по идее должен быть не administrator а moderator !!!*/
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
Спасибо за ответ. Хотел сказать то что у меня просто в базе идут роли 1,2,3 а не полные названия. Возможно я понял ошибку в своей схеме, там в наследование написаны не цифры, а в моем случае это ошибка но, я непонемаю где же в вашей схеме идет иерархия ролей если и user и administrator имеют страницу create, просто если есть иерархия только у юзера должна быть эта функция, та как administrator её уже будет иметь по наследованию. Или это не так. Или это касается только таклй конструкции?
if(Yii::app()->user->checkAccess('3')){
echo "hello, I'm administrator"; }
вот иерархия то что я представил
return array(
'guest' => array(
...
),
'user' => array(
...
'children' => array(
'guest', // унаследуемся от гостя
),
...
),
'moderator' => array(
...
'children' => array(
'user', // позволим модератору всё, что позволено пользователю
),
...
),
'administrator' => array(
...
'children' => array(
'moderator', // позволим админу всё, что позволено модератору
),
...
),
);
вот ваша
return array(
'guest' => array(
...
),
'1' => array(
...
'children' => array(
'guest', // унаследуемся от гостя
),
...
),
'2' => array(
...
'children' => array(
'user', // !!! тут ошибка такой роли нету
),
...
),
'3' => array(
...
'children' => array(
'moderator', // !!! и тут ошибка такой роли нету
),
...
),
);
по поводу конструкции
система одинаково подаёт запрос на проверку прав доступа просто в данной кострукции
Yii::app()->user->checkAccess($operation,$params=array(),$allowCaching=true)
можно передать доп. параметры
по поводу того как это работает в случае с "create" (проверка на право user)
и так есть пользователь с ролью "user"
система проверяет вначале не является ли данное правило правилом по умолчанию если да то разрешить если нет идём дальше
система запрашивает все права связные с текущим пользователем получает массив проверяет есть ли у данного пользователя данное правило !!!!о ура правило есть значит разрешить
случай 2
есть пользователь с ролью "administrator"
система проверяет вначале не является ли данное правило правилом по умолчанию если да то разрешить если нет идём дальше
система запрашивает все права связные с текущим пользователем получает массив проверяет есть ли у данного пользователя данное правило если да то разрешить если нет идём дальше (в нашем случае у него нет прямого права)
система запрашивает всех родителей данного правила в нашем случае она получит массив с одним правилом это moderator
пробегается и опять же проверяет если у данного пользователя разрешения на право только у же на ‘moderator’
то есть система будет рекурсивно проходить иерархически по всем правам то есть от права user(так как мы запросили это право) до права administrator и проверять нет ли у пользователя данного права если найдёт вернёт разрешение если нет отказ в доступе
понятия роли задачи и операции созданы для лучшего понимания структуры
то есть предполагается что вся структура будет выглядеть примерно так
есть опреации
Post.Read,
Post.Create,
Post.Update,
Post.Delete
есть задачи
Post.Editor дети Post.Read,Post.Create,Post.Update, Post.Delete
Post.EditorOwn (тут будет проверка является ли данный пост этого пользователя) дети Post.Read,Post.Create,Post.Update, Post.Delete
Post.Reader дети Post.Read
а уже роли группируют данные права по задачам
роль Guest дети Post.Reader
роль User дети Post.EditorOwn, Guest
роль Moderator дети Post.Editor, User
роль Administrator дети Moderator
вот сам механизм проверки если хочешь покопаться в исходниках
http://www.yiiframework.com/doc/api/1.1/CPhpAuthManager#checkAccess-detail
Остальное переварю чуть позже, но касательно первого я же написал, что я увидел где ошибка, в том плане что вот новый вариант
eturn array(
'guest' => array(
...
),
'1' => array(
...
'children' => array(
'guest', // унаследуемся от гостя
),
...
),
'2' => array(
...
'children' => array(
'1', //
),
...
),
'3' => array(
...
'children' => array(
'2', //
),
...
),
);
И тем более у меня цифры так как, они у меня в БД. Но все равно мне не понятно, если пользователю разрешено использовать ф-ю create, то почему мы должны прописывать её и админу если админ наследует права пользователя.
К стати вот вопрос а для чего нужны вот эти константа в AR
const ROLE_ADMIN = 'administrator';
const ROLE_MODER = 'moderator';
const ROLE_USER = 'user';
const ROLE_BANNED = 'banned';
Просто в руководстве, они присутсвуют.
можно ссылку на документацию
тут я ничего не вижу подобного
http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth
система не знает что пользователю с ролью administrator всё можно
системе на всё наплевать пусть роль называется хоть nafnaf ей главное что были все связи чтоб она смогла проверить
а то что в примере кто то зарезервировал стандартные названия ролей для простоты работы это ещё ни о чём не говорит! если только в системе проверки ни сделано каких то костылей!
как я и говорил здесь подразумевается что у AR пользователя будет иметь поле роль но для того чтоб она была функциональна и участвовала в процессе проверки данных нужно написать ещё пару костылей в стандарте подразумевается что пользователь может иметь не только одну роль!!!
про костыли
в примере реализовано получение роли компонентой user (WebUser::getRole)
на до ещё добавить следующие костыли в классе WebUser
public function checkAccess($operation,$params=array(),$allowCaching=true)
{
if($this->role == User::ROLE_ADMIN)
return true;
if($this->role == User::ROLE_BANNED)
return false;
if(!Yii::app()->getAuthManager()->isAssigned($this->role,$this->id))
Yii::app()->getAuthManager()->assign($this->role,$this->id);
return parent::checkAccess($operation,$params,$allowCaching);
}
примерно как то так