Как проверить, зарегистрирован ли пользователь в Symfony2 внутри контроллера?

65

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

$user = $this->get('security.context')->getToken()->getUser();

но он всегда возвращает что-то, например. зарегистрированного пользователя или анонимного пользователя.

Любая идея? Спасибо заранее.

  • 0
    не могли бы вы проверить, если $ user! = "anon."?
  • 0
    Ну, я искал что-то более «безопасное». Разве нет другого способа, то есть какой-то функции для вызова?
Теги:
symfony-security
login

6 ответов

128
Лучший ответ

Предупреждение: проверка только для 'IS_AUTHENTICATED_FULLY' вернет false, если пользователь выполнил вход в систему, используя функцию "Запомнить меня".

В соответствии с документацией Symfony 2 существует 3 возможности:

IS_AUTHENTICATED_ANONYMOUSLY - автоматически назначается пользователю, который в защищенной части брандмауэра сайта, но на самом деле вошел в систему. Это возможно только в том случае, если анонимный доступ разрешен.

IS_AUTHENTICATED_REMEMBERED - автоматически назначается пользователю, который был аутентифицируется через куки файл "запомнить меня".

IS_AUTHENTICATED_FULLY - автоматически назначается пользователю, который имеет предоставили свои данные для входа в течение текущего сеанса.

Эти роли представляют собой три уровня аутентификации:

Если у вас есть роль IS_AUTHENTICATED_REMEMBERED, то у вас также есть роль IS_AUTHENTICATED_ANONYMOUSLY. Если у вас есть IS_AUTHENTICATED_FULLY, тогда у вас также есть две другие роли. Другими словами, эти роли представляют собой три уровня "сила" аутентификации.

У меня возникла проблема, когда пользователи нашей системы, которые использовали функциональность "Помни меня", обрабатывались так, как если бы они вообще не вошли в систему на страницах, которые проверялись только на 'IS_AUTHENTICATED_FULLY'.

Тогда ответ должен состоять в том, чтобы потребовать, чтобы они повторно вошли в систему, если они полностью не прошли аутентификацию, или чтобы проверить запомненную роль:

$securityContext = $this->container->get('security.authorization_checker');
if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
    // authenticated REMEMBERED, FULLY will imply REMEMBERED (NON anonymous)
}

Надеюсь, это спасет кого-то там от совершения той же самой ошибки, которую я совершил. Я использовал этот пост в качестве ссылки, когда смотрел, как проверить, был ли кто-то зарегистрирован или нет на Symfony 2.

Источник: http://symfony.com/doc/2.3/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources

  • 4
    На самом деле, вы можете просто использовать $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED') , поскольку роли являются иерархическими. Таким образом, наличие IS_AUTHENTICATED_FULLY означает, что у пользователя также есть IS_AUTHENTICATED_REMEMBERED .
  • 3
    Не правда. IS_AUTHENTICATED_REMEMBERED возвращает true только тогда, когда пользователь использует функцию «Запомнить меня». Наличие IS_AUTHENTICATED_FULLY подразумевает IS_AUTHENTICATED_REMEMBERED, но не наоборот.
Показать ещё 8 комментариев
45

SecurityContext будет устаревшим в Symfony 3.0

До Symfony 2.6 вы должны использовать SecurityContext.
SecurityContext будет устаревать в Symfony 3.0 в пользу AuthorizationChecker.

Для Symfony 2.6+ и Symfony 3.0 используйте AuthorizationChecker.


Symfony 2.6 (и ниже)

// Get our Security Context Object - [deprecated in 3.0]
$security_context = $this->get('security.context');
# e.g: $security_context->isGranted('ROLE_ADMIN');

// Get our Token (representing the currently logged in user)
$security_token = $security_context->getToken();
# e.g: $security_token->getUser();
# e.g: $security_token->isAuthenticated();
# [Careful]             ^ "Anonymous users are technically authenticated"

// Get our user from that security_token
$user = $security_token->getUser();
# e.g: $user->getEmail(); $user->isSuperAdmin(); $user->hasRole();

// Check for Roles on the $security_context
$isRoleAdmin = $security_context->isGranted('ROLE_ADMIN');
# e.g: (bool) true/false

Symfony 3.0+ (и от Symfony 2.6 +)

security.context становится security.authorization_checker.
Теперь мы получаем наш токен от security.token_storage вместо security.context

// [New 3.0] Get our "authorization_checker" Object
$auth_checker = $this->get('security.authorization_checker');
# e.g: $auth_checker->isGranted('ROLE_ADMIN');

// Get our Token (representing the currently logged in user)
// [New 3.0] Get the `token_storage` object (instead of calling upon `security.context`)
$token = $this->get('security.token_storage')->getToken();
# e.g: $token->getUser();
# e.g: $token->isAuthenticated();
# [Careful]            ^ "Anonymous users are technically authenticated"

// Get our user from that token
$user = $token->getUser();
# e.g (w/ FOSUserBundle): $user->getEmail(); $user->isSuperAdmin(); $user->hasRole();

// [New 3.0] Check for Roles on the $auth_checker
$isRoleAdmin = $auth_checker->isGranted('ROLE_ADMIN');
// e.g: (bool) true/false

Подробнее читайте в документах: AuthorizationChecker
Как это сделать в twig?: Symfony 2: Как проверить, не зашел ли пользователь внутри шаблона?

  • 2
    Внутри Symfony Controller вы можете просто написать $this->isGranted($role, $obj, $errMsg) . Функция denyAccessUnlessGranted() функции isGranted() являются просто ярлыками для вызова isGranted() в сервисе security.authorization_checker .
45

Попробуйте следующее:

if( $this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
    // authenticated (NON anonymous)
}

Дополнительная информация:

"Анонимные пользователи технически аутентичны, что означает, что isAuthenticated() анонимного объекта пользователя вернет true. Чтобы проверить, действительно ли ваш пользователь аутентифицирован, проверьте IS_AUTHENTICATED_FULLY роль."

Источник: http://symfony.com/doc/current/book/security.html

  • 0
    Да! Это работает ... большое спасибо! Тем не менее, вы думаете, что $ user! = "Anon." достаточно безопасно? Я боюсь, что новая версия может изменить значение, возвращаемое анонимным пользователем! Разве это не возможно?
  • 2
    Ну, так как Symfony предлагает это решение, я бы посоветовал вам использовать его (isGranted). Я не думаю, что они собираются изменить поведение такой базовой функции, как компонент безопасности. Кстати, использование isGranted намного более профессионально и чисто, чем простое сравнение строк.
Показать ещё 4 комментария
5

Если вы используете аннотацию безопасности из SensioFrameworkExtraBundle, вы можете использовать несколько выражений (которые определены в \Symfony\Component\Security\Core\Authorization\ExpressionLanguageProvider):

  • @Security("is_authenticated()"): чтобы проверить, что пользователь отключен, а не анонимный
  • @Security("is_anonymous()"): чтобы проверить, является ли текущий пользователь анонимным пользователем
  • @Security("is_fully_authenticated()"): эквивалентно is_granted('IS_AUTHENTICATED_FULLY')
  • @Security("is_remember_me()"): эквивалентно is_granted('IS_AUTHENTICATED_REMEMBERED')
5

Если вы используете роли, вы можете проверить ROLE_USER это решение, которое я использую:

if (TRUE === $this->get('security.authorization_checker')->isGranted('ROLE_USER')) {
    // user is logged in
} 
  • 0
    Предполагая, что ваше приложение назначает ROLE_USER для всех. Не все приложения делают.
2

Чтобы добавить к ответу, предоставленному Anil, в symfony3, вы можете использовать $this->getUser(), чтобы определить, вошел ли пользователь в систему, простое условие, подобное if(!$this->getUser()) {}.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню