Bonjour les amis,

Je viens vers vous je butte sur un problème depuis maintenant plus de 3 jours.

J'essaye de comprendre comment fonctionne les Events dans symfony pour pouvoir l'utiliser avec Google Authentificator et je vous avouerai que je ne comprend pas encore grand choses.

Finalement après 3 jours d'efforts, je me suis décidé à prendre l'exemple que j'ai trouvé sur le web et a tanter de le modifier.

Problème quoi que je fasse, ça ne fonctionne.

Ce que je veux

Je souhaite que lorsque je me connecte à mon application, tous se passe comme il le faut.
Mais quand je demande l'url lié à la la route admin, Google Autentificator me demande de m'authentifier seulement et seulement si j'ai le rôle SUPER_ADMIN si je n'ai pas le role SUPER_ADMIN ça me renvoie une erreur 403

Ce que j'obtien

Actuellement, que je sois, SUPER_ADMIN ou USER à la connexion google me demande m'authentifier. De plus cela même si je n'ai pas demandé l'url lié à la route admin

Voici mon code pour le Subscriber

class TwoFactorAuthenticationSubscriber implements EventSubscriberInterface
{
    const ROLE_2FA_SUCCEED = "2FA_SUCCEED";

    const FIREWALL_NAME = "main";
    const ROUTE_FOR_2FA = "two-factor";

    /**
     * @var TokenStorageInterface
     */
    private $tokenStorage;

    /**
     * @var RouterInterface
     */
    private $router;

    /**
     * TwoFactorAuthenticationSubscriber constructor.
     * @param TokenStorageInterface $tokenStorage
     * @param RouterInterface $router
     */
    public function __construct(TokenStorageInterface $tokenStorage, RouterInterface $router)
    {
        $this->tokenStorage = $tokenStorage;
        $this->router = $router;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        if (!$event->isMasterRequest()) {
            return;
        }

        if (in_array($event->getRequest()->attributes->get('_route'), ["admin", self::ROUTE_FOR_2FA])) {
            return;
        }

        if (($currentToken = $this->tokenStorage->getToken()) && $currentToken instanceof PostAuthenticationGuardToken) {
            if ($currentToken->getProviderKey() === self::FIREWALL_NAME) {
                if (!$this->hasRole($currentToken, self::ROLE_2FA_SUCCEED)) {
                    $response = new RedirectResponse($this->router->generate(self::ROUTE_FOR_2FA));
                    $event->setResponse($response);
                }
            }
        }
    }

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::REQUEST => ['onKernelRequest', -10],
        ];
    }

    private function hasRole(TokenInterface $token, string $role): bool
    {
        foreach ($token->getRoles() as $userRole) {
            if ($userRole->getRole() === $role) {
                return true;
            }
        }
        return false;
    }
}

Et voici mon code sur controller

class TwoFactorAuthenticationController extends AbstractController
{
    /**
     * @Route("/two-factor", name="two-factor")
     * @param Request $request
     * @param TokenStorageInterface $tokenStorage
     * @param SessionInterface $session
     * @param EntityManagerInterface $entityManager
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
     * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
     * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
     */
    public function twoFactorAction(Request $request, TokenStorageInterface $tokenStorage, SessionInterface $session,
                                    EntityManagerInterface $entityManager)
    {
        $form = $this->createForm(GoogleAuthenticatorType::class);

        $form->handleRequest($request);
        $google2fa = new Google2FA();

        $svg = null;

        // Ici je met la condition de vérification du rôle de l'utilisateur

        $userCurrent = $this->getUser(); 

            /** @var User $user */
            $user = $this->getUser();
            if (!$user->getGoogleAuthenticatorSecret()) {
                if ($session->get('2fa_secret')) {
                    $secret = $session->get('2fa_secret');
                } else {
                    $secret = $google2fa->generateSecretKey();
                    $request->getSession()->set('2fa_secret', $secret);
                }

                $svg = $this->generateSvgForUser($google2fa, $user, $secret);
            } else {
                $secret = $user->getGoogleAuthenticatorSecret();
            }

            if ($form->isSubmitted() && $form->isValid()) {
                $code = $form->getData()["code"];
                $codeIsValid = $google2fa->verifyKey($secret, $code, 4);
                if ($codeIsValid) {
                    if (!$user->getGoogleAuthenticatorSecret()) {
                        $user->setGoogleAuthenticatorSecret($secret);
                        $entityManager->persist($user);
                        $entityManager->flush();
                    }

                    $this->addRoleTwoFA($tokenStorage, $session);

                    return $this->redirectToRoute("admin");
                }
                $this->addFlash("error", "Invalid verification code");
            }

            return $this->render("security/two-factor.html.twig", [
                "svg" => $svg,
                "form" => $form->createView(),
            ]);
    }

    private function generateSvgForUser(Google2FA $google2FA, User $user, string $secret): string
    {
        $g2faUrl = $google2FA->getQRCodeUrl(
            "Uwandzani.com",
            $user->getUsername(),
            $secret
        );

        $writer = new Writer(
            new ImageRenderer(
                new RendererStyle(400),
                new SvgImageBackEnd() // can also user new ImagickImageBackEnd() in order to generate png
            )
        );

        return $writer->writeString($g2faUrl);
    }

    private function addRoleTwoFA(TokenStorageInterface $tokenStorage, SessionInterface $session): void
    {
        /** @var PostAuthenticationGuardToken $currentToken */
        $currentToken = $tokenStorage->getToken();
        $roles = array_merge($currentToken->getRoles(), [TwoFactorAuthenticationSubscriber::ROLE_2FA_SUCCEED]);
        $newToken = new PostAuthenticationGuardToken($currentToken->getUser(), $currentToken->getProviderKey(), $roles);
        $tokenStorage->setToken($newToken);
        $session->set('_security_' . $currentToken->getProviderKey(), serialize($newToken));
    }
}

Aucune réponse