Как сделать систему разрешений, как показано ниже, с Symfony 2?

Общее описание

Система должна обрабатывать множество элементов, организованных во вложенные категории (см. наглядный пример ниже), предоставляя клиентам возможность определять правила разрешений (см. правила разрешений ниже). Он также должен обрабатывать различные общие разрешения, которые не зависят от каких-либо элементов (например, «можно просматривать определенную страницу?» или «можно приглашать новых участников?»).

Все пользователи объединены в группы. У каждого пользователя есть основная группа, к которой он принадлежит, но у него также могут быть дополнительные второстепенные группы.

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

При принятии решения о том, разрешено ли пользователю что-то делать, наследование разрешений выглядит следующим образом:

  • Начните с разрешений основной группы
  • Разрешить все разрешения, разрешенные любой из дополнительных групп пользователя
  • Если они определены, проверьте определенные разрешения пользователя (чтобы разрешить или запретить, независимо от вышеперечисленного). Пользовательские разрешения не должны быть определены, если они не определены, пользователь просто наследует разрешение от разрешений группы.

При определении разрешения группы клиент может использовать наследование, чтобы сказать что-то вроде:

  • Пользователям разрешено...
  • Редакторы имеют все права пользователей + ...
  • Модераторы имеют все права редакторов + ... - ...
  • Администраторы имеют все права редакторов + модераторов.

ПРИМЕЧАНИЕ. Я должен иметь возможность запрашивать последние 10 элементов из базы данных, которые текущий пользователь может редактировать/просматривать, разрешение для каждого элемента должно определяться базой данных, я не хочу фильтровать элементы для разрешения на уровне приложения, если бы я мог решить это на основе информации, хранящейся в базе данных.

Правила разрешений

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

Правила также могут зависеть от любого свойства текущего пользователя (например, дата регистрации, приглашение участников), запрошенного действия (например, просмотр, список, переименование, отмена удаления и т. д.) и другой информации, уже доступной во время выполнения (например, параметры URL-адреса). , лимиты квот, содержимое элемента, загрузка сервера), эта информация доступна для php-скрипта.

См. примеры правил ниже.

Наглядный пример схемы базы данных:

Category 1
   Nested Category A
      item x
   Nested Category B
      Deeply Nested Category
         item w
      item y
Category 2
   item z

В настоящее время схема базы данных выглядит следующим образом, но я могу изменить ее, если это необходимо: (конечно, это только часть схемы, есть и другие таблицы и поля)

элементы:

id | title  | owner_id | category_id
====================================
1  | item x | 2        | 3
2  | item y | 1        | 4
3  | item z | 3        | 2
4  | item w | 1        | 5

категории:

id | parents | title
=====================================
1  | null    | Category 1
2  | null    | Category 2
3  | 1       | Nested Category A
4  | 1       | Nested Category B
5  | 1/4     | Deeply Nested Category

пользователи:

id | name | group | all_groups | is_super_admin
===============================================
1  | Tony | 5     | 5          | 1
2  | John | 5     | 5,8,6      | 0
3  | Mike | 4     | 4,7        | 0
4  | Ryan | 6     | 6          | 0

Примеры правил

Следующие правила являются лишь примерами реальных случаев, которые следует реализовать.

  • Пользователи могут редактировать свои собственные элементы в течение 5 минут после отправки ()
  • Пользователь «Джон» может редактировать все элементы в «Категории 1» и во всех вложенных категориях.
  • Редакторы могут редактировать все элементы, кроме тех, владелец которых помечен как суперадминистратор.

Обратите внимание, что эти правила могут быть определены на уровне базы данных, как и большинство правил в моем случае.

Реализация

Я искал документы symfony, stackoverflow и т.д. Есть много интересных статей и вопросов на тему безопасности и ACL, но я не смог найти лучший способ справиться с такой системой.

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

Вопрос

Я спрашиваю, как реализовать такую ​​систему, пожалуйста, не отвечайте ссылками на документацию symfony или другие ресурсы с общей идеей и типичными простыми случаями. Пожалуйста, прочитайте и поймите мой случай, прежде чем отвечать.


person Xuni    schedule 24.04.2012    source источник
comment
Вы нашли подходящий дизайн для вашей системы? Если да, то можете выложить сюда? Подхожу к реализации чего-то подобного. Спасибо!   -  person mokagio    schedule 08.08.2012
comment
Извините, но после нескольких дней поиска решения, работающего с symfony, я сдался...   -  person Xuni    schedule 10.09.2012
comment
Да, я тоже... Мы реализовали простую пользовательскую систему, вдохновленную Symfony ACL и использующую некоторые из их базовых компонентов. Я лично был очень разочарован.   -  person mokagio    schedule 11.09.2012
comment
Вы, ребята, рассматривали возможность использования ролей для каждого из ваших разрешений? Вы можете назначать роли пользователям и группам, и вы можете довольно легко редактировать роли внутри формы. Тогда просто используйте избиратель   -  person JamesHalsall    schedule 14.02.2014
comment
Главный решающий фактор в реализации разрешений определяется тем, где выполняются фактические проверки авторизации. По умолчанию Symfony использует авторизацию на основе маршрута для пользовательских ролей, но вы можете использовать ее и дальше. Недавно я работал над сложной системой ACL (отсюда и мой запоздалый комментарий), основанной на доступе к данным (мы обрабатываем PII для детей). Ручные проверки в контроллерах были недостаточно хороши (ручные проверки при отказе-открытии, нам нужно было при отказе-закрытии), поэтому я встроил автоматические проверки на уровне сущности Doctrine (используя защищенный антецедент, на котором основаны все сущности).   -  person Kal Zekdor    schedule 27.05.2014


Ответы (1)


Я понимаю, что этот вопрос устарел, но ответ применим для Symfony 2.3+, поэтому я публикую его здесь.

Для этого подхода вы должны использовать такие вещи, как SecurityVoters.

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

Избиратели работают как

$this->get('security.authorization_checker')->isGranted('update',$post);

который будет проверять всех избирателей, которые могут управлять объектами Post (см. Документы) и объединять их голоса с выбранной стратегией (утверждение, консенсус, единодушие), чтобы решить, уполномочен ли текущий пользователь обновлять сообщение (для вашего первого примера)

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

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

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

Также прочтите эти документы на SecurityComponent.

person ScayTrase    schedule 20.02.2015
comment
Зайдите на KnpUniversity knpuniversity.com/screencast/new-in-symfony3/voter для краткого руководства, которое объясняет самые важные вещи :-) - person MauganRa; 15.08.2016