Иерархический доступ на основе ролей/разрешений

Я хочу создать управление доступом к иерархической ролевой базе. Это моя текущая схема:
введите здесь описание изображения

В настоящее время у меня есть два варианта построения этой системы:

  1. Прикрепите все необходимые разрешения к роли (не иерархической) введите здесь описание изображения

  2. Прикрепляйте только специальные разрешения «уровня» и наследуйте разрешения более низкого уровня введите здесь описание изображения

Есть ли лучший подход или это просто зависит от потребностей моего проекта?

Я склонен выбрать Иерархический только из-за простоты. Если я это сделаю, есть ли лучший способ выбора уровней разрешений, возможно, с использованием двоичных чисел?

Вариант 2 будет иметь несколько уровней для ролей, а у меня будет несколько номеров уровней для разрешений. Поэтому, когда я создаю Full Administrator, роль унаследует все остальные разрешения, поскольку это будет уровень 4, а другие разрешения будут иметь номер меньше уровня 4 (или 4000).

Это перебор?


person Cristian    schedule 26.08.2015    source источник
comment
Не превращайте это в иерархию. Это доставляет больше хлопот, чем того стоит. Вместо этого просто создайте N разных «ролей» (каждая из ролей будет представлять содержащиеся в ней разрешения в виде отдельных свойств) и назначьте роль (или более) каждому из пользователей. В случае нескольких ролей просто выравнивайте разрешения как фиксированную стадию.   -  person user2864740    schedule 26.08.2015
comment
Я не понимаю, почему наследование должно быть проблемой. Кажется, чтобы сохранить много кодирования и доступа к сущностям.   -  person al'ein    schedule 26.08.2015
comment
Потому что это 1) намного сложнее 2) добавляет очень мало (если вообще есть) ценности в этом случае. Но что бы там ни было, делай то, что собираешься делать.   -  person user2864740    schedule 26.08.2015
comment
При подходе ООП класс user расширяет дочерние элементы своего профиля. Где сложность?   -  person al'ein    schedule 26.08.2015
comment
@AedixRhinedale Стандартный SQL не является «OO», и даже гораздо более сложные фреймворки, такие как EF (который является одним из лучших для этого обезьяньего бизнеса), выполняют довольно некачественную работу с импедансом. Существует также разница между иерархией дерева ОО (фиксированный набор, например классы) и иерархией данных (например, узлы дерева).   -  person user2864740    schedule 26.08.2015
comment
Ну, ты меня понял. Я не видел, чтобы ОП говорил что-то об этом только внутри базы данных. Я пришел сюда из-за тега PHP.   -  person al'ein    schedule 26.08.2015
comment
Но, я сказал свою часть. Хорошо проведите время, написав систему и изучив ее. (Я поддерживаю вариант 1, который не является иерархией.)   -  person user2864740    schedule 26.08.2015
comment
Вариант 1, безусловно, намного более гибкий/пригодный для повторного использования.   -  person rjdown    schedule 26.08.2015
comment
@user2864740 user2864740 Итак, вы говорите так: для платного пользователя я должен назначить им две роли: базовый пользователь и платный пользователь. Затем, по очереди, разрешения для основного пользователя (редактирование профиля, поиск сообщения) и платного пользователя (создание сообщения, редактирование сообщения, обновление сообщения). И эта комбинация дает платному пользователю все необходимые разрешения, верно?   -  person Cristian    schedule 26.08.2015
comment
Нисколько. Ты мог; но нет необходимости. Я говорю, что даже с № 1 (который является неиерархической основой) нет причин, по которым у пользователя может быть только одна роль, и если эта учетная запись для нее делает систему достаточно гибкой и все еще простой. Однако агрегация разрешений обрабатывается по ролям, а не по иерархиям.   -  person user2864740    schedule 26.08.2015
comment
@user2864740 user2864740 Мне действительно не хватает твоей точки зрения. Почему бы вам не построить ответ на это? Кажется интересным.   -  person al'ein    schedule 26.08.2015
comment
@user2864740 user2864740 Я до сих пор не понимаю вашего подхода. Не могли бы вы привести пример?   -  person Cristian    schedule 26.08.2015


Ответы (1)


Я рекомендую использовать вариант "Подхода №1" - неиерархические роли.

Я работал с подобными системами с большим успехом. Хотя на первый взгляд этот подход может показаться «менее структурированным», он относительно прост и очень гибок; когда разрешено несколько ролей для каждого пользователя и определены правила для агрегирования разрешений.

Против иерархий (для ролей)

Подобно «ОО-иерархии», использование иерархии ролей приводит к строгим отношениям замещения. Это усложняет определение ролей на основе меняющихся требований.

Например, возможно, в будущем потребуется учетная запись «Администратор», которая не может создавать свои собственные сообщения. Иерархия (и отношение замещения) предотвращает это без изменения самой древовидной структуры, потому что «Полный администратор» — это «Платный пользователь».

Запросы к истинной иерархии в SQL более сложны; особенно в реализациях, не поддерживающих рекурсивные запросы, таких как MySQL. Переключение на иерархию с использованием вложенного набора или материализованного подхода приводит к дополнительной структуре, а не только к отношению родитель-потомок.

Вам это просто не нужно; чем сложнее программное обеспечение, тем сложнее его писать и поддерживать. Хотя иерархии очень хороши в некоторых случаях — например, в спецификации материалов, генеалогии или структуре каталогов — в большинстве моделей ролей/групп-разрешений просто нет «необходимости».

Для (несколько) ролей

Роли без зависимости от «родительского типа» функционируют скорее как «объектно-ориентированные интерфейсы» — ну, может быть, Trait композиция была бы более подходящей, если бы аналогии были растянуты. Реализация (читай: предоставленные разрешения) каждой роли может изменяться независимо от любой другой роли, что делает ее чрезвычайно гибкой. Как и в случае с интерфейсами, одному пользователю/сущности может быть назначено более одной роли.

Запросы к плоской модели User <M-M> Role <M-M> Permission намного проще в SQL (с рекурсивной поддержкой или без нее или с дополнительной структурой), потому что просто нет иерархии ролей для обхода.

Группы ACL Windows (давайте проигнорируем вложенные группы) работают так же, как Роли; Пользователь принадлежит к одной или нескольким группам, которые предоставляют (или отклоняют, но это другая ситуация) разрешения.

Возьми свой торт и съешь его тоже

Вариант, который я рекомендую и о котором упоминалось выше, заключается в разрешении агрегирования разрешений между ролями. Простая модель агрегации такова:

  • Пользователь имеет объединение разрешений от всех назначенных ему ролей.

    (Действующие разрешения, как правило, создаются во время авторизации, но без иерархии также относительно просто выполнять запросы в SQL.)

Таким образом, разрешения привязаны к каждой роли с небольшим перекрытием или без него, как показано в «Подходе № 2», с той разницей: Иерархия отсутствует.

Например, чтобы разрешить специальному администратору выполнять поиск сообщений (и удалять «плохие» сообщения), можно просто назначить «Обычный пользователь» и «Ограниченный администратор». " Роли1.

Использование неиерархической многоролевой системы позволяет это сделать чисто, сбрасывая с себя бремя иерархии, и в то же время предоставляя гибкие/составляемые/настраиваемые архетипы ролей.


1 Это не очень хороший пример. На самом деле роли должны иметь разные имена (например, «Поддержка учетной записи» или «Модератор контента») и охватывать разные наборы разрешений; они, вероятно, со временем изменятся на основе проб и ошибок и бизнес-правил «вкус месяца».

Хотя я выступал против такой иерархии, в более сложных системах может возникнуть необходимость разрешить отношения между ролями, в первую очередь для их группировки. Как правило, эти отношения должны быть независимыми от действующих Разрешений, существующих для других управленческих целей.

person user2864740    schedule 26.08.2015
comment
Спасибо за ваше понимание. Действительно имеет смысл не использовать иерархическую структуру. Небольшое перекрытие или его отсутствие в сочетании с объединением действительно хорошо сочетаются с моим текущим проектом. В вашем примере специального администратора после назначения двух ролей основного пользователя и ограниченных ролей администратора специальный администратор не будет иметь разрешений платного пользователя. Это имеет смысл. И да, в определенных ситуациях иерархические роли будут работать, но это означает, что разрешения и роли не будут (может быть, немного) меняться со временем. Это не мой случай. Может иметь много изменений. - person Cristian; 27.08.2015