На нижнем уровне иерархии ролей находятся следующие роли (для простоты предположим, что все относится к статье):
создание (С)
просмотр (R )
редактирование (U)
удаление (D)
Есть типы пользователей (роли верхних уровней):
администратор (CRUD)
редактор (RU)
пользователь (CRU[sup]own[/sup])
гость (R )
Логично было бы наследовать редактора от пользователя. Но у редактора не должно быть роли "создание". Насколько я понимаю, в Yii все разрешения (permissions) одного знака - только разрешающие. Поэтому добавить редактору роль "создание" с разрешением "запрещено" невозможно. Какие механизмы в реализации Yii существуют для решения этой проблемы?
Абсолютно нелогичная стратегия, в данной ситуации операции всем ролям должны назначаться независимо. Что будет если вы захотите изменить права пользователя, они изменятся у редактора, что может быть нежелательным побочным эффектом.
Возможно. Есть "задачи", есть bizRule. Но в данной ситуации нет проблемы, чтобы её решать.
Но если вы всеже считаете, что наследовать логично, то данную ситуацию можно разрешить следующим образом. Для операции C можно создать bizRule, который может проверять принадлежность роли редактор пользователю и возвращать false.
Как раз все наоборот. В сложной системе требуется каскадное изменение ролей при изменении ролей на нижних уровнях. И чем лучше (наиболее полно) продумано наследование, тем легче поддерживать систему. В случае приведенного мною примера определенно лучше поступить так, как вы посоветовали. Но этот вариант подходит только в том случае, если список ролей верхнего уровня (т.е. фактически групп) этим и ограничится
Опять же, представьте себе сложную систему, где таких "исключений" может быть достаточно много, чтобы захламить иерархию ролей ненужными костылями. И bizrule станет не тривиальной проверкой принадлежности роли редактор пользователю, а целой серией проверок.
Все эти проблемы связаны не с самой концепцией RBAC, а с ее недореализацией в Yii. Хотелось бы, чтобы были запрещающие права на роли, а также возможность назначать бизнес правила на отношение ролей. В этом и проявляется лаконичность RBAC по сравнению с ACL. Но, к сожалению, в текущей реализации фреймоврка этого нет.
Если интересно, можете почитать мой пост на эту же тему в форуме о запросах на разработку
В общих чертах я отвечал уже на этот вопрос выше. Преимущества такого подхода реально ощутимы при построении и поддержке сложных систем авторизации. Попробую объяснить еще раз. Представьте себе, сколько будет таких промежуточных ролей, которые по с точки зрения пользователя вашей реализации RBAC сути логической нагрузки не несут - ведь реально нет в системе ни одного пользователя, обладающего непосредственно ролью "базовый пользователь" (а фактически принадлежащего к группе "базовый пользователь", поскольку в RBAC роли верхнего уровня ассоциируются с обычными группами пользователей).
Приведу еще один пример, о котором я писал в английском аналоге темы. В руководстве Yii рассматривается пример, где создается роль (в терминологии фреймворка - операция) updateOwnPost. На самом деле, если бы была возможность назначать бизнес правила на иерархическую связь, но можно было бы не создавать эту роль, а просто написать бизнес правило на отношение к примеру "updatePost - user"
Ну зачем тогда создавать абстрактные классы или интерфейсы? Или давайте создавать мега-классы от который наследуются все другие, но эти все классы не пользуются(или даже "отрекаются") от методов и свойств родителя…
Представьте себе конечного пользователя интерфейса вашей системы, которому нужно думать о том, что нужно создавать какие-то абстрактные роли.
Ну и так и остается открытым вопрос об огромном количестве таких абстрактных ролей на каждое исключение в наследовании. И все это нужно поддерживать в актуальном состоянии. Как вы думаете, зачем в спецификации RBAC предусмотрена возможность правила разнознаковыми? Наверное, для большей гибкости.
Если продолжать вашу аналогию с механизмом наследования в ООП, то запрещение ролей нижнего уровня - это аналог перекрытия методов в классе-потомка. Хотя, на мой взгляд, параллель с ООП немного неуместна, поскольку функциональность наследования в RBAC призвана решать более простые задачи, для которых, опять же на мой взгляд, избежать использование абстрактных ролей можно достичь ассайном бизнес правила на отношение ролей, а не только на сами отдельно взятые роли
конечно можно. но ACL не RBAC. хотя, как мне кажется, реализация более продвинутого RBAC в Yii предоставляет меньше возможностей, чем реализация менее продвинутого ACL в ZF
Здесь прекрасно реализован RBAC, если вы не до конца понимаете, как его грамотно использовать, спрашивайте, вам помогут. Более того, местная реализация RBAC подходит для решения задач разграничения прав любого(!) уровня сложности, что не раз было проверено на практике.
На самом деле здесь есть эта возможность, к сожалению текущая документация не раскрывает этот вопрос. Если нужны примеры, приведу.
Замечательно! Вы “очень” верно мыслите А потом когда у 100 пользователей нужно ввести ещё и ограничение по времени на возможность обновления поста вы все ешё правите bizRule у 100 отношений(даже врагу нельзя желать такой ад), а мы за 1 минуту правим только updateOwnPost и начинаем пить кофе. Думаю закончите вы, как раз когда я буду заваривать 10-ую кружку. Опять же, вы не до конца понимаете концепцию “задач” и смысл такого разделения. Вкратце скажу, смысл есть и он немал. Один из доводов - не засорять контроллер “левым” кодом. Это помимо [b]массового/b введения новых ограничений для операции. При помощи местного RBAC можно решать заранее неизвестные задачи разграничения доступа не меняя ни строчки кода в контроллерах, но при условии грамотного использования инструмента.
Вы даже не представляете насколько ошибаетесь. Конечно документация пока портит весь шарм, но уверяю вас, вскоре этот недостаток будет восполнен.
Я не знаю какую вы спецификацию по RBAC читали. Но важно одно. Здесь нет только ролей. Здесь есть роли, задачи и операции. И невзирая на то, что это по факту все роли, смысл такого трактования носит очень большой характер.
Ключевое слово здесь - зачачи(tasks). Это не костыли, это концепция. Важная концепция. Я вам просто привел решение попроще. Объяснение концепции задач будет выглядеть несколько сложнее, но если нужно расскажу без проблем. Не стоило делать вывод, что тут только костыли, нужно было решить проблему - решили. Есть проблема глобальнее и астрактнее? Требуется дальнейшее trouble free масштабирование системы ролей? Не вопрос, приводите. Решим без костылей, при помощи "задач", с возможностью дальнейшего роста.
Вот как раз открыл исходники нескольких таких своих систем, основанных на местном RBAC. Никаких костылей, тишь, гладь и красота. Все логично и четко. Одним махом через админку воздвигаются горы, решаются судьбы, совершаются подвиги. Это образно говоря. Назвать список ролей верхнего уровня фиксированным язык не повернется, он постоянно расширяется.
Теперь повторю ещё раз, назначение операций ролям должно происходить независимо. Но это не значит, что 2 разные роли верхнего уровня не могут включать 1 и ту же операцию нижнего уровня. Концепция задач, исходя из вашей критики в адрес updateOwnPost вам не ясна и вы все ещё не в курсе что тут можно назначать бизнес правила на иерархическую связь. Опять же это не проблема. Приведите в этот пост задачу разграничения доступа любого уровня сложности. Уверен на 99,9%, что при помощи текущего RBAC она решиться красиво, четко и лаконично. Если не понимаете инструмент до конца, не стоит его критиковать, стоит интересоваться реальными возможностями и особенностями работы, много стереотипов может порушиться.
Вообще конечно ключевая фраза:
Тут - не находятся. Тут на нижнем уровне операции, на среднем - задачи. Забудьте все, чему вас учили неправильные RBAC спецификации, потом сами спасибо скажете.
Конечно нужны примеры. Приводите, с интересом посмотрю
Так причем здесь пользователи. Их может быть сколько угодно. Я правлю один раз бизнес правило на отношение updatePost - users. Или же, если реализация позволяет, создаю еще одно бизнес правило на это отношение
Как я понял, разделение на роли, задачи и операции условно. Может проясните, в чем заключается смысл такого трактования
Я в начале темы и привел. Не хочу делать абстрактные роли. Удобно иметь в распоряжении разнознаковые правила, при помощи которых можно гибко управлять наследованием, не создавая пустых ролей
Вот вы странный . Не, примеры не нужны конечно, зачем? Все сразу стало и так понятно. Написал же умный человек, что есть примеры у него и чудно, действительно, зачем еще беспокоить его и просить их привести - глупо конечно.
И так весь пост - пространные рассуждения о мифической мощи RBAC (мифической она начинает казаться после вашего поста) без малейшей конкретики в стиле “но я то знаю как” (но не скажу? ).
Цель вашего поста помочь ответить на поставленный вопрос, или "блеснуть"?
Если вы заметили, то в первом посте я привел конкретное решение конкретной задачи. Цель поста была - разрушить стереотипы человека о местном RBAC
Здесь можно назначить bizRule на отношение конкретный пользователь - роль(задача,операция). Бизнес правила но отношения между ролями - лишнее. Условное разделение на 3 типа ролей позволяет решать проблемы другим способом. Пример приведу ниже.
Эти дополнения лишь для удобного администрирования RBAC, ничего принципиального они не меняют.
to Darkside73
Что касается идеологически верного решения задачи в вашем первом посте:
В целом отделить операцию от роли другого уровня довольно просто. Операция отражает конкретный action контроллера. У вас есть следующие операции(operations в терминологии Yii):
создание (createO)
просмотр (viewO)
редактирование (updateO)
удаление (deleteO)
В дальнейшем суффиксом буду помечать тип роли, чтобы потом удобно было представить иерархию. O - операция, R- роль, T - задача.
Определить что такое роль тоже просто. Роль - это всегда контейнер для операций(operations) и задач(tasks). У вас есть следующие роли(roles в терминологии Yii):
администратор (administratorR)
редактор (editorR)
пользователь (authorizedR)
гость (guestR)
Причем 2 из них authorized и guest могут быть выделены в defaultRoles. Для этого на первую нужно назначить bizRule=‘return !Yii::app()->user->isGuest;’, на вторую bizRule=‘return Yii::app()->user->isGuest;’.
Задача(task в терминологии Yii) это самое сложное понятие. Рассматривайте её как своеобразный фильтр в отношении роль(role)-операция(operation). Исходя из вашей задумки у вас имеются следующий задачи:
редактирование собственной сущности(updateOwnT)
Задачи отличаются тем, что находятся на среднем уровне иерархии и у них всегда есть bizRule. В вашем случае bizRule такой: ‘return Yii::app()->user->id===$params[“model”]->userID;’
Иерархия объектов авторизации в Yii - это не просто дерево! Это дерево, которое может иметь множество ветвей и множество корней, поэтому представить его четким иерархическим списком не получится, поэтому списков будет несколько. Иерархия объектов авторизации для вашей задачи:
administratorR
– createO
– viewO
– updateO
– deleteO
editorR
– viewO
– updateO
authorizedR
– createO
– viewO
– updateOwnT (особенно пристально обратите внимание!)
guestR
– viewO
и теперь самое главное:
updateOwnT
– updateO
Как видите роль authorizedR связана с операцией updateO через задачу updateOwnT на которую наложен bizRule. Вот это и есть концепция задач-фильтров. Очень мощный механизм. Что касается проверок в контроллере, то в checkAccess на практике должна попадать операция с передачей параметров, приблизительно по этому паттерну
$params=array('model'=>$model); //обязательно массивом
if(!Yii::app()->user->checkAccess('updateO',$params))
throw new CHttpException(403);
Особое внимание обратите на то, что в checkAccess ставится именно операция и именно ей передаются параметры. Задачи никогда на уровне кода не появляются. Несмотря на то, что у этой операции нет bizRule, параметры передаются в любом случае. Причина следующая. Параметры передаются вверх по иерархии объектов авторизации! Таким образом $params у нас попадет в задачу updateOwnT и все прекрасно отработает.
Плюсы которые дает RBAC в Yii:
Код в контроллерах всегда чистый и лаконичный, редко выходящий за рамки приведенного мною паттерна. Если в действии вам пришлось сделать 2 checkAccess, то это в 99% случаев сигнал о том, что у вас неверно составлена иерархия объектов авторизации!
Любые задачи по ограничению доступа в будующем решаются без изменения(!) кода в контроллерах. Даже заранее неизвестные.
Если бы вы хотя бы посмотрели код и почитали описание, то поняли, что это расширение - не лишь для удобного администрирования
Насколько я понимаю, с таким же успехом можно было сделать эту задачу операцией. На этом же уровне иерархии, который вы назвали "средним", может находится все, что угодно. И бизнес правила может содержать все, что угодно. И таски без бизнес правил тоже имеют смысл.
Вы так и не показали в чем же сложность этого понятия и чем задачи отличаются от остальных ролей.
Такое "не просто дерево" называется графом
Т.е. вы мне предлагаете строить иерархию, каждый раз назначая операции для ролей, вместо того, чтобы наследовать роли от "ущербных к продвинутым". А когда будет 100 операций? Вы тоже будете настаивать на своем варианте иерархии?
Ничего для меня нового в этом нет. Все равно нужно создавать дополнительную роль (задачу)
Я колеблюсь… Это плюс или минус?
Крайне редко используемая возможность
Почему?
Другого способа я так и не увидел. А показали вы мне единственно возможные способы, хотя я о них и сам знал:
наследование каждой роли от сотни-другой операций вместо наследования одной роли от другой
создание дополнительных ролей (задач) вместо назначения бизнес правил на иерархическую связь
Так что тут еще нужно разобраться у кого из вас стереотипы. "Местный RBAC" не поддерживает в принципе allow/deny-знаковость утверждений. И если для проектируемой заранее разработчиком статичной системы ролей это просто минус, то для организации интерфейса для конечного пользователя по управлению правами доступа, где он может создавать новые роли - это огромнейший минус. Равно как и отсутствие возможности определения бизнесрула для отношения ролей.
Можно, но рулы на ассайн пользователей к группам не есть гуд, потому как их прийдется хранить для каждого пользователя, а управление логичней строить по большей части на правах групп (представьте себе что у нас 100 пользователей в 1 группе и 100 во 2-й: вы допустим всем вторым будете назначать рул, или просто назанчите его их группе?).
Да ну? См. пример выше…
Это плюсы простите по сравнению с чем? Это ж задачи любой нормальной системы организации прав доступа. Особенно пункт 2 порадовал . Ну как будущий пользователь системы сможет менять код контроллеров? У него ж только UI к управлению правами и все.
Ничего сверхсложного в ней нет. И минусов особых нет, кроме того, конечно, что она реализована не полностью в Yii.
Я говорил про srbac. Что касается hrbac, хм… ну если вам список фич показался чем то полезным, юзайте Несмотря на то, что он внушителен он повторяет на 95% все что есть в оригинале, кроме сомнительной возможности назначения бизнес-правила связи роль-роль. А ещё обязательно посмотрите список требований. Человек разрабатывающий даже второе расширение под этот фреймворк знает, что есть методы AR::getPrimaryKey(), а у компонентов есть public свойства, которые прекрасно конфигурируются. Но больше всего меня повеселила фраза:
If the table name is different, just open HrbacModule?.php and change it there.
Этого уже достаточно чтобы расширение не смотреть, не говоря уже о том, чтобы использовать для таких серьезных вещей, как решение задач разграничения доступа. Чудес не бывает, как и хороших расширений с такими серьезными проколами.
Это и в документации написано, я просто максимально подробно раскрыл суть.
Это ему по барабану, он воспользуется промежуточным звеном - задачами.
Вы будете учить администратора интерфейса рулить bizRule??? У меня администратор просто выберет нужную “задачу”, он не знал, не знает и знать не желает что такое bizRule
Ну, если вы сами занимаетесь администрированием своих систем, то да, это наверное великая проблема. В системах для конечных заказчиков при упоминании матного выражения bizRule я думаю вас не поймут и очень оскорбятся.
Бизнес правила на отношения между ролями не нужны просто потому, что это прекрасно решается через другие средства. Даже если они и будут, то какого плана ‘return true;’,‘return false’? Если хотите в дым запутать отношения объектов авторизации, то конечно стоит грезить о такой возможности.
Не единственно возможный, а просто удобный, простой и правильный с точки зрения многих позиций.
С этим согласен, просто рассказал, что такая возможность есть и использовать её можно например для временного исключения роли у пользователя.
Вот и я о том же.
Нет, предложу ещё использовать задачи для группировки ряда операций, не только как фильтр.
to Darkside73
Судя по вашему посту вы понимаете возможности RBAC в Yii. Если вас не устривает философия местного RBAC, то к чему вообще был первый пост? Предложите новую концепцию, напишите расширение с примерами использования. Покажите преимущества налицо, так сказать! Чего на возможности сетовать? Много юзеров фрейма вообще не понимает как RBAC использовать в принципе, а те кто понимает использует его и возможностей хватает с лихвой.
Вот мне интересно, раз уж вы говорили о заказчике, настраивающем систему и "не знающем что такое бизрулы" а просто применяющем роль, подумайте над простейшими ситуациями:
Заказчику через его UI нужно запретить какое-то действие пользователям определенной группы при заходе с ip из блэклиста или в определенное время. Вы его снабдите отдельной версией роли с встроенным бизрулом для каждой возможной роли которую он захочет ограничить таким образом? Или просто дадите возможность установить на любую роль дополнительное правило из заранее предоставленных ему бизрулов? И кто тут запутывает структуру? И чей заказчик оскорбится?
Вы все еще утверждаете что это не нужно? Это как раз будет самый частый варинт использования бизрулов.
Ну а про отсутствие allow/deny я вообще молчу… Без них построить мало-мальски сложный но в то же время понятный интерфейс управления правами вообще не представляется возможным.
Зачем отдельной версии, для всех операций которые нужно будет ограничить достаточно будет ОДНОЙ общей задачи-фильтра с bizRule. У такого bizRule будет специальный конструктор, который будет действовать в определенных рамках. Таким образом опять пользователь решит все очень быстро через UI. А я опять же продолжу вам утверждать что bizRule на связь роль-роль не нужен ни в каких случаях!
Из цитаты стало ясно что вы не видите другого выхода из ситуации, потому что говорите о многих доп. ролях к ролям чтобы ограничить. Посмотрите более плотно концепцию задач. Попробуйте на них посмотреть не как на роли, а как на фильтры, которые могут быть общими.
Не понимаю в чем проблема, вопрос решается также. Одна лишняя сущность в виде задачи - катастрофа?
Приведите пример как вы бы решили эту задачу не в рамках Yii, а вообще. И если это то что вы написали в первом посте, то у меня нет больше слов, остаются одни эмоции…