Моделирование ACL - как управлять иерархией списка контроля доступа?

Я все еще работаю над своим проектом ACL, и мне нужны некоторые идеи для следующей проблемы:

Я использую MySQL для хранения своих пользователей, ролей и разрешений. Сначала я создал поле «parent_id» в своих ролях TABLE и пытался через него управлять разрешениями каждого пользователя. Это вроде как работало, пока я не понял, что если я добавлю новую роль, будет очень сложно управлять иерархией и контролировать, кто имеет доступ к какому ресурсу. Я провел несколько поисков и понял, что использовать реляционную базу данных для работы с иерархией очень сложно, поэтому я отказался от иерархии.

Мне нужна ваша помощь, чтобы найти лучшее решение для управления созданием пользователей: у меня есть 4 разных пользователя: SuperAdmin, CustomerAdmin, Technician, client. Когда я нахожусь на странице создания новых пользователей, я не хочу, чтобы технический специалист создавал нового пользователя типа CustomerAdmin или SuperAdmin, например.

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

Пытаясь быть более назидательным, суперадмином могу быть я. Администратор клиента — мой клиент, и у него есть предприятие. На своем предприятии он может создать 2 типа пользователей: техников и клиентов.

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

Я не уверен, был ли я объективен в своем вопросе, но любой, кто может поговорить об этом со мной, буду рад.


person sergioviniciuss    schedule 28.06.2012    source источник
comment
Действительно сложно моделировать деревья в реляционной базе данных, основываясь на природе того, чем она является, просто она не очень хорошо подходит для моделирования этой структуры данных для извлечения в одном запросе. Я делал это раньше в PostgreSQL с так называемым материализованным путем, но в моей реализации использовались некоторые функции, которых нет в MySQL. Я использовал так называемый материализованный путь и реализовал его с помощью доступных для записи представлений + ltree. Лучший способ сделать это с MySQL, возможно, состоит в том, чтобы извлечь ваши данные и построить дерево путем обхода данных, хотя построение древовидной структуры данных в PHP заставляет меня содрогнуться.   -  person hsanders    schedule 28.06.2012
comment
Я понял твою идею.. но я действительно должен найти способ решить это самым простым способом.. Это не должен был быть этот монстр   -  person sergioviniciuss    schedule 28.06.2012


Ответы (2)


У вас уже есть свои роли, но каждая роль должна иметь права на выполнение действий. Это почти наверняка излишество, но оно должно быть очень гибким.

 | Role Table                           | 
 | Role ID | Role Name   | Access Level |
 ----------------------------------------
 |       1 | SuperAdmin  |           10 |
 |       2 | ClientAdmin |           20 |
 |       3 | Technician  |           40 |
 |       4 | Client      |           80 |

 | Action Table            |
 | Action ID | Action Name |
 ---------------------------
 |         1 | Create User |
 |         2 | Delete User |
 Etc.

 | Rights Table                   |
 | Right ID | Role ID | Action ID |
 ----------------------------------
 |        1 |       1 |         1 |
 |        2 |       1 |         2 |
 |        3 |       2 |         1 |
 |        4 |       2 |         2 |
 Etc.

 | Parameter Table                                         |
 | Param ID | Right ID | Parameter Name  | Parameter Value |
 -----------------------------------------------------------
 |        1 |        1 | Max User Access |              10 |
 |        2 |        2 | Max User Access |              10 |
 |        3 |        3 | Max User Access |              20 |
 |        4 |        4 | Max User Access |              20 |
 Etc.

Таблица прав показывает, что и SuperAdmin, и ClientAdmin могут создавать и удалять пользователей. Таблица параметров ограничивает ClientAdmin созданием пользователей с максимальным уровнем доступа 20 (1 — самый высокий). Вы можете сопоставить этот уровень доступа с ролью, чтобы предложить список ролей для нового пользователя, где Role.Access_Level >= Max User Access.

Действия могут использовать более одного набора параметров в соответствии с правом, но я не мог придумать ничего, кроме максимального доступа пользователей.

person SpacedMonkey    schedule 28.06.2012

Что, если вы использовали схему типа значения разрешения, где число представляет «уровень» разрешения, и с определенным приращением вы получаете определенные разрешения?

E.G.

Суперадминистратор 10000 Администратор клиента 1000 Техник 100 Работник 10

Может читать = 10 Может записывать настройки = 100 Может создавать пользователей 1000

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

person hsanders    schedule 28.06.2012
comment
это может быть интересная идея (отличная, я бы сказал, от всего, о чем я думал), но проблема в том, что я использую Zend_Acl (без плагина, потому что я должен использовать персонализированную среду MVC), и моя функция для проверяем, разрешен пользователь или нет, получает идентификатор роли, ресурс и разрешение), и это проверяется в базе данных, если в моей таблице ACL_Role есть реестр: role_id = 5, Resource_id = 2, разрешение = чтение, я проверяю: проверяю (5,2, читать). Если все в порядке, возвращает 1, иначе 0. И я думаю, следуя вашей идее, я не смогу продолжить свой ACL. ( Я могу быть не прав). - person sergioviniciuss; 28.06.2012
comment
Вам, вероятно, придется настроить существующее решение ACL, чтобы использовать что-то в этом роде. Я думаю, что для этого вам нужно настроить его, несмотря ни на что. Вы можете определить уровни ролей для каждой существующей роли, а затем просто выполнить числовое сравнение, а не использовать его для определения всей системы, и это потребует меньшего количества изменений того, что вы используете. - person hsanders; 28.06.2012