Несколько уровней авторизации, а не только на основе ролей
В нашем приложении используется несколько способов авторизации доступа к данному ресурсу. Хотя он работает, он грязный и... ну, это не кажется правильным.
1) Ролевая авторизация
У нас есть четко определенные роли, где каждая роль имеет доступ к набору ресурсов, а разные роли могут обращаться к тем же ресурсам.
Ресурсы на данный момент представляют собой просто действия MVC, отображаемые в таблице базы данных как module
, controller
и action
.
Кажется, все в порядке, но каждый раз, когда мне нужно добавить новый контроллер/действие, мне нужно сопоставить этот ресурс с таблицей базы данных.
2) Пользовательское разрешение
Помимо авторизации на основе ролей пользователи могут иметь более или менее доступ к подмножеству ресурсов другой роли. Например:.
RoleA: ресурсы a, b, c, d
RoleB: ресурсы x, y, z
RoleC: ресурсы 1, 2, 3
User1: имеет RoleA, но ему необходимо получить доступ к ресурсу y
User2: имеет RoleB и RoleC, но не имеет доступа к ресурсу z
Это реализовано как таблица user_resources
с записями для дополнительных ресурсов, которые пользователь имеет доступ или отклонен (обозначен флагом).
Я мог бы создавать разные роли с индивидуальным доступом, рассматривая роли как группу разрешений, но это могло бы привести к взрыву ролей.
3) Разрешение состояния модели
Если этого недостаточно, некоторые действия могут выполняться только тогда, когда модель находится в определенном состоянии (каждая модель знает, когда что-то можно сделать). Например: заказ может быть отредактирован только в том случае, если пользователь имеет доступ к ресурсу редактирования (через шаги №1 или №2), а объект Order
можно редактировать.
Пример Anoter: пользователь может получить доступ к Customer
, если у него есть доступ к ресурсу /customer/view
, и он владеет этим клиентом (он является контактной информацией для этого клиента).
4) Отображение информации в пользовательском интерфейсе
Роль, группа ролей или отдельные пользователи могут видеть более или менее информацию о модели, в зависимости от ее состояния.
Как я могу упростить этот процесс авторизации без потери гибкости в предоставлении или ограничении доступа к ресурсам?
Есть ли какой-либо шаблон, который мне не хватает, чтобы объединить все это авторизацию в одном месте?
Ответы
Ответ 1
После долгого времени я наконец нашел ответ, который удовлетворяет всем моим требованиям:
http://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/.
Его решение состоит в том, чтобы рассматривать все как действие, разрешение на выполнение/вызов/независимо от того, какая роль принадлежит роли, и пользователи могут иметь несколько ролей.
То, что сияет в этом подходе, заключается в том, что проверка разрешений выполняется только для самой активности, а не для ролей.
Ответ 2
Я реализовал контроль доступа с помощью шаблона , который я нахожу непосредственно подходящим для этого. Центральный метод isSatisfiedBy
. X разрешено делать y, если оно выполняется z. Например, пользователю разрешено просматривать "страницу администратора", если он удовлетворен "имеет роль администратора". Посмотрите, как isSatisfiedBy
может быть очень общим (например, "пользователь с id 324", "был зарегистрирован в течение 30 минут", "является членом группы foo",...). Затем правила становятся следующей общей формы:
allow X to do Y if X satisfies Z