Як перевірити, чи ввійшов користувач в систему Symfony2 всередині контролера?


75

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

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

але воно завжди щось повертає, наприклад зареєстрований користувач або анонімний користувач.

Будь-яка ідея? Заздалегідь спасибі.


Ви не можете перевірити, чи $ user! = "anon."?
— Lorenzo Marcon

Ну, я шукав щось більш «безпечне». Це не інший спосіб, тобто якась функція для виклику?
— JeanValjean

Відповіді:


150

Попередження : Перевірка на наявність 'IS_AUTHENTICATED_FULLY'поодинці поверне значення false, якщо користувач увійшов, використовуючи функцію "Запам'ятати мене".

Згідно з документацією Symfony 2, є 3 можливості:

IS_AUTHENTICATED_ANONYMOUSLY - автоматично призначається користувачеві, який знаходиться в частині сайту, захищеному брандмауером, але який фактично не ввійшов у систему. Це можливо лише за умови дозволу анонімного доступу.

IS_AUTHENTICATED_REMEMBERED - автоматично призначається користувачеві, який пройшов аутентифікацію за допомогою файлу cookie запам'ятати мене.

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.
— theunraveler

3
Неправда. IS_AUTHENTICATED_REMEMBERED повертає true лише тоді, коли користувач використовує функцію "Запам'ятати мене". Наявність IS_AUTHENTICATED_FULLY означає, що IS_AUTHENTICATED_REMEMBERED, але не навпаки.
— Брайсон,

4
Правильно. Якщо це IS_AUTHENTICATED_FULLYтакож гарантує, що користувач має IS_AUTHENTICATED_REMEMBERED, то вам потрібно лише перевірити наявність IS_AUTHENTICATED_REMEMBERED.
— theunraveler

1
Як це обробляється, коли у вас різні РОЛІ. Наприклад, у мене є ROLE_USER та ROLE_ADMIN, які потрібні для певних областей сайту, я хотів би дозволити обом цим типам користувачів доступ до відповідних областей з рівнем IS_AUTHENTICATED_REMEMBERED. Як я можу це зробити?
— Нік

2
До речі, використовувати $this->container->get('security.authorization_checker')замість цього (нове у 2.6)
— Ронан,

56

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

Детальніше читайте тут у документах: Як це зробити у гілці ?: Symfony 2: Як мені перевірити, чи не ввійшов користувач у шаблон?AuthorizationChecker


2
Зсередини symfony Controllerви можете просто писати $this->isGranted($role, $obj, $errMsg). denyAccessUnlessGranted()Функції та isGranted()функції є тільки ярлики зателефонувати isGranted()на security.authorization_checkerслужбу.
— Мехулкумар,

46

Спробуйте це:

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

Додаткова інформація:

"Анонімні користувачі технічно автентифікуються, це означає, що метод isAuthenticated () анонімного об'єкта користувача поверне істину. Щоб перевірити, чи справді ваш користувач автентифікований, перевірте роль IS_AUTHENTICATED_FULLY."

Джерело: http://symfony.com/doc/current/book/security.html


Так! Це працює ... велике спасибі! Однак, чи вважаєте ви, що $ user! = "Anon." досить безпечний? Я боюся, що новий випуск може змінити значення, яке повертає анонімний користувач! Хіба це не можливо?
— JeanValjean

2
Ну .. оскільки існує таке рішення, яке надає Symfony, я пропоную вам скористатися цим (isGranted). Я не думаю, що вони збираються змінити поведінку такої базової функції, як компонент безпеки. До речі, використання isGranted набагато професійніше та чіткіше, ніж просте порівняння рядків.
— Lorenzo Marcon

Ще раз спасибі за повну відповідь!
— JeanValjean

3
До речі, використовувати $this->container->get('security.authorization_checker')замість цього (нове у 2.6)
— Ронан,

Ви подали запит на неіснуючу послугу "security.context".
— fdrv

7

Якщо ви використовуєте анотацію безпеки з 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')

6

Щоб додати до відповіді, даної Анілом, у symfony3 ви можете $this->getUser()визначити, чи ввійшов користувач, простий стан, як це if(!$this->getUser()) {}буде робити.

Якщо ви подивитесь на вихідний код, який доступний у базовому контролері, він робить те саме, що визначено Anil.


Підхід $ this-> getUser () працює нормально, просто протестував його в Symfony 5. Крім того, припустимо, у контролері у вас є $ someVar = $ this-> getUser (); і передайте його гілочці. Тоді ви можете зробити десь усередині тегу тіла {{dump (someVar)}} або {% dump (someVar)%}, і ви отримаєте або нуль, або вміст користувацького об'єкта.
— Алі

6

Якщо ви використовуєте ролі, ви можете перевірити, ROLE_USER чи є це рішення, яке я використовую:

if (TRUE === $this->get('security.authorization_checker')->isGranted('ROLE_USER')) {
    // user is logged in
} 

Якщо припустити, що ваш додаток призначено ROLE_USERвсім. Не всі програми роблять це.
— Брайан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.