Ваш вопрос заставил меня задуматься. При использовании безопасности symfony2 у вас возникла одна проблема: либо сеанс действителен, то есть пользователь аутентифицирован как анонимный или реальный пользователь, либо сеанс недействителен.
Итак, учитывая это, я не вижу, чтобы ваш подход работал так, как вам хотелось бы, потому что, скажем, user1 входит в систему и использует app1. Теперь он переключается на app2 и не находится в базе данных, что означает, что у него не должно быть доступа. Что делать сейчас? Отменить сессию? Это будет означать, что он должен снова войти в app1.
Если бы вы использовали субдомены, вы могли бы привязать сеанс к этому субдомену, но это означало бы, что пользователь должен снова войти в систему для каждого приложения.
Существует еще одна проблема: похоже, что symfony2 сохраняет идентификатор пользователя в сеансе, поэтому без доступа к базе данных app1 вы не сможете узнать пароль и роли пользователя в базе данных app1 и не сможете проверить за это.
Полагаю, безопасность symfony2 просто не была создана для такого поведения. Ожидается, что сеанс будет относиться к одному и тому же пользователю во всем приложении.
Я не думаю, что symfony2 - большая проблема здесь , но общая обработка с php. Давайте на минуту подумаем, что бы я предложил без symfony2:
Когда пользователь входит в систему, сохраните пользователя и роли в определенном массиве в сеансе, например:
user.app1 = array('username','password',array('role1','role2'))
Теперь при каждом запросе к app1 я бы проверял, присутствует ли user.app1 в сеансе, и считывал оттуда роли. Если нет, я бы проверил user.app2, user.app3 и так далее. Если я не нахожу ничего, перенаправьте на логин. Если я найду один, я бы запросил базу данных, чтобы найти пользователя с тем же именем пользователя и сравнить другие значения. Если совпадают, сохраните все в базу данных. Если нет, проверьте следующего пользователя из сеанса.
Я посмотрел справочник по безопасности Symfony , и у вас есть несколько точек расширения, так что, возможно, вы сможете работать с этого момента. form_login
получил success_handler
, поэтому добавление массива в сессию, как предложено выше, должно быть сделано там. Сам брандмауэр имеет некоторые параметры, такие как request_matcher
и entry_point
, которые можно использовать для добавления дополнительных проверок, подобных тем, которые я упоминал выше. Все они определены как сервисы, поэтому внедрение менеджера сущностей и контекста безопасности не должно быть проблемой.
Лично я считаю, что сам дизайн здесь неоптимален, и вам лучше реорганизовать код, чтобы использовать одного пользователя для всех приложений и разных ролей (помните, что вы можете определить много менеджеров сущностей и использовать разные базы данных) или даже консолидировать все базы данных и хранение всего в одной базе данных, используя acl, чтобы пользователи не могли просматривать «неправильный» контент.