0

I created custom authenticator:

<?php

namespace App\Security;

use App\Service\CaptchaService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;

class MainAuthenticator extends AbstractAuthenticator
{
    public function __construct(
        private CaptchaService $captchaService,
        private EntityManagerInterface $entityManager
    ){}

    public function supports(Request $request): ?bool
    {
        return 'app_login' === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function authenticate(Request $request): Passport
    {
        $captcha = $request->request->get('g-recaptcha-response');
        $captchaIsValid = $this->captchaService->valid($captcha);

        if (!$captchaIsValid) {
            throw new CustomUserMessageAuthenticationException('Captcha');
        }

        return new SelfValidatingPassport(new UserBadge($request->request->get('_username')));
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        return null;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
    {
        return null;
    }
}

The service captcha is correct if I select checkbox or not return true or false: $this->captchaService->valid($captcha);

Exception does not stop authentication, and user is log in.

In older versions of symfony I extend class AbstractFormLoginAuthenticator and use method getCredentials:

public function getCredentials(Request $request)
    {
        $captcha = $request->request->get('g-recaptcha-response');
        $captchaIsValid = $this->captchaService->valid($captcha);

        if (!$captchaIsValid) {
            throw new CustomUserMessageAuthenticationException('Invalid credentials.');
        }

        $credentials = [
            'email' => $request->request->get('email'),
            'password' => $request->request->get('password'),
        ];

        return $credentials;
    }

Above example of symfony 4 works.

How to do the same in a symfony 6? how to return error from authentication method?

Mariusz
  • 13
  • 3
  • Look at https://github.com/karser/KarserRecaptcha3Bundle It is good to avoid user friction and still do the job – ThomasL Mar 01 '23 at 10:36

0 Answers0