PHP сложные списки контроля доступа на основе ролей
Я уже сделал базу данных и код php, необходимые для реализации этой настраиваемой системы ACL. Теперь я должен "Авторизовать" текущего пользователя, и вот где мне нужны ваши советы.
Система основана на гибком назначении разрешений как пользователям системы, так и системным модулям. Он также имеет несколько предопределенных, скажем, групп пользователей, с возможностью создания полностью настроенных групп. Глобальное правило также может применяться поверх ACL, но оно имеет самый низкий приоритет над группами или назначенными пользователями разрешениями.
Чтобы изобразить это лучше:
Предопределенные группы:
- Ограниченный (нет доступа)
- Обычный пользователь
- Продвинутый пользователь
- администратор
- Посетители (образец настроенной группы)
Вот уровни доступа (пары имя / значение):
- disallow / 0
- разрешить / 1
- отказать / 2
- разрешить, если владелец / 3
Примечание: "Разрешить" имеет более высокий приоритет по отношению к "Запретить", поэтому если у вас есть пользователь X "Запрещен" в группе А, но "Разрешен" в группе В при определенном доступе, то он, наконец, "Разрешил". С другой стороны, если пользователь X имеет "Полный доступ", будучи членом группы "Администратор", но если ему просто "Отказано" в определенном доступе, он не имеет доступа в конце, что означает "Запретить". имеет более высокий приоритет на "Разрешить".
На верхнем уровне у вас может быть что-то вроде этого:
- "Администратор" * "1", что означает, что администраторы имеют полный доступ к системе
- "Посетители" * "0", что означает, что посетители не допускаются ни к чему
У меня вопрос, как обрабатывать такие проверки? Представьте, что у нас есть простой механизм авторизации. У нас были бы некоторые индексы в нашем $_SESSION['user']
лайк $_SESSION['user']['login'] = true;
а также $_SESSION['user']['id'] = $row['user_id']
, право?
Теперь, если вы хотите реализовать этот механизм в своем скрипте, как вы собираетесь это сделать?
Я мог бы сначала проверить глобальные правила доступа. Тогда я бы посмотрел, вошел ли пользователь уже в систему или нет. Если да, просто получите все его группы, а затем просмотрите таблицу разрешений, чтобы увидеть, какие разрешения назначены его группам и его идентификатору пользователя, а затем сохраните их в сеансе пользователя. Затем, когда модуль говорит, что это мои необходимые разрешения для запуска, я бы посмотрел, есть ли у пользователя достаточный доступ к запрошенному модулю или нет.
Выглядит довольно сложно! Любая помощь или совет высоко ценятся!:)
Редактировать:
Я не использую какие-либо рамки. На самом деле я использую, но это мое. Таким образом, здесь нет готовых ACL!
Обновить:
Есть ли у вас идеи об эффективном способе расставить приоритеты (перезаписать / заменить?) Списки ACL?
Deny
самый высокий, то Allow
а потом Disallow
, Также User
назначенные ACL самые высокие, тогда Group
ACL и, наконец, Global
Списки управления доступом.
Вот что я наконец-то придумал:
Есть Array
, как это:
$_SESSION['ACL'][$module][$action] = $access_level; // 0, 1, 2, 3
Во-первых, я бы искал все Глобальные правила *
и поместит их в массив:
// The current user can see the map, applied by a global rule
$_SESSION['ACL']['map']['render'] = 1;
// All the other permissions are disallowed by default
$_SESSION['ACL']['*']['*'] = 0;
// He can edit his preferences, (Owner)
$_SESSION['ACL']['user']['*'] = 3;
Затем я буду искать ACL на основе групп:
// User could access the Analyze module, all the methods
// with Permission Name "report". Applied by being a member
// of "Moderator" Group
$_SESSION['ACL']['analyze']['report'] = 1;
// User NOT allowed to access "groups" module, let say
// it reserved for "admin" group! - To see the ACLs' Overwriting!
$_SESSION['ACL']['groups']['*'] = 0;
В конце концов, я бы искал назначенные пользователем списки ACL:
// User have Full Access to the "groups" module.
// It's gonna replace the last ACL, applied by "Moderator" group
// Note that the order of processing ACLs is IMPORTANT!
$_SESSION['ACL']['groups']['*'] = 1;
Я думаю, это будет работать отлично, есть идеи?
Это работает довольно хорошо сейчас:)
2 ответа
Вот способ, которым я обрабатываю это в среде MVC, создаю таблицу с такой структурой:
(id, group_id(int), user_id(int), controller(varchar), action(varchar))
Затем я использую -1 для группы и user_id для представления подстановочного знака, а * для контроллера и действия. Таким образом, в вашем примере администратор может сделать что-нибудь (1,4, -1,,). Или, скажем, опытные пользователи могут изменять пользователей (2,3,-1, пользователь,*). Или, если вы хотите дать одному человеку (user_id из 34) разрешение независимо от того, в какую группу он входит (3,-1,34, пользователь, обновление). Если вы хотите сохранить 0-3 для разрешения, запретите, просто добавьте столбец. Затем вы просто проверяете, какой контроллер и какое действие вызываются, и находите любые разрешения, которые относятся к группе (группам) человека и конкретно к ним.
Просто создайте свою таблицу разрешений / групп:
id, group/permission name
Затем создайте множество групп связывания таблиц для пользователей:
id, user_id, group_id
Вам не нужны уровни доступа, если вы просто используете групповые разрешения.
Затем, в своем коде, просто проверьте пользователя для группы, как это:
function checkAccess($pageLevelRequired)
{
// run query based on current user session id
// run your query to check if the current user belongs to the group required to view this page.
}
Есть смысл?