Symfony 4.0
Dieser Prozess hat sich nicht von Symfony 3 auf 4 geändert, aber hier ist ein Beispiel mit dem neu empfohlenen AbstractController. Sowohl der security.token_storage
als auch der session
Dienst sind in der übergeordneten getSubscribedServices
Methode registriert , sodass Sie diese nicht in Ihrem Controller hinzufügen müssen.
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends AbstractController{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->container->get('security.token_storage')->setToken($token);
$this->container->get('session')->set('_security_main', serialize($token));
// The user is now logged in, you can redirect or do whatever.
}
}
Symfony 2.6.x - Symfony 3.0.x.
Ab Symfony ist 2.6 security.context
zugunsten von veraltet security.token_storage
. Der Controller kann jetzt einfach sein:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends Controller{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
}
}
Obwohl dies veraltet ist, können Sie es weiterhin verwenden, security.context
da es abwärtskompatibel ist. Seien Sie einfach bereit, es für Symfony 3 zu aktualisieren
Weitere Informationen zu den 2.6-Sicherheitsänderungen finden Sie hier: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md
Symfony 2.3.x.
Um dies in Symfony 2.3 zu erreichen, können Sie das Token nicht mehr nur im Sicherheitskontext festlegen. Sie müssen das Token auch in der Sitzung speichern.
Angenommen, eine Sicherheitsdatei mit einer Firewall wie:
// app/config/security.yml
security:
firewalls:
main:
//firewall settings here
Und eine ähnliche Controller-Aktion:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends Controller{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.context')->setToken($token);
$this->get('session')->set('_security_main',serialize($token));
//Now you can redirect where ever you need and the user will be logged in
}
}
Für die Token-Erstellung möchten Sie Folgendes erstellen UsernamePasswordToken
: Dies akzeptiert 4 Parameter: Benutzerentität, Benutzeranmeldeinformationen, Firewall-Name, Benutzerrollen. Sie müssen die Benutzeranmeldeinformationen nicht angeben, damit das Token gültig ist.
Ich bin nicht 100% sicher, dass das Setzen des Tokens auf dem security.context
notwendig ist, wenn Sie nur sofort umleiten wollen. Aber es scheint nicht weh zu tun, also habe ich es verlassen.
Dann der wichtige Teil, das Setzen der Sitzungsvariablen. Die Variablen Namenskonvention wird _security_
von der Firewall Namen, in diesem Fall gefolgt main
Herstellung_security_main
$this->get('session')->set('_security_main', serialize($token));
. Danke, @Chausser!main
AND festlegen und bei einer anderen Firewall mit dem Namen authentifiziert werdenadmin
(während Sie sich als Benutzer ausgeben), passiert etwas Seltsames: Das_security_admin
wirdUsernamePasswordToken
mit dem von Ihnen angegebenen Benutzer abgerufen, dh Sie werden "getrennt" Ihreadmin
Firewall. Irgendeine Idee, wie man das Token für die "Admin" -Firewall verwaltet?setToken(..)
unter derselben Zielfirewall anrufen oder noch nicht authentifiziert sind .Ich habe es endlich herausgefunden.
Nach der Benutzerregistrierung sollten Sie Zugriff auf eine Objektinstanz haben, die Sie in Ihrer Anbieterkonfiguration als Benutzerentität festgelegt haben. Die Lösung besteht darin, mit dieser Benutzerentität ein neues Token zu erstellen und es an den Sicherheitskontext zu übergeben. Hier ist ein Beispiel basierend auf meinem Setup:
RegistrationController.php:
Wo
main
ist der Name der Firewall für Ihre Anwendung (danke, @Joe). Das ist wirklich alles, was dazu gehört. Das System betrachtet Ihren Benutzer nun als den Benutzer, den er gerade erstellt hat, vollständig angemeldet.BEARBEITEN: Gemäß dem Kommentar von @ Miquel habe ich das Controller-Codebeispiel aktualisiert, um eine sinnvolle Standardrolle für einen neuen Benutzer aufzunehmen (obwohl dies natürlich an die spezifischen Anforderungen Ihrer Anwendung angepasst werden kann).
quelle
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
Wenn Sie ein UserInterface-Objekt haben (und dies sollte die meiste Zeit der Fall sein), möchten Sie möglicherweise die Funktion getRoles verwenden, die es für das letzte Argument implementiert. Wenn Sie also eine Funktion logUser erstellen, sollte dies folgendermaßen aussehen:
quelle
Ich verwende Symfony 2.2 und meine Erfahrung war etwas anders als die von Problematic. Dies ist also eine kombinierte Version aller Informationen aus dieser Frage sowie einiger meiner eigenen.
Ich denke, Joe ist falsch in Bezug auf den Wert des
$providerKey
dritten Parameters für denUsernamePasswordToken
Konstruktor. Es soll der Schlüssel eines Authentifizierungsanbieters (nicht eines Benutzers) sein. Es wird vom Authentifizierungssystem verwendet, um zwischen Token zu unterscheiden, die für verschiedene Anbieter erstellt wurden. Jeder Anbieter, von dem er abstammtUserAuthenticationProvider
, authentifiziert nur Token, deren Anbieterschlüssel mit seinem eigenen übereinstimmt. BeispielsweiseUsernamePasswordFormAuthenticationListener
setzt der Schlüssel des von ihm erstellten Tokens so, dass er mit dem des entsprechenden Tokens übereinstimmtDaoAuthenticationProvider
. Auf diese Weise verfügt eine einzelne Firewall über mehrere Anbieter von Benutzernamen und Kennwörtern, ohne dass diese aufeinander treten. Wir müssen daher einen Schlüssel auswählen, der nicht mit anderen Anbietern in Konflikt steht. Ich benutze'new_user'
.Ich habe einige Systeme in anderen Teilen meiner Anwendung, die vom Authentifizierungserfolgsereignis abhängen und die nicht durch einfaches Setzen des Tokens auf den Kontext ausgelöst werden. Ich musste das
EventDispatcher
aus dem Container holen und das Ereignis manuell auslösen. Ich habe mich dagegen entschieden, auch ein interaktives Anmeldeereignis auszulösen, da wir den Benutzer implizit authentifizieren und nicht als Antwort auf eine explizite Anmeldeanforderung.Beachten Sie, dass bei der Verwendung von
$this->get( .. )
davon ausgegangen wird, dass sich das Snippet in einer Controller-Methode befindet. Wenn Sie den Code an einer anderen Stelle verwenden, müssen Sie diese ändern, um sieContainerInterface::get( ... )
auf eine der Umgebung entsprechende Weise aufzurufen . Zufällig implementieren meine Benutzerentitäten,UserInterface
sodass ich sie direkt mit dem Token verwenden kann. Wenn dies bei Ihnen nicht der Fall ist, müssen Sie einen Weg finden, sie inUserInterface
Instanzen zu konvertieren .Dieser Code funktioniert, aber ich habe das Gefühl, dass er die Authentifizierungsarchitektur von Symfony hackt, anstatt damit zu arbeiten. Es wäre wahrscheinlich korrekter, einen neuen Authentifizierungsanbieter mit einer eigenen Token-Klasse zu implementieren, als den zu entführen
UsernamePasswordToken
. Die Verwendung eines geeigneten Anbieters würde auch bedeuten, dass die Ereignisse für Sie behandelt wurden.quelle
Falls jemand die gleiche Folgefrage hat, die mich dazu gebracht hat, hierher zurückzukehren:
Berufung
wirkt sich nur auf den Strom
security.context
für die verwendete Route aus.Das heißt, Sie können einen Benutzer nur über eine URL anmelden, die der Firewall unterliegt.
(Fügen Sie bei Bedarf eine Ausnahme für die Route hinzu -
IS_AUTHENTICATED_ANONYMOUSLY
)quelle
Mit Symfony 4.4 können Sie in Ihrer Controller-Methode einfach Folgendes tun (siehe Symfony-Dokumentation: https://symfony.com/doc/current/security/guard_authentication.html#manually-authenticating-a-user ):
Eine wichtige Sache, stellen Sie sicher, dass Ihre Firewall nicht eingestellt ist
lazy
. Wenn dies der Fall ist, wird das Token niemals in der Sitzung gespeichert und Sie werden niemals angemeldet.quelle
Wie hier bereits erwähnt, ist dieser schwer fassbare $ providerKey-Parameter in Wirklichkeit nichts anderes als der Name Ihrer Firewall-Regel, im folgenden Beispiel 'foobar'.
quelle
blablabla
es auch funktioniert, wenn ich eine beliebige Zeichenfolge beispielsweise als dritten Parameter an UsernamePasswordToken übergebe? Was bedeutet dieser Parameter?Ich habe alle Antworten hier ausprobiert und keine hat funktioniert. Die einzige Möglichkeit, meine Benutzer auf einem Controller zu authentifizieren, besteht darin, eine Unteranforderung zu stellen und dann umzuleiten. Hier ist mein Code, ich verwende Silex, aber Sie können ihn leicht an symfony2 anpassen:
quelle
Wenn Sie in Symfony Version 2.8.11 (wahrscheinlich für ältere und neuere Versionen) FOSUserBundle verwenden, gehen Sie wie folgt vor :
Keine Notwendigkeit, Ereignis auszulösen, wie ich in anderen Lösungen gesehen habe.
von FOS \ UserBundle \ Controller \ RegistrationController :: authenticateUser inspiriert
(aus der FOSUserBundle-Version von composer.json: "friendsofsymfony / user-bundle": "~ 1.3")
quelle