7

Я являюсь частью команды, создающей веб-приложение с использованием PHP и MySQL. Приложение будет иметь несколько пользователей с разными ролями. Приложение также будет использоваться в географически распределенной форме. Соответственно, мы должны создать систему контроля доступа, которая работает на двух уровнях:PHP Access Control System

  1. разрешения пользовательских элементов управления для конкретных страниц PHP, т.е. предоставляет или запрещает доступ к определенным страницам (или элементов пользовательского интерфейса) на основе роли пользователя. Например: пользователю разрешен доступ к странице «Студенты», но не к странице «Учителя».
  2. Управляет разрешениями пользователей для определенных записей базы данных, то есть изменяет запросы к базе данных, чтобы отображать только определенные записи. Например, для пользователя на уровне города должны отображаться только те записи, которые относятся к конкретному городу пользователя, в то время как для пользователя на национальном уровне должны отображаться записи для ВСЕХ городов в стране.

Мне нужна помощь в разработке системы, которая может обрабатывать оба этих типа контроля доступа. Пункт №. 1 кажется достаточно простым. Тем не менее, я совершенно не понимаю, как сделать точку №2 без жесткого кодирования информации в SQL-запросах.

Любая помощь будет оценена по достоинству.

Заранее спасибо

Винаяк

ответ

12

Я был в похожей ситуации несколько месяцев назад. Я обнаружил, что такие инструменты, как Zend_ACL, отлично работают, если вы просто проверяете уровень доступа к одному элементу (или достаточно малому числу). Он терпит неудачу, когда вам нужно получить огромный список элементов, доступ к которым пользователь может получить. Я создал собственное решение этой проблемы, используя шаблон Business Delegate. BD предоставляет бизнес-логику, которая может применяться в определенном контексте.В этом случае логика SQL была доставлена ​​и использована в качестве условия фильтрации в подзапросе. Смотрите следующие диаграммы:

alt text http://gruz.epsi.pl/g/uml/permissions.png

И схема последовательности операций, которая иллюстрирует вызовы заказа:

alt text http://gruz.epsi.pl/g/uml/permissions-s2.png

I blogged about this solution, к сожалению, это все на польском языке, но вы можете найти куски кода и диаграмм удобным. Я могу сказать, что реализация - это не кусок торта, но по производительности это чемпион по сравнению с итеративной проверкой доступа для каждого элемента в списке. Кроме того, инфраструктура выше обрабатывает не только один тип элементов в списке. Он может использоваться при доступе к различным спискам, будь то список городов, стран, продуктов или документов, если элементы в списке реализуют интерфейс IAuthorizable.

1

Не знает о деталях вашей проблемы, но Zend Framework имеет довольно мощный ACL и AUTH набор компонентов, которые вы можете посмотреть на. Хорошие вещи, такие как очень точный контроль доступа, хранение данных для устойчивости, расширенные условные правила.

1

Мне кажется, нравится то, что вам нужно это: (я буду использовать страну/штат/город пример)

  1. список всех стран. Каждая «страна» имеет удостоверение личности.
  2. Список всех государств внутри стран. Каждое состояние привязано к идентификатору coutnry, но также имеет свой собственный уникальный идентификатор.
  3. Список всех городов. Каждый город обязан либо государству, либо непосредственно стране, и имеет флаг, указывающий, какой из них.

Для городского пользователя, очевидно, поиск и отображение только тех записей, которые относятся к городу, который соответствует их ID. Однако на государственном или национальном уровне выполните поиск всех записей, относящихся к каждому городу, у которого есть идентификатор, соответствующий этой нации (или государству или тому, что у вас есть).

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

+0

Hi Но это означает, что поисковые запросы должны быть по-разному записаны для каждого уровня пользователя. Моя проблема заключается в том, чтобы найти способ сделать один и тот же запрос возвратом другого набора результатов на основе уровня пользователя. – Vinayak 2008-10-23 13:58:53

+0

@ vinayak.myopenid.com. В любом случае вам придется использовать другой запрос, если бы вы знали, какой уровень доступа у вас есть на сервере SQL. Кажется, что разрешения будут обрабатываться путем привязки выражений в предложении WHERE с AND. Звучит довольно просто. – strager 2008-11-28 05:14:46

0

Если вы не знаете, как это сделать, я бы использовал инфраструктуру php, такую ​​как Zend Framework, CakePHP или Symphony. Они сделали тяжелую работу для вас и уже имеют некоторую систему контроля доступа.

0

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

Я искал, чтобы найти кого-то уже реализующего решение, но, похоже, никто этого не делал. Будем надеяться, что это не будет ошибкой :)