Я пытаюсь реализовать единый знак доступа к веб-сайту с помощью Symfony2.
Сама аутентификация работает нормально, но только для начальной страницы. На следующей загруженной странице пользователь больше не войдет в систему.
Соответствующий код:
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles()); $event = new InteractiveLoginEvent($request, $token); $this->get("event_dispatcher")->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $event); $this->get("security.context")->setToken($token); return $this->redirect($this->generateUrl('sonata_user_profile_show'));
Первая страница (без перенаправления):
Вторая страница:
Для пользовательского входа требуется только следующий код.
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles()); $this->get("security.context")->setToken($token); return $this->redirect($this->generateUrl('sonata_user_profile_show'));
Это делает настройку UsernamePasswordToken в контексте безопасности. Этот токен (а также пользователь) будет сериализован и помещен в сеанс. На следующей странице токен будет неэтериализован из сеанса, а обновленный, а также несертифицированный пользователь будет обновлен.
Пользователь-поставщик в FOSUserBundle делает это обновление, используя идентификатор несериализованного пользователя.
Кроме того, Doctrine2 в некоторых случаях использует прокси-классы как сущности-классы вместо исходного класса сущности. Этот прокси-класс перезаписывает функцию «getId ()» объекта сложной реализацией сложной ленивой загрузки.
Это вместе может привести к тому, что когда вы помещаете прокси-объект Doctrine2 в UserPasswordToken, «getId ()» сериализованного и затем несертифицированного прокси-объекта не вернет исходный идентификатор. Когда это произойдет, пользователь не может быть обновлен пользователем-провайдером, а токен станет недействительным.
Исправить это – создать пользовательский пользовательский провайдер, который перезаписывает «refreshUser ()» путем обновления с использованием имени пользователя (или другого уникального свойства).
//... class UserProvider extends FOSUserProvider { /** * {@inheritDoc} */ public function refreshUser(SecurityUserInterface $user) { if (!$user instanceof User) { throw new UnsupportedUserException(sprintf('Expected an instance of User, but got "%s".', get_class($user))); } if (null === $reloadedUser = $this->userManager->findUserBy(array('username' => $user->getUsername()))) { throw new UsernameNotFoundException(sprintf('User with username "%s" could not be reloaded.', $user->getUsername())); } return $reloadedUser; } }