Як перевірити, чи ввійшов користувач в систему 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.