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?