Лучший способ управлять разрешениями для пользователей / групповых объектов с помощью Symfony2 - PullRequest
12 голосов
/ 11 марта 2012

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

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

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

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

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

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

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

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

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

Ответы [ 2 ]

11 голосов
/ 15 апреля 2012

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

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

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

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

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

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

1 голос
/ 19 января 2016

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

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

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

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

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

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

...