Подтвердить что ты не робот

Лучший способ управления разрешениями пользователя/группы с помощью Symfony2

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

У нас есть несколько объектов /db записей (события, места проведения и т.д.), некоторые из которых имеют дочерние объекты (что касается тех же разрешений - изображения, мета и т.д.)

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

В настоящее время для управления пользователями и группами есть пользователь, группа пользователей и группа.

Каждый родительский объект, например, места в качестве столбца для user_id и group_id.

Хорошо работает (в symfony 1.4), но это беспорядочно - каждый запрос для чего-либо должен выполнять сложные объединения для получения возможных групп и т.д. Мы хотели бы найти более простой способ.

Я был очень взволнован компонентом ACL Sf2, но мне снова и снова говорят, что я не должен использовать его для поиска объектов, которыми может управлять пользователь, - скорее, я должен использовать ACL, чтобы узнать, разрешено ли пользователю управлять своими собственными объектами (не очень полезно, но что угодно).

Все альтернативные попытки онлайн, которые я нашел для этого, говорят, чтобы вытащить все объекты из db, а затем фильтровать ACL - это мило для мамы и поп-сайта - не произойдет с миллионом объектов.

Итак... Мне бы хотелось услышать идеи о том, как мы можем это сделать - мы также открыты для выхода Symfony для чего-то, что имеет масштабируемое решение ACL, но пока ничего не найдено (php или ruby) к тому же, хотя мы хотели бы продолжать использовать Sf. Обратите внимание, что мы намерены использовать MongoDB в случае, если это имеет значение.

4b9b3361

Ответ 1

Из того, как я это понимаю, ACL используется для предоставления доступа к определенному объекту конкретному человеку для специальных сценариев. То, что вы описываете, более общее, но оно просто отличается от того, что Symfony2 описывает для безопасности (у этого человека есть роль "admin", но только для объектов, содержащихся в определенной группе).

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

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

  • Создайте избирателя, чтобы справиться с этим. Избиратели позволяют проверять токены авторизации и возвращать, предоставлен ли доступ или отклонен на основании того, как вы его обрабатываете. Таким образом, вы можете создать пользовательский избиратель, который проверяет группу пользователей и пытается сопоставить ее с группой, в которой находится объект. Если это так, верните ACCESS_GRANTED, иначе ACCESS_DENIED или ACCESS_ABSTAIN, если Voter недействителен для текущей проверки. EDIT: Вот ссылка на поваренную книгу Symfony2 для избирателей: http://symfony.com/doc/current/cookbook/security/voters.html

  • Также возможно изучить интерфейс SecurityContext. Это обеспечивает метод isGranted(), который определяет определение доступа к объектам. Если избирателей недостаточно просто, вам, возможно, придется идти по пути создания нового класса SecurityContext; Я думаю, что это будет немного более привлекательным, хотя.

Как я уже сказал, я не профессионал и не имею решения; это лишь некоторые направления, которые я исследую, чтобы попытаться решить (что я чувствую) подобную проблему. Надеюсь, что это поможет.

Ответ 2

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

Пока Symfony предоставляет уровень безопасности /ACL для использования, вам не нужно использовать его или, по крайней мере, полностью.

Примерно в любой момент времени в вашем коде вы можете выбросить Symfony\Component\Security\Core\Exception\AccessDeniedException, и уровень безопасности будет "удариться" и обработать его для вас, например перенаправление пользователей на страницу входа и т.д.

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

Короче говоря, Symfony предоставляет несколько отличных механизмов и функций для создания ACL, вам не нужно работать, чтобы соответствовать вашим данным и процессам в том, что они определили.

Для нашей системы в качестве примера у нас есть учетные записи, роли и группы в нашей системе (наряду с Разрешениями). Мы также делим разделы данных на департаменты. Хотя пользователи могут иметь роли и разрешения на глобальном уровне, они также могут иметь доступ к Департаменту. Эта настройка была сделана с использованием встроенных функций Symfony ACL и инструментов проверки доступа почти непригодными (не означает, что их инструменты бесполезны, на самом деле они великолепны, они просто не подходят для нашего использования). Таким образом, мы создали собственный сервис (который использует некоторые тонко настроенные запросы), где мы передаем соответствующие данные, касающиеся проверки, и выдает соответствующий Symfony\Component\Security\Core\Exception\AccessDeniedException, когда сбой проверки.