[Security] deprecate multiple providers in context listener

Passing multiple user providers to the context listener does not make
much sense. The listener is only responsible to refresh users for a
particular firewall. Thus, it must only be aware of the user provider
for this particular firewall.
This commit is contained in:
Christian Flothmann 2017-02-27 22:53:00 +01:00
parent fbd9f88e31
commit 53df0de7fc
6 changed files with 38 additions and 10 deletions

View File

@ -94,6 +94,9 @@ Process
Security Security
-------- --------
* Deprecated the ability to pass multiple user providers to the `ContextListener`. Pass only the user provider responsible
for the active firewall instead.
* The `RoleInterface` has been deprecated. Extend the `Symfony\Component\Security\Core\Role\Role` * The `RoleInterface` has been deprecated. Extend the `Symfony\Component\Security\Core\Role\Role`
class in your custom role implementations instead. class in your custom role implementations instead.

View File

@ -252,6 +252,9 @@ Process
Security Security
-------- --------
* Dropped support for passing multiple user providers to the `ContextListener`. Pass only the user provider responsible
for the active firewall instead.
* The `RoleInterface` has been removed. Extend the `Symfony\Component\Security\Core\Role\Role` * The `RoleInterface` has been removed. Extend the `Symfony\Component\Security\Core\Role\Role`
class instead. class instead.

View File

@ -434,7 +434,7 @@ class SecurityExtension extends Extension
$listenerId = 'security.context_listener.'.count($this->contextListeners); $listenerId = 'security.context_listener.'.count($this->contextListeners);
$listener = $container->setDefinition($listenerId, new ChildDefinition('security.context_listener')); $listener = $container->setDefinition($listenerId, new ChildDefinition('security.context_listener'));
$listener->replaceArgument(1, array(new Reference($providerId))); $listener->replaceArgument(1, new Reference($providerId));
$listener->replaceArgument(2, $contextKey); $listener->replaceArgument(2, $contextKey);
return $this->contextListeners[$contextKey] = $listenerId; return $this->contextListeners[$contextKey] = $listenerId;

View File

@ -1,6 +1,12 @@
CHANGELOG CHANGELOG
========= =========
3.3.0
-----
* Deprecated the ability to pass multiple user providers to the `ContextListener`. Pass only the user provider responsible
for the active firewall instead.
3.2.0 3.2.0
----- -----

View File

@ -44,12 +44,26 @@ class ContextListener implements ListenerInterface
private $registered; private $registered;
private $trustResolver; private $trustResolver;
public function __construct(TokenStorageInterface $tokenStorage, array $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null) /**
* @param TokenStorageInterface $tokenStorage
* @param UserProviderInterface|UserProviderInterface[] $userProviders
* @param string $contextKey
* @param LoggerInterface|null $logger
* @param EventDispatcherInterface|null $dispatcher
* @param AuthenticationTrustResolverInterface|null $trustResolver
*/
public function __construct(TokenStorageInterface $tokenStorage, $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null)
{ {
if (empty($contextKey)) { if (empty($contextKey)) {
throw new \InvalidArgumentException('$contextKey must not be empty.'); throw new \InvalidArgumentException('$contextKey must not be empty.');
} }
if (is_array($userProviders)) {
@trigger_error(sprintf('Being able to pass multiple user providers to the constructor of %s is deprecated since version 3.3 and will not be supported anymore in 4.0. Only pass the user provider for the current firewall context instead.', __CLASS__), E_USER_DEPRECATED);
} else {
$userProviders = array($userProviders);
}
foreach ($userProviders as $userProvider) { foreach ($userProviders as $userProvider) {
if (!$userProvider instanceof UserProviderInterface) { if (!$userProvider instanceof UserProviderInterface) {
throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "Symfony\Component\Security\Core\User\UserProviderInterface".', get_class($userProvider))); throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "Symfony\Component\Security\Core\User\UserProviderInterface".', get_class($userProvider)));

View File

@ -22,6 +22,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Firewall\ContextListener; use Symfony\Component\Security\Http\Firewall\ContextListener;
use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\EventDispatcher;
@ -35,12 +36,13 @@ class ContextListenerTest extends TestCase
{ {
new ContextListener( new ContextListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(), $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
array(), $this->getMockBuilder(UserProviderInterface::class)->getMock(),
'' ''
); );
} }
/** /**
* @group legacy
* @expectedException \InvalidArgumentException * @expectedException \InvalidArgumentException
* @expectedExceptionMessage User provider "stdClass" must implement "Symfony\Component\Security\Core\User\UserProviderInterface * @expectedExceptionMessage User provider "stdClass" must implement "Symfony\Component\Security\Core\User\UserProviderInterface
*/ */
@ -109,7 +111,7 @@ class ContextListenerTest extends TestCase
new Response() new Response()
); );
$listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher()); $listener = new ContextListener($tokenStorage, $this->getMockBuilder(UserProviderInterface::class)->getMock(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event); $listener->onKernelResponse($event);
$this->assertTrue($session->isStarted()); $this->assertTrue($session->isStarted());
@ -128,7 +130,7 @@ class ContextListenerTest extends TestCase
new Response() new Response()
); );
$listener = new ContextListener(new TokenStorage(), array(), 'session', null, new EventDispatcher()); $listener = new ContextListener(new TokenStorage(), $this->getMockBuilder(UserProviderInterface::class)->getMock(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event); $listener->onKernelResponse($event);
$this->assertFalse($session->isStarted()); $this->assertFalse($session->isStarted());
@ -163,7 +165,7 @@ class ContextListenerTest extends TestCase
->method('setToken') ->method('setToken')
->with(null); ->with(null);
$listener = new ContextListener($tokenStorage, array(), 'key123'); $listener = new ContextListener($tokenStorage, $this->getMockBuilder(UserProviderInterface::class)->getMock(), 'key123');
$listener->handle($event); $listener->handle($event);
} }
@ -184,7 +186,7 @@ class ContextListenerTest extends TestCase
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher); $listener = new ContextListener($tokenStorage, $this->getMockBuilder(UserProviderInterface::class)->getMock(), 'key123', null, $dispatcher);
$event->expects($this->any()) $event->expects($this->any())
->method('isMasterRequest') ->method('isMasterRequest')
@ -208,7 +210,7 @@ class ContextListenerTest extends TestCase
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher); $listener = new ContextListener($tokenStorage, $this->getMockBuilder(UserProviderInterface::class)->getMock(), 'key123', null, $dispatcher);
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock(); $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$request->expects($this->any()) $request->expects($this->any())
@ -242,7 +244,7 @@ class ContextListenerTest extends TestCase
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(); $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage->expects($this->once())->method('setToken')->with(null); $tokenStorage->expects($this->once())->method('setToken')->with(null);
$listener = new ContextListener($tokenStorage, array(), 'key123'); $listener = new ContextListener($tokenStorage, $this->getMockBuilder(UserProviderInterface::class)->getMock(), 'key123');
$listener->handle($event); $listener->handle($event);
} }
@ -268,7 +270,7 @@ class ContextListenerTest extends TestCase
new Response() new Response()
); );
$listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher()); $listener = new ContextListener($tokenStorage, $this->getMockBuilder(UserProviderInterface::class)->getMock(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event); $listener->onKernelResponse($event);
return $session; return $session;