PHP сложные списки контроля доступа на основе ролей

Я уже сделал базу данных и код php, необходимые для реализации этой настраиваемой системы ACL. Теперь я должен "Авторизовать" текущего пользователя, и вот где мне нужны ваши советы.

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

Чтобы изобразить это лучше:

Предопределенные группы:

  1. Ограниченный (нет доступа)
  2. Обычный пользователь
  3. Продвинутый пользователь
  4. администратор
  5. Посетители (образец настроенной группы)

Вот уровни доступа (пары имя / значение):

  • 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.
}

Есть смысл?

Другие вопросы по тегам