[英]Symfony Security logout not clearing RememberMe token
Using Symfony 4 with a security.yaml
like this: 将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
operation is not clearing the rememberMe token. logout
操作不会清除RememberMe令牌。
I can see that LogoutListener
( https://github.com/symfony/security/blob/master/Http/Firewall/LogoutListener.php ) is called after RememberMeListener
( https://github.com/symfony/security/blob/master/Http/Firewall/RememberMeListener.php ) so for LogoutListener, the token is null and nothing is cleared :/ 我可以看到
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,并且不会清除任何内容:/
The listeners list from TraceableFirewallListener
: TraceableFirewallListener
的侦听器列表:
Symfony\\Component\\Security\\Http\\Firewall\\ChannelListener Symfony\\Component\\Security\\Http\\Firewall\\ContextListener Symfony\\Component\\Security\\Http\\Firewall\\LogoutListener
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 \\ UsernamePasswordFormAuthenticationListener Symfony \\ Component \\ Security \\ Http \\ Firewall \\ RememberMeListener
Symfony\\Component\\Security\\Http\\Firewall\\AnonymousAuthenticationListener Symfony\\Component\\Security\\Http\\Firewall\\AccessListener
Symfony \\ Component \\ Security \\ Http \\ Firewall \\ AnonymousAuthenticationListener Symfony \\ Component \\ Security \\ Http \\ Firewall \\ AccessListener
Why the logout listener is before others? 为什么注销侦听器先于其他侦听器?
It looks a known issue since ... 2013! 自2013年以来看起来是一个已知问题!
https://github.com/symfony/symfony/issues/7104 https://github.com/symfony/symfony/issues/7104
So basically, you cant logout from a RememberMe token :/ 因此,基本上,您不能从RememberMe令牌中注销:/
You can override the firewall listener to call logout listener the last as below 您可以覆盖防火墙侦听器以调用注销侦听器,如下所示
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.