Wie kann ich überprüfen, ob ein Benutzer in Symfony2 in einem Controller angemeldet ist?

75

Ich habe hier gelesen , wie Sie den Anmeldestatus eines Benutzers anhand einer Zweigvorlage für eine Symfony2-basierte Website überprüfen können. Ich muss jedoch wissen, wie ich überprüfen kann, ob der Benutzer innerhalb eines Controllers angemeldet ist. Ich war mir ziemlich sicher, dass der folgende Code richtig war:

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

Es wird jedoch immer etwas zurückgegeben, z. B. ein protokollierter Benutzer oder ein anonymer Benutzer.

Irgendeine Idee? Danke im Voraus.

Jean Valjean
quelle
Kannst du nicht überprüfen, ob $ user! = "anon."?
Lorenzo Marcon
Nun, ich suchte nach etwas "Sichererem". Ist nicht ein anderer Weg, dh eine Funktion aufzurufen?
JeanValjean

Antworten:

150

Warnung : 'IS_AUTHENTICATED_FULLY'Wenn Sie nur nach prüfen, wird false zurückgegeben, wenn sich der Benutzer mit der Funktion "Angemeldet bleiben" angemeldet hat.

Laut Symfony 2-Dokumentation gibt es drei Möglichkeiten:

IS_AUTHENTICATED_ANONYMOUSLY - Wird automatisch einem Benutzer zugewiesen, der sich in einem Firewall-geschützten Teil der Site befindet, sich jedoch nicht angemeldet hat. Dies ist nur möglich, wenn anonymer Zugriff zugelassen wurde.

IS_AUTHENTICATED_REMEMBERED - Wird automatisch einem Benutzer zugewiesen, der über ein Remember-Me-Cookie authentifiziert wurde.

IS_AUTHENTICATED_FULLY - Wird automatisch einem Benutzer zugewiesen, der während der aktuellen Sitzung seine Anmeldedaten angegeben hat.

Diese Rollen repräsentieren drei Authentifizierungsebenen:

Wenn Sie die IS_AUTHENTICATED_REMEMBEREDRolle haben, dann haben Sie auch die IS_AUTHENTICATED_ANONYMOUSLYRolle. Wenn Sie die IS_AUTHENTICATED_FULLYRolle haben, haben Sie auch die beiden anderen Rollen. Mit anderen Worten, diese Rollen repräsentieren drei Ebenen zunehmender "Stärke" der Authentifizierung.

Ich bin auf ein Problem gestoßen, bei dem Benutzer unseres Systems, die die Funktion "Angemeldet bleiben" verwendet hatten, so behandelt wurden, als hätten sie sich auf Seiten, auf die nur geprüft wurde, überhaupt nicht angemeldet 'IS_AUTHENTICATED_FULLY'.

Die Antwort besteht dann darin, dass sie sich erneut anmelden müssen, wenn sie nicht vollständig authentifiziert sind, oder nach der gespeicherten Rolle suchen müssen:

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

Hoffentlich wird dies jemanden da draußen davor bewahren, den gleichen Fehler zu machen, den ich gemacht habe. Ich habe genau diesen Beitrag als Referenz verwendet, um zu überprüfen, ob jemand bei Symfony 2 angemeldet war oder nicht.

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

Bryson
quelle
4
Eigentlich könnte man nur verwenden $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED'), da die Rollen hierarchisch sind. Das IS_AUTHENTICATED_FULLYbedeutet also, dass der Benutzer auch hat IS_AUTHENTICATED_REMEMBERED.
Theunraveler
3
Nicht wahr. IS_AUTHENTICATED_REMEMBERED gibt nur dann true zurück, wenn der Benutzer die Funktion "Remember me" verwendet. IS_AUTHENTICATED_FULLY bedeutet IS_AUTHENTICATED_REMEMBERED, aber nicht umgekehrt.
Bryson
4
Richtig. Wenn dies IS_AUTHENTICATED_FULLYauch garantiert, dass ein Benutzer hat IS_AUTHENTICATED_REMEMBERED, müssen Sie immer nur nach suchen IS_AUTHENTICATED_REMEMBERED.
Theunraveler
1
Wie wird damit umgegangen, wenn Sie unterschiedliche ROLLEN haben? Ich habe beispielsweise einen ROLE_USER und einen ROLE_ADMIN, die für bestimmte Bereiche der Site erforderlich sind. Ich möchte diesen beiden Benutzertypen den Zugriff auf ihre jeweiligen Bereiche mit der Ebene IS_AUTHENTICATED_REMEMBERED ermöglichen. Wie kann ich das erreichen?
Nick
2
Übrigens, verwenden Sie $this->container->get('security.authorization_checker')stattdessen (neu in 2.6)
Ronan
56

SecurityContext wird in veraltet sein Symfony 3.0

Bevor Symfony 2.6Sie verwenden würden SecurityContext.
SecurityContextwird Symfony 3.0zugunsten der abgelehnt AuthorizationChecker.

Für Symfony 2.6+& Symfony 3.0Verwendung AuthorizationChecker.


Symfony 2.6 (und darunter)

// 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+ (und von Symfony 2.6+)

security.contextwird security.authorization_checker.
Wir bekommen jetzt unseren Token von security.token_storageanstelle vonsecurity.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

Lesen Sie hier mehr in den Dokumenten: Wie geht das im Zweig?: Symfony 2: Wie überprüfe ich, ob ein Benutzer nicht in einer Vorlage angemeldet ist?AuthorizationChecker

Anil
quelle
2
Von innen heraus können ControllerSie einfach schreiben $this->isGranted($role, $obj, $errMsg). Die denyAccessUnlessGranted()Funktion und die isGranted()Funktionen sind nur Verknüpfungen, um isGranted()den security.authorization_checkerDienst aufzurufen .
Mehulkumar
46

Versuche dies:

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

Weitere Informationen:

"Anonyme Benutzer sind technisch authentifiziert. Dies bedeutet, dass die isAuthenticated () -Methode eines anonymen Benutzerobjekts true zurückgibt. Um zu überprüfen, ob Ihr Benutzer tatsächlich authentifiziert ist, überprüfen Sie die Rolle IS_AUTHENTICATED_FULLY."

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

Lorenzo Marcon
quelle
Ja! Es funktioniert ... vielen Dank! Denken Sie jedoch, dass der $ user! = "Anon". ist sicher genug? Ich befürchte, dass eine neue Version den von einem anonymen Benutzer zurückgegebenen Wert ändern könnte! Ist das nicht möglich
JeanValjean
2
Nun, da es diese Lösung von Symfony gibt, würde ich Ihnen empfehlen, diese zu verwenden (isGranted). Ich glaube nicht, dass sie das Verhalten einer so grundlegenden Funktion wie der Sicherheitskomponente ändern werden. Die Verwendung von isGranted ist übrigens weitaus professioneller und sauberer als ein einfacher Zeichenfolgenvergleich.
Lorenzo Marcon
Nochmals vielen Dank für die vollständige Antwort!
JeanValjean
3
Übrigens, verwenden Sie $this->container->get('security.authorization_checker')stattdessen (neu in 2.6)
Ronan
Sie haben einen nicht vorhandenen Dienst "security.context" angefordert.
fdrv
7

Wenn Sie Sicherheitsanmerkungen aus dem verwenden SensioFrameworkExtraBundle, können Sie einige Ausdrücke verwenden (die in definiert sind \Symfony\Component\Security\Core\Authorization\ExpressionLanguageProvider):

  • @Security("is_authenticated()"): um zu überprüfen, ob der Benutzer autorisiert und nicht anonym ist
  • @Security("is_anonymous()"): um zu überprüfen, ob der aktuelle Benutzer der anonyme Benutzer ist
  • @Security("is_fully_authenticated()"): gleichwertig is_granted('IS_AUTHENTICATED_FULLY')
  • @Security("is_remember_me()"): gleichwertig is_granted('IS_AUTHENTICATED_REMEMBERED')
magnetik
quelle
6

Um die von Anil gegebene Antwort zu ergänzen , können Sie in symfony3 mithilfe $this->getUser()einer einfachen Bedingung bestimmen, ob der Benutzer angemeldet ist if(!$this->getUser()) {}.

Wenn Sie sich den Quellcode ansehen, der im Basis-Controller verfügbar ist, funktioniert er genau so, wie er von Anil definiert wurde.

Ibrahim Azhar Armar
quelle
Der Ansatz $ this-> getUser () funktioniert einwandfrei. Sie wurde nur in Symfony 5 getestet. Angenommen, Sie haben im Controller $ someVar = $ this-> getUser (). und an Zweig weitergeben. Dann können Sie irgendwo innerhalb des Body-Tags {{dump (someVar)}} oder {% dump (someVar)%} etwas tun, und Sie erhalten entweder eine Null oder den Inhalt des Benutzerobjekts.
Ali
6

Wenn Sie Rollen verwenden, können Sie überprüfen, ROLE_USER ob dies die Lösung ist, die ich verwende:

if (TRUE === $this->get('security.authorization_checker')->isGranted('ROLE_USER')) {
    // user is logged in
} 
Redwan Nassim
quelle
Angenommen, Ihre App wird jedem ROLE_USERzugewiesen. Nicht alle Apps tun dies.
Brian