Я разрабатываю приложение в symfony с открытым доступом, когда пользователи входят в систему с формой входа и разделом администратора с другой формой входа и другим провайдером пользователя.
Я создал LoginFormAuthenticator для каждой области и два брандмауэра для выбора правильного аутентификатора в каждой области. Это моя безопасность.yaml:
безопасность: провайдеры: admin_provider: организация: класс: App\Entity\AdminUser свойство: электронная почта веб_провайдер: организация: класс: Приложение\Энтити\Пользователь свойство: электронная почта
firewalls:
admin:
pattern: '^/admin'
anonymous: true
provider: admin_provider
guard:
authenticators:
- App\Security\AdminLoginFormAuthenticator
logout:
path: /admin/logout
target: /
main:
anonymous: true
provider: web_provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: /logout
Теперь я добавляю /api в проект, и оба пользователя должны иметь доступ, управляя правами доступа по-разному, если пользователь является публичным пользователем или администратором.
При разработке контроллера в области /api я не могу получить пользователя при входе в систему через администратора.
Вопрос в том, как в /api я могу получить AdminUser, если он вошел в систему, или пользователя (в этом порядке) при доступе к $this->getuser() или $this->denyAccessUnlessGranted()?
Я попытался добавить App\Security\AdminLoginFormAuthenticator в основной брандмауэр и добавить chain_provider в main.provider. Но это не работает.
Спасибо.




Брандмауэры должны иметь «общий контекст», чтобы иметь доступ к одним и тем же подключенным пользователям. Я думаю, что эта формулировка пришла из Symfony 2, где SecurityContext был сервисом, хранящим пользователя и авторизацию.
Вам нужно немного изменить конфигурацию, и тогда $this->getUser() и $this->denyAccessUnlessGranted() будут возвращать/использовать один и тот же объект пользователя для обоих брандмауэров.
firewalls:
admin:
pattern: '^/admin'
context: my_app_context
anonymous: true
# ...
main:
anonymous: true
context: my_app_context
# ...
Нет необходимости в общем провайдере или специальной защите. Хотя может быть проще иметь везде один и тот же класс User или хотя бы общую роль для ясности.
Сложно заставить службу безопасности работать с «AdminUser», если вы подключены как «User», и наоборот. И я подозреваю, что код, обрабатывающий одного пользователя или другого, будет сложным. Я бы попытался настроить базовый объект, общий для двух брандмауэров, и, в конечном итоге, чтобы AdminUser / User расширил его для дополнительной дополнительной информации.
Наконец, я решил использовать ваш подход с одним объектом, общим для брандмауэров, поддерживая брандмауэры для двух разных форм входа в систему (хотя это и не обязательно, просто для целей дизайна) и управляя контролем доступа с помощью ролей. Спасибо
Привет @romaricdrigon, проблема в том, что на каждом брандмауэре есть два объекта для каждого пользователя, пользователь может войти в систему с правами администратора и войти на общедоступный сайт с разными пользователями. При таком подходе в обоих разделах используется один и тот же объект. Если есть возможность сохранить две сущности, я предпочитаю это. Если нет, я бы попытался объединить сущности в одну сущность.