[英]Symfony Security logout not clearing RememberMe token
将Symfony 4与security.yaml
一起使用,如下所示:
encoders:
App\Entity\User: sha256
providers:
public_users:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: ~
form_login:
login_path: login
remember_me: true
remember_me:
secret: "%kernel.secret%"
name: relevea_remember_me
lifetime: 864000
always_remember_me: false
remember_me_parameter: user_login[stayConnected]
logout:
path: logout
target: /about
invalidate_session: false
access_control:
- { path: ^/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
logout
操作不会清除RememberMe令牌。
我可以看到LogoutListener
( https://github.com/symfony/security/blob/master/Http/Firewall/LogoutListener.php )之后被称为RememberMeListener
( https://github.com/symfony/security/blob/master /Http/Firewall/RememberMeListener.php ),因此对于LogoutListener而言,令牌为null,并且不会清除任何内容:/
TraceableFirewallListener
的侦听器列表:
Symfony \\ Component \\ Security \\ Http \\ Firewall \\ ChannelListener Symfony \\ Component \\ Security \\ Http \\ Firewall \\ ContextListener Symfony \\ Component \\ Security \\ Http \\ Firewall \\ LogoutListener
Symfony \\ Component \\ Security \\ Http \\ Firewall \\ UsernamePasswordFormAuthenticationListener Symfony \\ Component \\ Security \\ Http \\ Firewall \\ RememberMeListener
Symfony \\ Component \\ Security \\ Http \\ Firewall \\ AnonymousAuthenticationListener Symfony \\ Component \\ Security \\ Http \\ Firewall \\ AccessListener
为什么注销侦听器先于其他侦听器?
您可以覆盖防火墙侦听器以调用注销侦听器,如下所示
security.firewall:
class: AppBundle\Security\FirewallListener
arguments:
- '@security.firewall.map'
- '@event_dispatcher'
- '@security.logout_url_generator'
tags:
- { name: kernel.event_subscriber }
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Http\Firewall\LogoutListener;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
class FirewallListener extends Firewall
{
private $map;
private $exceptionListeners;
private $logoutUrlGenerator;
private $dispatcher;
public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher, LogoutUrlGenerator $logoutUrlGenerator)
{
$this->map = $map;
$this->dispatcher = $dispatcher;
$this->exceptionListeners = new \SplObjectStorage();
$this->logoutUrlGenerator = $logoutUrlGenerator;
parent::__construct($map, $dispatcher);
}
/**
* {@inheritdoc}
*/
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
if ($this->map instanceof FirewallMap && $config = $this->map->getFirewallConfig($event->getRequest())) {
$this->logoutUrlGenerator->setCurrentFirewall($config->getName(), $config->getContext());
}
// register listeners for this firewall
list($listeners, $exceptionListener) = $this->map->getListeners($event->getRequest());
if (null !== $exceptionListener) {
$this->exceptionListeners[$event->getRequest()] = $exceptionListener;
$exceptionListener->register($this->dispatcher);
}
// initiate the listener chain
$logoutListener = null;
foreach ($listeners as $listener) {
if ($listener instanceof LogoutListener) {
$logoutListener = $listener;
continue;
}
$listener->handle($event);
if ($event->hasResponse()) {
break;
}
}
if ($logoutListener) {
$logoutListener->handle($event);
}
}
/**
* {@inheritdoc}
*/
public function onKernelFinishRequest(FinishRequestEvent $event)
{
if ($event->isMasterRequest()) {
$this->logoutUrlGenerator->setCurrentFirewall(null);
}
parent::onKernelFinishRequest($event);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.