簡體   English   中英

Symfony Security注銷未清除RememberMe令牌

[英]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令牌。

我可以看到LogoutListenerhttps://github.com/symfony/security/blob/master/Http/Firewall/LogoutListener.php )之后被稱為RememberMeListenerhttps://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

為什么注銷偵聽器先於其他偵聽器?

自2013年以來看起來是一個已知問題!

https://github.com/symfony/symfony/issues/7104

因此,基本上,您不能從RememberMe令牌中注銷:/

您可以覆蓋防火牆偵聽器以調用注銷偵聽器,如下所示

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM