Symfony 4.0
Este proceso no ha cambiado de Symfony 3 a 4, pero aquí hay un ejemplo utilizando el AbstractController recomendado recientemente. Tanto las security.token_storage
y los session
servicios están registrados en la matriz getSubscribedServices
método para que no tenga que añadir los de su controlador.
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
A partir de Symfony 2.6 security.context
está obsoleto en favor de security.token_storage
. El controlador ahora puede ser simplemente:
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));
}
}
Si bien esto está obsoleto, aún puede usarlo, security.context
ya que se ha hecho para ser compatible con versiones anteriores. Solo prepárate para actualizarlo para Symfony 3
Puede leer más sobre los cambios 2.6 por seguridad aquí: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md
Symfony 2.3.x
Para lograr esto en Symfony 2.3, ya no puedes simplemente configurar el token en el contexto de seguridad. También debe guardar el token en la sesión.
Suponiendo un archivo de seguridad con un firewall como:
// app/config/security.yml
security:
firewalls:
main:
//firewall settings here
Y una acción de controlador similar también:
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
}
}
Para la creación del token, querrá crear un UsernamePasswordToken
, Esto acepta 4 parámetros: Entidad de usuario, Credenciales de usuario, Nombre del firewall, Roles de usuario. No es necesario que proporcione las credenciales de usuario para que el token sea válido.
No estoy 100% seguro de que security.context
sea necesario configurar el token en el si solo va a redireccionar de inmediato. Pero no parece doler, así que lo dejé.
Luego, la parte importante, configurar la variable de sesión. La convención de nomenclatura de variables es _security_
seguida por el nombre de su firewall, en este caso main
haciendo_security_main
$this->get('session')->set('_security_main', serialize($token));
. ¡Gracias, @Chausser!main
Y estás autenticado con otro cortafuegos llamadoadmin
(ya que te estás haciendo pasar por el usuario), sucede algo extraño:_security_admin
obtiene elUsernamePasswordToken
con el usuario que proporcionaste, es decir, te "desconecta" de suadmin
firewall. ¿Alguna idea de cómo mantener el token para el firewall "admin"?setToken(..)
bajo el mismo firewall de destino o sin estar autenticado aún.Descubrí este, finalmente.
Después del registro de usuario, debe tener acceso a una instancia de objeto de lo que haya establecido como su entidad de usuario en la configuración de su proveedor. La solución es crear un nuevo token con esa entidad de usuario y pasarlo al contexto de seguridad. Aquí hay un ejemplo basado en mi configuración:
RegistrationController.php:
¿Dónde
main
está el nombre del firewall para su aplicación (gracias, @Joe). Eso es realmente todo lo que hay que hacer; el sistema ahora considera que su usuario ha iniciado sesión como el usuario que acaba de crear.EDITAR: Según el comentario de @ Miquel, he actualizado la muestra de código del controlador para incluir un rol predeterminado sensible para un nuevo usuario (aunque obviamente esto se puede ajustar de acuerdo con las necesidades específicas de su aplicación).
fuente
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
Si tiene un objeto UserInterface (y ese debería ser el caso la mayor parte del tiempo), es posible que desee utilizar la función getRoles que implementa para el último argumento. Entonces, si crea una función logUser, debería verse así:
fuente
Estoy usando Symfony 2.2 y mi experiencia fue ligeramente diferente a la de Problematic , por lo que esta es una versión combinada de toda la información de esta pregunta más parte de la mía.
Creo que Joe está equivocado sobre el valor de
$providerKey
, el tercer parámetro delUsernamePasswordToken
constructor. Se supone que es la clave de un proveedor de autenticación (no de un usuario). Es utilizado por el sistema de autenticación para distinguir entre tokens creados para diferentes proveedores. Cualquier proveedor que descienda deUserAuthenticationProvider
solo autenticará tokens cuya clave de proveedor coincida con la suya. Por ejemplo,UsernamePasswordFormAuthenticationListener
establece la clave del token que crea para que coincida con la de su correspondienteDaoAuthenticationProvider
. Eso permite que un solo firewall tenga múltiples proveedores de nombre de usuario + contraseña sin que se pisen entre sí. Por lo tanto, debemos elegir una clave que no entre en conflicto con ningún otro proveedor. yo suelo'new_user'
.Tengo algunos sistemas en otras partes de mi aplicación que dependen del evento de éxito de la autenticación , y eso no se activa simplemente configurando el token en el contexto. Tuve que sacar el
EventDispatcher
del contenedor y disparar el evento manualmente. Decidí no activar también un evento de inicio de sesión interactivo porque estamos autenticando al usuario implícitamente, no en respuesta a una solicitud de inicio de sesión explícita.Tenga en cuenta que el uso de
$this->get( .. )
asume que el fragmento está en un método de controlador. Si está utilizando el código en otro lugar, tendrá que cambiarlos para llamarContainerInterface::get( ... )
de una manera adecuada al entorno. Como sucede, mis entidades de usuario implementanUserInterface
para que pueda usarlas directamente con el token. Si el tuyo no es así, tendrás que encontrar una manera de convertirlos aUserInterface
instancias.Ese código funciona, pero siento que está pirateando la arquitectura de autenticación de Symfony en lugar de trabajar con ella. Probablemente sería más correcto implementar un nuevo proveedor de autenticación con su propia clase de token en lugar de secuestrar el
UsernamePasswordToken
. Además, usar un proveedor adecuado significaría que los eventos se manejaron por usted.fuente
En caso de que alguien tenga la misma pregunta de seguimiento que me hizo volver aquí:
Vocación
solo afecta la corriente
security.context
de la ruta utilizada.Es decir, solo puede iniciar sesión un usuario desde una URL dentro del control del firewall.
(Agregue una excepción para la ruta si es necesario -
IS_AUTHENTICATED_ANONYMOUSLY
)fuente
Con Symfony 4.4, simplemente puede hacer lo siguiente en su método de controlador (consulte la documentación de Symfony: https://symfony.com/doc/current/security/guard_authentication.html#manually-authenticating-a-user ):
Una cosa importante, asegúrese de que su firewall no esté configurado en
lazy
. Si es así, el token nunca se almacenará en la sesión y nunca iniciará sesión.fuente
Como Problematic ya mencionó aquí, este elusivo parámetro $ providerKey no es en realidad más que el nombre de su regla de firewall, 'foobar' en el caso del ejemplo siguiente.
fuente
blablabla
como tercer parámetro a UsernamePasswordToken, también funcionará? ¿Qué significa este parámetro?Probé todas las respuestas aquí y ninguna funcionó. La única forma en que podría autenticar a mis usuarios en un controlador es haciendo una subconsulta y luego redireccionando. Aquí está mi código, estoy usando silex pero puedes adaptarlo fácilmente a Symfony2:
fuente
En Symfony versión 2.8.11 (probablemente funciona para versiones más antiguas y más nuevas), si usa FOSUserBundle simplemente haga esto:
No es necesario enviar eventos como he visto en otras soluciones.
inspirado en FOS \ UserBundle \ Controller \ RegistrationController :: authenticateUser
(de composer.json FOSUserBundle versión: "friendsofsymfony / user-bundle": "~ 1.3")
fuente