Partage
  • Partager sur Facebook
  • Partager sur Twitter

mon Subcriber n'est pas appelé sur un évènement.

Symfony 5.3.

Sujet résolu
    25 octobre 2021 à 20:14:08

    Bonjour, je suis actuellement sur mon premier gros projet sur SYMFONY 5.3 j'ai créer mon Authenticator via le Maker qui fonctionne bien.

    À partir de là j'ai voulu créer un subscriber (toujours via le Maker) afin de pouvoir gérer les erreurs d'authentification, mais c'est de là que vient mon problème:

    Mon subscriber et abonné à 3 évènements  :   

    1.LoginFailureEvent

    2.LoginSuccessEven

    3.KernelEvents::REQUEST (pour tester)

    Je vais donc sur la page de mon formulaire de Login je vois que mon premier Evènement KernelEvents::REQUEST fonctionne  avec un (dump($event)).

    Ensuite je tente de me connecter avec une bonne adresse email et un bon mot de passe, une fois connecté je vois que mon évènement LoginSuccessEvent fonctionne avec un (dump($event)).

    je finis donc par tenter de me connecter a mon Formulaire de login avec une mauvaise adresse email et un mauvais mot de passe et là rien.. mon LoginFailureEvent ne fonctionne pas  je ne comprend pas pourquoi. j'ai cherché sur le net et dans la doc de Symfony mais rien de plus que ce que je fais déjà ..

    -J'ai essayer la fonction dd($event) à la place de dump($event) rien n'a changé .

    - J'ai lancé la commande :

    bin/console debug:event-dispatcher LoginFailureEvent

    qui m'a renvoyer :

     ------- ---------------------------------------------------------------- ---------- 
      Order   Callable                                                         Priority  
     ------- ---------------------------------------------------------------- ----------
      #1      App\EventSubscriber\AuthenticationSubscriber::onLoginFailure()   0
     ------- ---------------------------------------------------------------- ----------


     SecuritySubscriber.php:

    <?php
    
    
    namespace App\EventSubscriber;
    
    use Symfony\Component\HttpKernel\KernelEvents;
    use Symfony\Component\HttpKernel\Event\RequestEvent;
    use Symfony\Component\Security\Http\Event\LoginFailureEvent;
    use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    
    
    
    class SecuritySubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents() :array
        {
            return [
                LoginFailureEvent::class => 'onLoginFailure',
                LoginSuccessEvent::class => 'onLoginSuccess',
                KernelEvents::REQUEST => 'KernelRequest',
                
                
            ];
            
        }
    
        public function onLoginFailure(LoginFailureEvent $event){
              dump($event);
        }
    
        public function onLoginSuccess(LoginSuccessEvent $event){
            dump($event);
      }
    
        public function KernelRequest(RequestEvent $event){
        //dump($event);
    }
      
    
    }
    





    UserAuthenticator.php:

    <?php
    
    namespace App\Security;
    
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Security;
    use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
    use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
    use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
    use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
    use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
    use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
    use Symfony\Component\Security\Http\Util\TargetPathTrait;
    
    class UserAuthenticator extends AbstractLoginFormAuthenticator
    {
        use TargetPathTrait;
    
        public const LOGIN_ROUTE = 'app_login';
    
        private UrlGeneratorInterface $urlGenerator;
    
        public function __construct(UrlGeneratorInterface $urlGenerator)
        {
            $this->urlGenerator = $urlGenerator;
        }
    
        public function authenticate(Request $request): PassportInterface
        {
            $email = $request->request->get('email', '');
    
            $request->getSession()->set(Security::LAST_USERNAME, $email);
    
            return new Passport(
                new UserBadge($email),
                new PasswordCredentials($request->request->get('password', '')),
                [
                    new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
                ]
            );
    
        }
    
        public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
        {
            if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
                return new RedirectResponse($targetPath);
            }
    
            // For example:
            return new RedirectResponse($this->urlGenerator->generate('app_registration'));
            //throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
        }
    
        protected function getLoginUrl(Request $request): string
        {
            
            return $this->urlGenerator->generate(self::LOGIN_ROUTE);
            dump($request);
        }
    }
    




    SecurityController.php:

    <?php 
    
    
    
    namespace App\Controller;
    
    use App\Entity\User;
    use DateTimeImmutable;
    use App\Form\RegistrationType;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Annotation\Route;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
    use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
    
    
    class SecurityController extends AbstractController {
    
        /**
         * @Route("/test", name="test")
         */
        public function test(Request $request, Response $response){
           
        
          
    
          return $this->render('test.html.twig');
          dump($response);
          
    
        }
    
        /**
         * @Route("/Connexion", name="app_login")
         */
        public function login(AuthenticationUtils $authenticationUtils): Response
        {
            // if ($this->getUser()) {
            //     return $this->redirectToRoute('target_path');
            // }
    
            // get the login error if there is one
            $error = $authenticationUtils->getLastAuthenticationError();
            
            // last username entered by the user
            $lastUsername = $authenticationUtils->getLastUsername();
            
            
            return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
        }
    
        /**
         * @Route("/Déconnexion", name="app_logout")
         */
        public function logout(): void
        {
            throw new \LogicException('');
        }
    
        /**
         * @Route("/Inscription", name="app_registration")
         */
        public function registration(EntityManagerInterface $manager, Request $request, UserPasswordHasherInterface $passwordEncoder): Response
        {
            $user = new User;
            $registrationForm = $this->createForm(RegistrationType::class, $user);
            $registrationForm->handleRequest($request);
            if($registrationForm->isSubmitted() && $registrationForm->isValid()){
               
               $plainPassword = $registrationForm->getData()->getPassword();
               $user->setPassword($passwordEncoder->hashPassword($user, $plainPassword));
               $user->setCreatedAt( new \DateTimeImmutable('NOW'));
               $user->setRoles($user->getRoles());
               $manager->persist($user);
               $manager->flush();
            }
           
            return $this->render('security/registration.html.twig',
            ['registrationForm' => $registrationForm->createView()]);
        }
    
    
    
    }





    security.yaml:

    security:
        # https://symfony.com/doc/current/security/authenticator_manager.html
        enable_authenticator_manager: true
        # https://symfony.com/doc/current/security.html#c-hashing-passwords
        password_hashers:
            Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
            App\Entity\User:
                algorithm: auto
    
        # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
        providers:
            # used to reload user from session & other features (e.g. switch_user)
            app_user_provider:
                entity:
                    class: App\Entity\User
                    property: email
        firewalls:
            dev:
                pattern: ^/(_(profiler|wdt)|css|images|js)/
                security: false
            main:
                lazy: true
                provider: app_user_provider
                custom_authenticator: App\Security\UserAuthenticator
                logout:
                    path: app_logout
                    # where to redirect after logout
                    # target: app_any_route
                
    
                # activate different ways to authenticate
                # https://symfony.com/doc/current/security.html#firewalls-authentication
    
                # https://symfony.com/doc/current/security/impersonating_user.html
                # switch_user: true
    
        # Easy way to control access for large sections of your site
        # Note: Only the *first* access control that matches will be used
        access_control:
            # - { path: ^/admin, roles: ROLE_ADMIN }
            # - { path: ^/profile, roles: ROLE_USER }
    




    Services.yaml:

    # This file is the entry point to configure your own services.
    # Files in the packages/ subdirectory configure your dependencies.
    
    # Put parameters here that don't need to change on each machine where the app is deployed
    # https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
    parameters:
    
    services:
    
        # default configuration for services in *this* file
        _defaults:
            autowire: true      # Automatically injects dependencies in your services.
            autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        
        # makes classes in src/ available to be used as services
        # this creates a service per class whose id is the fully-qualified class name
        App\:
            resource: '../src/'
            exclude:
                - '../src/DependencyInjection/'
                - '../src/Entity/'
                - '../src/Kernel.php'
                - '../src/Tests/'
    
        # add more service definitions when explicit configuration is needed
        # please note that last definitions always *replace* previous ones
        
        
    







    • Partager sur Facebook
    • Partager sur Twitter

    mon Subcriber n'est pas appelé sur un évènement.

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown