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:
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 LoginSuccessEventfonctionne 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 dedump($event) rien n'a changé .
<?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
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.