Use the firewall event dispatcher
This commit is contained in:
parent
95edc806a1
commit
7ef6a7ab03
@ -218,9 +218,8 @@ class RememberMeFactory implements SecurityFactoryInterface, AuthenticatorFactor
|
||||
{
|
||||
$container
|
||||
->setDefinition('security.listener.remember_me.'.$id, new ChildDefinition('security.listener.remember_me'))
|
||||
->addTag('kernel.event_subscriber')
|
||||
->addTag('kernel.event_subscriber', ['dispatcher' => 'security.event_dispatcher.'.$id])
|
||||
->replaceArgument(0, new Reference($rememberMeServicesId))
|
||||
->replaceArgument(1, $id)
|
||||
;
|
||||
|
||||
$container
|
||||
|
@ -156,8 +156,11 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
|
||||
->replaceArgument(2, $this->statelessFirewallKeys);
|
||||
|
||||
if ($this->authenticatorManagerEnabled) {
|
||||
$container->getDefinition(SessionListener::class)
|
||||
->replaceArgument(1, $this->statelessFirewallKeys);
|
||||
foreach ($this->statelessFirewallKeys as $statelessFirewallId) {
|
||||
$container
|
||||
->setDefinition('security.listener.session.'.$statelessFirewallId, new ChildDefinition('security.listener.session'))
|
||||
->addTag('kernel.event_subscriber', ['dispatcher' => 'security.event_dispatcher.'.$statelessFirewallId]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($config['encoders']) {
|
||||
@ -446,6 +449,7 @@ class SecurityExtension extends Extension implements PrependExtensionInterface
|
||||
$container
|
||||
->setDefinition($managerId = 'security.authenticator.manager.'.$id, new ChildDefinition('security.authenticator.manager'))
|
||||
->replaceArgument(0, $authenticators)
|
||||
->replaceArgument(2, new Reference($firewallEventDispatcherId))
|
||||
->replaceArgument(3, $id)
|
||||
->addTag('monolog.logger', ['channel' => 'security'])
|
||||
;
|
||||
|
@ -12,7 +12,10 @@
|
||||
namespace Symfony\Bundle\SecurityBundle\EventListener;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Security\Http\Event\LoginFailureEvent;
|
||||
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
|
||||
use Symfony\Component\Security\Http\Event\LogoutEvent;
|
||||
use Symfony\Component\Security\Http\Event\VerifyAuthenticatorCredentialsEvent;
|
||||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
@ -34,6 +37,9 @@ class FirewallEventBubblingListener implements EventSubscriberInterface
|
||||
{
|
||||
return [
|
||||
LogoutEvent::class => 'bubbleEvent',
|
||||
LoginFailureEvent::class => 'bubbleEvent',
|
||||
LoginSuccessEvent::class => 'bubbleEvent',
|
||||
VerifyAuthenticatorCredentialsEvent::class => 'bubbleEvent',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,9 @@
|
||||
<argument type="service" id="Symfony\Component\Security\Core\User\UserCheckerInterface" />
|
||||
</service>
|
||||
|
||||
<service id="security.listener.session" class="Symfony\Component\Security\Http\EventListener\SessionStrategyListener">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
<service id="security.listener.session"
|
||||
class="Symfony\Component\Security\Http\EventListener\SessionStrategyListener"
|
||||
abstract="true">
|
||||
<argument type="service" id="security.authentication.session_strategy" />
|
||||
<argument type="abstract">stateless firewall keys</argument>
|
||||
</service>
|
||||
|
@ -26,26 +26,29 @@ use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
|
||||
class RememberMeListener implements EventSubscriberInterface
|
||||
{
|
||||
private $rememberMeServices;
|
||||
private $providerKey;
|
||||
private $logger;
|
||||
|
||||
public function __construct(RememberMeServicesInterface $rememberMeServices, string $providerKey, ?LoggerInterface $logger = null)
|
||||
public function __construct(RememberMeServicesInterface $rememberMeServices, ?LoggerInterface $logger = null)
|
||||
{
|
||||
$this->rememberMeServices = $rememberMeServices;
|
||||
$this->providerKey = $providerKey;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
|
||||
public function onSuccessfulLogin(LoginSuccessEvent $event): void
|
||||
{
|
||||
if (!$this->isRememberMeEnabled($event->getProviderKey(), $event->getAuthenticator())) {
|
||||
$authenticator = $event->getAuthenticator();
|
||||
if (!$authenticator instanceof RememberMeAuthenticatorInterface || !$authenticator->supportsRememberMe()) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Remember me skipped: your authenticator does not support it.', ['authenticator' => \get_class($authenticator)]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $event->getResponse()) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Remember me skipped: the authenticator did not set a success response.', ['authenticator' => \get_class($event->getAuthenticator())]);
|
||||
$this->logger->debug('Remember me skipped: the authenticator did not set a success response.', ['authenticator' => \get_class($authenticator)]);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -56,31 +59,9 @@ class RememberMeListener implements EventSubscriberInterface
|
||||
|
||||
public function onFailedLogin(LoginFailureEvent $event): void
|
||||
{
|
||||
if (!$this->isRememberMeEnabled($event->getProviderKey())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->rememberMeServices->loginFail($event->getRequest(), $event->getException());
|
||||
}
|
||||
|
||||
private function isRememberMeEnabled(string $providerKey, ?AuthenticatorInterface $authenticator = null): bool
|
||||
{
|
||||
if ($providerKey !== $this->providerKey) {
|
||||
// This listener is created for a different firewall.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null !== $authenticator && (!$authenticator instanceof RememberMeAuthenticatorInterface || !$authenticator->supportsRememberMe())) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Remember me skipped: your authenticator does not support it.', ['authenticator' => \get_class($authenticator)]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
|
@ -28,21 +28,18 @@ use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterfa
|
||||
class SessionStrategyListener implements EventSubscriberInterface
|
||||
{
|
||||
private $sessionAuthenticationStrategy;
|
||||
private $statelessProviderKeys;
|
||||
|
||||
public function __construct(SessionAuthenticationStrategyInterface $sessionAuthenticationStrategy, array $statelessProviderKeys = [])
|
||||
public function __construct(SessionAuthenticationStrategyInterface $sessionAuthenticationStrategy)
|
||||
{
|
||||
$this->sessionAuthenticationStrategy = $sessionAuthenticationStrategy;
|
||||
$this->statelessProviderKeys = $statelessProviderKeys;
|
||||
}
|
||||
|
||||
public function onSuccessfulLogin(LoginSuccessEvent $event): void
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
$token = $event->getAuthenticatedToken();
|
||||
$providerKey = $event->getProviderKey();
|
||||
|
||||
if (!$request->hasSession() || !$request->hasPreviousSession() || \in_array($providerKey, $this->statelessProviderKeys, true)) {
|
||||
if (!$request->hasSession() || !$request->hasPreviousSession()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user