77 votes

Comment vérifier si un utilisateur est connecté à Symfony2 dans un contrôleur ?

Je lis ici comment vérifier le statut de connexion d'un utilisateur à l'intérieur d'un template twig pour un site web basé sur Symfony2. Cependant, j'ai besoin de savoir comment vérifier si l'utilisateur est connecté à partir de l'intérieur d'un contrôleur. Je suis sûr que le code suivant est correct :

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

mais il renvoie toujours quelque chose, par exemple un utilisateur connecté ou un utilisateur anonyme.

Une idée ? Merci d'avance.

0 votes

Ne pouvez-vous pas vérifier si $user != "anon." ?

0 votes

Eh bien, je cherchais quelque chose de plus "sûr". N'y a-t-il pas un autre moyen, c'est-à-dire une fonction à appeler ?

153voto

Bryson Points 836

Avertissement : Vérification de 'IS_AUTHENTICATED_FULLY' seul renverra false si l'utilisateur s'est connecté en utilisant la fonctionnalité "Remember me".

Selon la documentation de Symfony 2, il y a 3 possibilités :

EST_AUTHENTIFIÉ_ANONYMEMENT - automatiquement attribué à un utilisateur qui se trouve dans une partie du site protégée par un pare-feu mais qui ne s'est pas encore connecté. Cela n'est possible que si l'accès anonyme a été autorisé.

EST_AUTHENTIFIÉ_REMEMBERED - automatiquement attribué à un utilisateur qui a été authentifié via un cookie "remember me".

EST_AUTHENTIFIÉ_COMPLÈTEMENT - automatiquement attribué à un utilisateur qui a fourni ses données de connexion pendant la session en cours.

Ces rôles représentent trois niveaux d'authentification :

Si vous avez le IS_AUTHENTICATED_REMEMBERED rôle, alors vous avez aussi le site IS_AUTHENTICATED_ANONYMOUSLY rôle. Si vous avez le IS_AUTHENTICATED_FULLY vous avez également les deux autres rôles. En d'autres termes, ces rôles représentent trois niveaux d'augmentation. "d'authentification.

J'ai rencontré un problème où les utilisateurs de notre système qui avaient utilisé la fonctionnalité "Se souvenir de moi" étaient traités comme s'ils ne s'étaient pas connectés du tout sur des pages qui ne vérifiaient que la présence d'un numéro d'identification. 'IS_AUTHENTICATED_FULLY' .

La solution consiste alors à leur demander de se reconnecter s'ils ne sont pas pleinement authentifiés, ou à vérifier le rôle mémorisé :

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

J'espère que cela évitera à quelqu'un de faire la même erreur que moi. J'ai utilisé ce même article comme référence lorsque j'ai cherché comment vérifier si quelqu'un était connecté ou non sur Symfony 2.

Source : http://symfony.com/doc/2.3/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources

4 votes

En fait, vous pourriez simplement utiliser $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED') puisque les rôles sont hiérarchisés. Ainsi, avoir IS_AUTHENTICATED_FULLY implique que l'utilisateur a également IS_AUTHENTICATED_REMEMBERED .

3 votes

Pas vrai. IS_AUTHENTICATED_REMEMBERED renvoie la réponse vraie uniquement lorsque l'utilisateur utilise la fonctionnalité "Se souvenir de moi". Le fait d'avoir IS_AUTHENTICATED_FULLY implique IS_AUTHENTICATED_REMEMBERED, mais pas l'inverse.

4 votes

Bien. Si IS_AUTHENTICATED_FULLY garantit également qu'un utilisateur a IS_AUTHENTICATED_REMEMBERED alors vous ne devez vérifier que IS_AUTHENTICATED_REMEMBERED .

56voto

JustAnil Points 4635

SecurityContext sera déprécié en Symfony 3.0

Avant Symfony 2.6 vous utiliseriez SecurityContext .
SecurityContext sera déprécié dans Symfony 3.0 en faveur de la AuthorizationChecker .

Pour Symfony 2.6+ & Symfony 3.0 utiliser AuthorizationChecker .


Symfony 2.6 (et inférieur)

// 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+ (et à partir de Symfony 2.6+)

security.context devient security.authorization_checker .
Nous obtenons maintenant notre jeton à partir de security.token_storage au lieu de la 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

Pour en savoir plus, consultez la documentation : AuthorizationChecker
Comment faire cela en twig ? Symfony 2 : Comment vérifier si un utilisateur n'est pas connecté dans un modèle ?

2 votes

Depuis l'intérieur de Symfony Controller vous pouvez simplement écrire $this->isGranted($role, $obj, $errMsg) . Le site denyAccessUnlessGranted() et la fonction isGranted() sont toutes deux des raccourcis pour appeler isGranted() en el security.authorization_checker service.

46voto

Lorenzo Marcon Points 3840

Essayez ça :

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

Pour plus d'informations :

"Les utilisateurs anonymes sont techniquement authentifiés, ce qui signifie que la méthode isAuthenticated() d'un objet utilisateur anonyme renvoie true. Pour vérifier si votre utilisateur est réellement authentifié, vérifiez que le rôle IS_AUTHENTICATED_FULLY".

Source : http://symfony.com/doc/current/book/security.html

0 votes

Oui, ça marche... merci beaucoup ! Cependant, pensez-vous que le paramètre $user != "anon." est suffisamment sécurisé ? Ma crainte est qu'une nouvelle version puisse modifier la valeur renvoyée par un utilisateur anonyme ! N'est-ce pas possible ?

2 votes

Eh bien puisqu'il y a cette solution fournie par Symfony, je vous suggère d'utiliser celle-ci (isGranted). Je ne pense pas qu'ils vont changer le comportement d'une fonctionnalité aussi basique que le composant de sécurité. D'ailleurs, l'utilisation de isGranted est beaucoup plus professionnelle et propre qu'une simple comparaison de chaînes de caractères.

0 votes

Merci encore pour cette réponse complète !

9voto

Pour ajouter à la réponse donnée par Anil, en symfony3 vous pouvez utiliser $this->getUser() pour déterminer si l'utilisateur est connecté, une simple condition telle que if(!$this->getUser()) {} fera l'affaire.

Si vous regardez le code source qui est disponible dans le contrôleur de base, il fait exactement la même chose que celle définie par Anil.

0 votes

L'approche $this->getUser() fonctionne très bien, je viens de la tester dans Symfony 5. Supposons également que dans le contrôleur vous ayez $someVar = $this->getUser() ; et que vous le passiez à twig. Ensuite, vous pouvez faire quelque part dans la balise body {{dump(someVar)}} ou {% dump(someVar) %} et vous obtiendrez soit un null soit le contenu de l'objet user.

7voto

magnetik Points 1030

Si vous utilisez l'annotation de sécurité de l SensioFrameworkExtraBundle vous pouvez utiliser quelques expressions (qui sont définies dans le document \Symfony\Component\Security\Core\Authorization\ExpressionLanguageProvider ):

  • @Security("is_authenticated()") : pour vérifier que l'utilisateur est autorisé et non anonyme
  • @Security("is_anonymous()") : pour vérifier si l'utilisateur actuel est l'utilisateur anonyme
  • @Security("is_fully_authenticated()") : équivalent à is_granted('IS_AUTHENTICATED_FULLY')
  • @Security("is_remember_me()") : équivalent à is_granted('IS_AUTHENTICATED_REMEMBERED')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X