you must create custom authorization and exceptions.
example:
config/packages/security.yaml
security:
enable_authenticator_manager: true
...
providers:
...
firewalls:
...
client:
pattern: ^/
custom_authenticators:
- App\Security\ClientLoginFormAuthenticator
logout:
path: store.account.logout
target: store.home
access_control:
...
src/Security/ClientLoginFormAuthenticator.php
<?php
declare(strict_types=1);
namespace App\Security;
use App\Repository\UserRepository;
use App\Security\Exception\CustomException;
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\Exception\BadCredentialsException;
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 function in_array;
class ClientLoginFormAuthenticator extends AbstractLoginFormAuthenticator
{
private const LOGIN_ROUTE = 'store.account.login';
public function __construct(private UserRepository $userRepository, private UrlGeneratorInterface $urlGenerator)
{}
public function supports(Request $request): bool
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function authenticate(Request $request): Passport
{
$password = $request->request->get('_password');
$username = $request->request->get('_username');
$csrfToken = $request->request->get('_csrf_token');
return new Passport(
new UserBadge($username, function ($userIdentifier) {
$user = $this->userRepository->findOneBy(['email' => $userIdentifier]);
if ($user && in_array('ROLE_CLIENT', $user->getRoles(), true)) {
return $user;
}
//next condition
if($user && $user->getEmail() === 'superadmin@example.com') {
throw new CustomException();
}
throw new BadCredentialsException(); //default exception
}),
new PasswordCredentials($password),
[new CsrfTokenBadge('authenticate', $csrfToken)]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
src/Security/Exception/CustomException.php
<?php
namespace App\Security\Exception;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class CustomException extends AuthenticationException
{
/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return 'My Message.';
}
}
It works for me! :) Good luck!