Система управления доступом PHP
Я являюсь частью команды, создающей веб-приложение с использованием PHP и MySQL. Приложение будет иметь несколько пользователей с разными ролями. Приложение также будет использоваться географически распределенным образом. Поэтому мы должны создать систему контроля доступа, которая работает на двух уровнях:
- управляет разрешениями пользователя для определенных страниц php, т. е. предоставляет или запрещает доступ к определенным страницам (или элементам пользовательского интерфейса) на основе роли пользователя. Для пример: пользователю может быть разрешен доступ к странице "студенты", но не к странице" учителя".
- управляет разрешениями пользователя для определенных записей базы данных, т. е. изменяет запросы базы данных, чтобы отображались только определенные записи. Например, для пользователя на уровне города должны отображаться только те записи, которые относятся к конкретному городу пользователя, в то время как для пользователя на национальном уровне должны отображаться записи для всех городов страны.
Мне нужен помощь в разработке системы, которая может обрабатывать оба этих типа контроля доступа. Пункт нет. 1 кажется достаточно простым. Тем не менее, я совершенно не понимаю, как сделать пункт 2 без жесткого кодирования информации в SQL-запросах.
любая помощь будет оценили.
спасибо заранее
Виньяк
5 ответов
Я был в подобной ситуации несколько месяцев назад. Я обнаружил, что такие инструменты, как Zend_ACL, отлично работают, если вы просто проверяете уровень доступа к одному элементу (или достаточно низкое их количество). Он терпит неудачу, когда вам нужно получить огромный список элементов, к которым пользователь имеет доступ. Я создал пользовательское решение этой проблемы, используя Бизнес-Делегат узор. BD предоставляет бизнес-логику, которая может применяться в определенном контексте. В этом сценарии логика SQL была доставлена и использована в качестве условия фильтрации в подзапрос выборки. См. следующие диаграммы:
alt текст http://gruz.epsi.pl/g/uml/permissions.png
и диаграмма последовательности, иллюстрирующая порядок вызовов:
alt текст http://gruz.epsi.pl/g/uml/permissions-s2.png
я написал в блоге об этом решении, к сожалению, все это на польском языке, но вы можете найти куски кода и диаграммы удобно. Что я могу сказать, реализация-это не кусок пирога, но производительность - это чемпион по сравнению с итеративной проверкой доступа для каждого элемента в списке. Кроме того, инфраструктура выше обрабатывает не только один тип элементов в списке. Он может служить при доступе к различным спискам, будь то список городов, стран, продуктов или документов, пока элементы в списке реализуют IAuthorizable
интерфейс.
Мне кажется, что вам нужно следующее: (Я буду использовать пример страны/штата/города)
- список всех стран. Каждая" страна " имеет ID.
- список всех государств в странах. Каждое государство связано с ID coutnry, но также имеет свой собственный уникальный ID.
- список всех городов. Каждый город связан либо с государством, либо непосредственно со страной и имеет флаг, чтобы указать, который.
для пользователя города, очевидно, поиск Для и отображать только те записи, относящиеся к городу, который соответствует их ID. Для штата или национального уровня, однако, поиск всех записей, относящихся к каждому городу, который имеет идентификатор, соответствующий этой нации (или штата или что у вас есть).
таким образом, в основном, каждая подгруппа зависит от группы над ней, и хотя я не помню правильно, я считаю, что вы можете использовать подзапросы, чтобы сделать трюк оттуда.
Если вы не знаете, как это сделать, я бы использовал PHP-фреймворк, такой как Zend Framework, CakePHP или Symphony. Они сделали тяжелый подъем для вас и имеют некоторый тип схемы контроля доступа уже на месте.
У меня есть аналогичное решение для сборки, и до сих пор я решил использовать спецификации и роли, поэтому на самом деле одна роль будет иметь некоторые спецификации привилегий. Если они все удовлетворены, разрешение предоставляется, в противном случае-оно возвращается к доступу по умолчанию к ресурсу.
Я искал, чтобы найти кого-то, кто уже реализует решение, но, похоже, никто этого не сделал. Будем надеяться, что это не будет неудачей:)