Disable automatic login after registration with Symfony FOSUserbundle

Using the latest Symfony and FOSUserbundle, after successfully registering a new user, the user is automatically registered. I want to prevent this. My reason is that only a special user should be able to register new users.

I think I need to override registerAction in the RegisterController package, but I do not know how to do this.

I tried: http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html but it seems to be deprecated and this method is not created by the user.

Any hints appreciated.

Edit:

I found out that I did not create the child package correctly. I also had to create my own EventListener. It works now when I overwrite the FOSUserEvents::REGISTRATION_SUCCESS event.

The strange thing is that when I use the FOSUserEvents::REGISTRATION_COMPLETED event, both events, my package and FOSUserbundle are dispatched, so that the user is redirected to the correct site, but logged in as a new user.

Edit 2:

So this is in my listener:

 public static function getSubscribedEvents() { return array( FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess', FOSUserEvents::REGISTRATION_COMPLETED => 'onRegistrationCompleted', ); } public function onRegistrationSuccess(FormEvent $event) { $url = $this->router->generate('admin'); $event->setResponse(new RedirectResponse($url)); } public function onRegistrationCompleted(FilterUserResponseEvent $event) { } 

I set the redirect in the REGISTRATION_SUCCESS event, and REGISTRATION_COMPLETED empty. With a debugger, I can verify that my own listener event is triggered, but the original event is also fired.

+6
source share
4 answers

You can solve this problem with the Listener package, In fos, it authenticates the user after registration.

file: friendsofsymfony/user-bundle/EventListener/AuthenticationListener.php

class: FOS\UserBundle\EventListener\AuthenticationListener

If you check this class, you will see that it is tracking the REGISTRATION_COMPLETED Event.

In the Authenticatiton Listener It dispatches an event after running the logInUser function. Therefore, you must log out of the user in your listener who signs "REGISTRATION IS COMPLETED."

you can check https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/controller_events.rst to record your listener for logout.

Note. This may not be a good way for a user to log in to each registration process, but if you use the simplest fosuserbundle method and the minimum size will be that if there is no yml configuration already, there is actually no yml conf direction in the code. Thus, this approach will be minimal. track.

  try { $this->loginManager->logInUser($this->firewallName, $event->getUser(), $event->getResponse()); $eventDispatcher->dispatch(FOSUserEvents::SECURITY_IMPLICIT_LOGIN, new UserEvent($event->getUser(), $event->getRequest())); } catch (AccountStatusException $ex) { // We simply do not authenticate users which do not pass the user // checker (not enabled, expired, etc.). } 
+1
source

EDIT: This method works on Symfony 3.3, I don't know if this works on lower versions.

The right way to do this is by creating a Compiler Pass .

You can also: redefine the service by adding a new service with the same name: fos_user.listener.authentication in the app / config.yml file or in the package configuration file and adding a new class to it, as I did below and add this

Here's how to override automatic logging when registering a new user using the compiler transfer technique.

Compiler transfer

 namespace arpa3\UserBundle\DependencyInjection; use arpa3\UserBundle\EventListener\AuthenticationListener; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; class OverrideServiceCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { $definition = $container->getDefinition('fos_user.listener.authentication'); $definition->setClass(AuthenticationListener::class); } } 

Service Override

 namespace arpa3\UserBundle\EventListener; use FOS\UserBundle\Event\FilterUserResponseEvent; use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\FOSUserEvents; use FOS\UserBundle\Security\LoginManagerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Core\Exception\AccountStatusException; class AuthenticationListener implements EventSubscriberInterface { /** * @var LoginManagerInterface */ private $loginManager; /** * @var string */ private $firewallName; /** * AuthenticationListener constructor. * * @param LoginManagerInterface $loginManager * @param string $firewallName */ public function __construct(LoginManagerInterface $loginManager, $firewallName) { $this->loginManager = $loginManager; $this->firewallName = $firewallName; } /** * {@inheritdoc} */ public static function getSubscribedEvents() { return array( // You can disable any of them or all of them as you want //FOSUserEvents::REGISTRATION_COMPLETED => 'authenticate', //FOSUserEvents::REGISTRATION_CONFIRMED => 'authenticate', //FOSUserEvents::RESETTING_RESET_COMPLETED => 'authenticate', ); } /** * @param FilterUserResponseEvent $event * @param string $eventName * @param EventDispatcherInterface $eventDispatcher */ public function authenticate(FilterUserResponseEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) { try { $this->loginManager->logInUser($this->firewallName, $event->getUser(), $event->getResponse()); $eventDispatcher->dispatch(FOSUserEvents::SECURITY_IMPLICIT_LOGIN, new UserEvent($event->getUser(), $event->getRequest())); } catch (AccountStatusException $ex) { // We simply do not authenticate users which do not pass the user // checker (not enabled, expired, etc.). } } } 

Register your Compiler Pass in your main package file

  namespace arpa3\UserBundle; use arpa3\UserBundle\DependencyInjection\OverrideServiceCompilerPass; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; class arpa3UserBundle extends Bundle { public function getParent () { return 'FOSUserBundle'; } /** * * This injects a Compiler Pass that is used to override the automatic login after registration of a new user * We have done this in order to disable the "by default" behaviour given that only admins can register users * and logging in into the newly created account automatically is just not a desired behaviour * * @param ContainerBuilder $container */ public function build ( ContainerBuilder $container ) { parent ::build( $container ); $container -> addCompilerPass( new OverrideServiceCompilerPass() ); } } 

There are other ways to override the authentication service on your config.yml, but the solution above is the cleanest and most service-friendly solution I have found.

+1
source

You are almost there since you said that your listeners are being called, but the order is wrong, so you need your listener to run to the default value To make this change

FOSUserEvents :: REGISTRATION_SUCCESS => 'OnRegistrationSuccess'

to

FOSUserEvents :: REGISTRATION_SUCCESS => ['OnRegistrationSuccess', - 10],

Note -10 , this changes the priority of the listener.

 class RegistrationSuccessEventListener implements EventSubscriberInterface{ private $router; public function __construct(UrlGeneratorInterface $router){ $this->router = $router; } public static function getSubscribedEvents() { //this will be called before return array( FOSUserEvents::REGISTRATION_SUCCESS => ['onUserRegistrationSuccess', -30], ); } /** * @param FormEvent $event * When the user registration is completed redirect * to the employee list page and avoid the automatic * mail sending and user authentication that happends * */ public function onUserRegistrationSuccess(FormEvent $event){ $url = $this->router->generate('employees_list'); $event->setResponse(new RedirectResponse($url)); } } 

I am using symfony 2.8 with the FOSBundle version

friendsofsymfony / user-bundle dev-master 1f97ccf Symfony FOSUserBundle

according to composer info output

0
source

In fact, there is no need to do any of this. The fos_user.listener.authentication service is removed from the container if use_authentication_listener is set to false.

See FOS\UserBundle\DependencyInjection\FOSUserExtension 74-76 in FOS\UserBundle\DependencyInjection\FOSUserExtension .

This information is also included in the FOS UserBundle Configuration document.

0
source

Source: https://habr.com/ru/post/1241139/


All Articles