Symfony 4.0
Ce processus n'a pas changé de symfony 3 à 4 mais voici un exemple utilisant le nouveau AbstractController recommandé. Les deuxsecurity.token_storage
session
services et les services sont enregistrés dans la getSubscribedServices
méthode parente , vous n'avez donc pas à les ajouter dans votre contrôleur.
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
À partir de symfony 2.6 security.context
est obsolète au profit de security.token_storage
. Le contrôleur peut maintenant être simplement:
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));
}
}
Bien que cela soit obsolète, vous pouvez toujours l'utiliser security.context
car il a été conçu pour être rétrocompatible. Soyez juste prêt à le mettre à jour pour Symfony 3
Vous pouvez en savoir plus sur les changements 2.6 pour la sécurité ici: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md
Symfony 2.3.x
Pour accomplir cela dans symfony 2.3, vous ne pouvez plus simplement définir le jeton dans le contexte de sécurité. Vous devez également enregistrer le jeton dans la session.
En supposant un fichier de sécurité avec un pare-feu comme:
// app/config/security.yml
security:
firewalls:
main:
//firewall settings here
Et une action de contrôleur similaire aussi:
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
}
}
Pour la création du jeton, vous voudrez créer un UsernamePasswordToken
, Cela accepte 4 paramètres: entité utilisateur, informations d'identification de l'utilisateur, nom du pare-feu, rôles d'utilisateur. Vous n'avez pas besoin de fournir les informations d'identification de l'utilisateur pour que le jeton soit valide.
Je ne suis pas sûr à 100% que la définition du jeton sur le security.context
soit nécessaire si vous allez simplement rediriger tout de suite. Mais cela ne semble pas faire mal, donc je l'ai laissé.
Ensuite, la partie importante, la définition de la variable de session. Les variables convention de nommage est _security_
suivi de votre nom pare - feu, dans ce cas , la main
prise_security_main
$this->get('session')->set('_security_main', serialize($token));
. Merci, @Chausser!main
ET que vous êtes authentifié avec un autre pare-feu nomméadmin
(car vous usurpez l'identité de l'utilisateur), une chose étrange se produit:_security_admin
obtient leUsernamePasswordToken
avec l'utilisateur que vous avez fourni, c'est-à-dire que vous êtes "déconnecté" de votreadmin
pare - feu. Une idée comment maintenir le jeton pour le pare-feu "admin"?setToken(..)
sous le même pare - feu cible ou sans être encore authentifié .J'ai finalement compris celui-ci.
Après l'enregistrement de l'utilisateur, vous devriez avoir accès à une instance d'objet de tout ce que vous avez défini comme entité utilisateur dans la configuration de votre fournisseur. La solution consiste à créer un nouveau jeton avec cette entité utilisateur et à le transmettre dans le contexte de sécurité. Voici un exemple basé sur ma configuration:
RegistrationController.php:
Où
main
est le nom du pare-feu de votre application (merci, @Joe). C'est vraiment tout ce qu'il y a à faire; le système considère désormais votre utilisateur entièrement connecté comme l'utilisateur qu'il vient de créer.EDIT: Selon le commentaire de @ Miquel, j'ai mis à jour l'exemple de code du contrôleur pour inclure un rôle par défaut raisonnable pour un nouvel utilisateur (bien que cela puisse évidemment être ajusté en fonction des besoins spécifiques de votre application).
la source
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
Si vous avez un objet UserInterface (et cela devrait être le cas la plupart du temps), vous souhaiterez peut-être utiliser la fonction getRoles qu'il implémente pour le dernier argument. Donc, si vous créez une fonction logUser, cela devrait ressembler à ça:
la source
J'utilise Symfony 2.2 et mon expérience était légèrement différente de celle de Problematic , c'est donc une version combinée de toutes les informations de cette question plus certaines des miennes.
Je pense que Joe se trompe sur la valeur de
$providerKey
, le troisième paramètre pour leUsernamePasswordToken
constructeur. C'est censé être la clé d'un fournisseur d'authentification (pas d'utilisateur). Il est utilisé par le système d'authentification pour distinguer les jetons créés pour différents fournisseurs. Tout fournisseur qui descend deUserAuthenticationProvider
n'authentifiera que les jetons dont la clé de fournisseur correspond à la sienne. Par exemple, leUsernamePasswordFormAuthenticationListener
définit la clé du jeton qu'il crée pour correspondre à celle de son correspondantDaoAuthenticationProvider
. Cela permet à un seul pare-feu d'avoir plusieurs fournisseurs de nom d'utilisateur et de mot de passe sans qu'ils se marient les uns les autres. Nous devons donc choisir une clé qui n'entrera en conflit avec aucun autre fournisseur. J'utilise'new_user'
.J'ai quelques systèmes dans d'autres parties de mon application qui dépendent de l' événement de réussite d'authentification , et qui ne sont pas déclenchés simplement en définissant le jeton sur le contexte. Je devais récupérer le
EventDispatcher
contenu du conteneur et déclencher l'événement manuellement. J'ai décidé de ne pas déclencher également un événement de connexion interactif car nous authentifions l'utilisateur implicitement, et non en réponse à une demande de connexion explicite.Notez que l'utilisation de
$this->get( .. )
suppose que l'extrait de code est dans une méthode de contrôleur. Si vous utilisez le code ailleurs, vous devrez les modifier pour les appelerContainerInterface::get( ... )
d'une manière appropriée à l'environnement. En l'occurrence, mes entités utilisateur sont implémentéesUserInterface
pour que je puisse les utiliser directement avec le jeton. Si ce n'est pas le cas, vous devrez trouver un moyen de les convertir enUserInterface
instances.Ce code fonctionne, mais j'ai l'impression qu'il pirate l'architecture d'authentification de Symfony plutôt que de travailler avec. Il serait probablement plus correct d' implémenter un nouveau fournisseur d'authentification avec sa propre classe de jeton plutôt que de détourner le fichier
UsernamePasswordToken
. En outre, l'utilisation d'un fournisseur approprié signifierait que les événements ont été gérés pour vous.la source
Au cas où quelqu'un aurait la même question de suivi qui m'a fait revenir ici:
Appel
affecte uniquement le courant
security.context
de l'itinéraire utilisé.C'est-à-dire que vous ne pouvez connecter un utilisateur qu'à partir d'une URL sous le contrôle du pare-feu.
(Ajoutez une exception pour l'itinéraire si nécessaire -
IS_AUTHENTICATED_ANONYMOUSLY
)la source
Avec Symfony 4.4, vous pouvez simplement faire ce qui suit dans votre méthode de contrôleur (voir dans la documentation Symfony: https://symfony.com/doc/current/security/guard_authentication.html#manually-authenticating-a-user ):
Une chose importante, assurez-vous que votre pare-feu n'est pas défini sur
lazy
. Si tel est le cas, le jeton ne sera jamais stocké dans la session et vous ne serez jamais connecté.la source
Comme Problematic ici déjà mentionné, ce paramètre insaisissable $ providerKey n'est en réalité rien de plus que le nom de votre règle de pare-feu, 'foobar' dans le cas de l'exemple ci-dessous.
la source
blablabla
tant que troisième paramètre à UsernamePasswordToken, cela fonctionnera également? que signifie ce paramètre?J'ai essayé toutes les réponses ici et aucune n'a fonctionné. La seule façon dont je pourrais authentifier mes utilisateurs sur un contrôleur est de faire une sous-demande puis de rediriger. Voici mon code, j'utilise silex mais vous pouvez facilement l'adapter à symfony2:
la source
Sur Symfony version 2.8.11 (fonctionnant probablement pour les versions plus anciennes et plus récentes), si vous utilisez FOSUserBundle, faites simplement ceci:
Pas besoin de répartir l'événement comme je l'ai vu dans d'autres solutions.
inspiré de FOS \ UserBundle \ Controller \ RegistrationController :: authenticateUser
(à partir de la version composer.json FOSUserBundle: "friendsofsymfony / user-bundle": "~ 1.3")
la source