Я настраиваю веб-сайт, на котором хочу использовать отдельные брандмауэры и системы аутентификации для интерфейса и сервера. Итак, мой security.yml
настроен, как показано ниже. Я использую поставщика пользователей in_memory на ранней стадии разработки.
security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
backend_in_memory:
memory:
users:
admin: { password: admin, roles: [ 'ROLE_ADMIN' ] }
frontend_in_memory:
memory:
users:
user: { password: 12345, roles: [ 'ROLE_USER' ] }
firewalls:
# (Configuration for backend omitted)
frontend_login_page:
pattern: ^/login$
security: false
frontend:
pattern: ^/
provider: frontend_in_memory
anonymous: ~
form_login:
check_path: login_check_route # http://example.com/login_check
login_path: login_route # http://example.com/login
access_control:
# (Configuration for backend omitted)
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
Я опустил внутреннюю часть, потому что это не имеет значения. Проблема все еще существует, когда пропущенная часть закомментирована.
Проблема в том, что внешняя аутентификация не будет работать с указанной выше конфигурацией. Вот что я сделал:
- Посетите http://example.com/login.
- Введите учетные данные (пользователь: 12345), нажмите «Войти».
- http://example.com/login_check аутентифицирует пользователя
- Служба аутентификации перенаправляет пользователя обратно на http://example.com/. Ошибка не выдается. На самом деле, когда я включил опцию debug_redirects, она ясно показывает, что «пользователь» аутентифицирован на странице перенаправления.
Ожидаемое поведение: токен безопасности должен показывать, что я вошел в систему как «пользователь» после перенаправления и вернулся на страницу индекса.
Фактическое поведение: токен безопасности по-прежнему показывает «анонимный» вход в систему после перенаправления и возврата на страницу индекса.
Но при почти одинаковых настройках (пути и названия маршрутов не совпадают) бэкенд-часть работает корректно.
После некоторого расследования я обнаружил, что причина в том, как в настоящее время написаны пользовательские поставщики. Обратите внимание, что раздел frontend_in_memory расположен под разделом backend_in_memory, который используется для внутренней аутентификации. Поэтому я явно указываю поставщика frontend_in_memory для внешнего брандмауэра. И это работает - я должен войти в систему с «пользователем: 12345» на странице входа в систему. Войти под "админом" не получится. Поэтому он должен использовать правильного поставщика пользователей. Но я подозреваю, что платформа не может правильно обновить токен безопасности, потому что она все еще ищет учетную запись «пользователь» из первого поставщика пользователей, который является backend_in_memory. На самом деле я могу заставить приведенную выше конфигурацию работать с одним из следующих изменений:
- добавить логин "user" в список пользователей поставщика backend_in_memory (пароль может не совпадать) или
- поменяйте местами frontend_in_memory с backend_in_memory, чтобы frontend_in_memory стал первым поставщиком пользователей.
Конечно, они не являются правильным способом решения этой проблемы. Добавление учетной записи «пользователя» в бэкэнд вообще не имеет смысла; замена порядка двух пользовательских провайдеров исправляет интерфейс, но ломает серверную часть.
Я хотел бы знать, что не так и как это исправить. Спасибо!