+
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml
index e8ed61ef031b9..a2b57201bfbd2 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml
@@ -64,11 +64,13 @@ security:
methods: [GET,POST]
anonymous: true
http_basic: true
+ logout_on_user_change: true
with_user_checker:
anonymous: ~
http_basic: ~
user_checker: app.user_checker
+ logout_on_user_change: true
role_hierarchy:
ROLE_ADMIN: ROLE_USER
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_provider.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_provider.yml
index 11c329aa8e2fe..b8da52b6e45d3 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_provider.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_provider.yml
@@ -11,6 +11,8 @@ security:
main:
provider: default
form_login: true
+ logout_on_user_change: true
other:
provider: with-dash
form_login: true
+ logout_on_user_change: true
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_undefined_provider.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_undefined_provider.yml
index ec2664054009c..3385fc3485a0e 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_undefined_provider.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/firewall_undefined_provider.yml
@@ -8,3 +8,4 @@ security:
main:
provider: undefined
form_login: true
+ logout_on_user_change: true
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_provider.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_provider.yml
index 652f23b5f0425..53e2784c4b3a9 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_provider.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_provider.yml
@@ -8,3 +8,4 @@ security:
main:
form_login:
provider: default
+ logout_on_user_change: true
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_undefined_provider.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_undefined_provider.yml
index 1916df4c2e7ca..ba5f69ede665d 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_undefined_provider.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/listener_undefined_provider.yml
@@ -8,3 +8,4 @@ security:
main:
form_login:
provider: undefined
+ logout_on_user_change: true
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml
index 60c0bbea558e7..d8f443c62f34e 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge.yml
@@ -9,6 +9,7 @@ security:
main:
form_login: false
http_basic: ~
+ logout_on_user_change: true
role_hierarchy:
FOO: [MOO]
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml
index 4f8db0a09f7b4..a081003a49578 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/merge_import.yml
@@ -3,6 +3,7 @@ security:
main:
form_login:
login_path: /login
+ logout_on_user_change: true
role_hierarchy:
FOO: BAR
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/remember_me_options.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/remember_me_options.yml
index a521c8c6a803d..716cd4cf99d14 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/remember_me_options.yml
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/remember_me_options.yml
@@ -10,3 +10,4 @@ security:
secret: TheSecret
catch_exceptions: false
token_provider: token_provider_id
+ logout_on_user_change: true
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php
index a64c4fe4101f1..02e8062c269f4 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php
@@ -31,6 +31,7 @@ class MainConfigurationTest extends TestCase
),
'firewalls' => array(
'stub' => array(),
+ 'logout_on_user_change' => true,
),
);
@@ -78,6 +79,7 @@ public function testCsrfAliases()
'csrf_token_generator' => 'a_token_generator',
'csrf_token_id' => 'a_token_id',
),
+ 'logout_on_user_change' => true,
),
),
);
@@ -107,6 +109,7 @@ public function testUserCheckers()
'firewalls' => array(
'stub' => array(
'user_checker' => 'app.henk_checker',
+ 'logout_on_user_change' => true,
),
),
);
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
index 72ef2e0c3ed56..1055e4afd40f6 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
@@ -38,6 +38,7 @@ public function testInvalidCheckPath()
'form_login' => array(
'check_path' => '/some_area/login_check',
),
+ 'logout_on_user_change' => true,
),
),
));
@@ -61,6 +62,7 @@ public function testFirewallWithoutAuthenticationListener()
'firewalls' => array(
'some_firewall' => array(
'pattern' => '/.*',
+ 'logout_on_user_change' => true,
),
),
));
@@ -88,6 +90,7 @@ public function testFirewallWithInvalidUserProvider()
'some_firewall' => array(
'pattern' => '/.*',
'http_basic' => array(),
+ 'logout_on_user_change' => true,
),
),
));
@@ -110,6 +113,7 @@ public function testDisableRoleHierarchyVoter()
'some_firewall' => array(
'pattern' => '/.*',
'http_basic' => null,
+ 'logout_on_user_change' => true,
),
),
));
@@ -119,6 +123,31 @@ public function testDisableRoleHierarchyVoter()
$this->assertFalse($container->hasDefinition('security.access.role_hierarchy_voter'));
}
+ /**
+ * @group legacy
+ * @expectedDeprecation Setting logout_on_user_change to false is deprecated as of 3.4 and will always be true in 4.0. Set logout_on_user_change to true in your firewall configuration.
+ */
+ public function testDeprecationForUserLogout()
+ {
+ $container = $this->getRawContainer();
+
+ $container->loadFromExtension('security', array(
+ 'providers' => array(
+ 'default' => array('id' => 'foo'),
+ ),
+
+ 'firewalls' => array(
+ 'some_firewall' => array(
+ 'pattern' => '/.*',
+ 'http_basic' => null,
+ 'logout_on_user_change' => false,
+ ),
+ ),
+ ));
+
+ $container->compile();
+ }
+
protected function getRawContainer()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/Security/CHANGELOG.md b/src/Symfony/Component/Security/CHANGELOG.md
index 292c304fc68c7..99032dae9da9b 100644
--- a/src/Symfony/Component/Security/CHANGELOG.md
+++ b/src/Symfony/Component/Security/CHANGELOG.md
@@ -6,6 +6,10 @@ CHANGELOG
* Using voters that do not implement the `VoterInterface`is now deprecated in
the `AccessDecisionManager` and this functionality will be removed in 4.0.
+ * Using the `ContextListener` without setting the `logoutOnUserChange`
+ property will trigger a deprecation when the user has changed. As of 4.0
+ the user will always be logged out when the user has changed between
+ requests.
3.3.0
-----
diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php
index cd26d83ef7291..e018f704dd659 100644
--- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php
@@ -44,6 +44,7 @@ class ContextListener implements ListenerInterface
private $dispatcher;
private $registered;
private $trustResolver;
+ private $logoutOnUserChange = false;
/**
* @param TokenStorageInterface $tokenStorage
@@ -68,6 +69,16 @@ public function __construct(TokenStorageInterface $tokenStorage, $userProviders,
$this->trustResolver = $trustResolver ?: new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class);
}
+ /**
+ * Enables deauthentication during refreshUser when the user has changed.
+ *
+ * @param bool $logoutOnUserChange
+ */
+ public function setLogoutOnUserChange($logoutOnUserChange)
+ {
+ $this->logoutOnUserChange = (bool) $logoutOnUserChange;
+ }
+
/**
* Reads the Security Token from the session.
*
@@ -122,14 +133,14 @@ public function onKernelResponse(FilterResponseEvent $event)
return;
}
- if (!$event->getRequest()->hasSession()) {
+ $request = $event->getRequest();
+
+ if (!$request->hasSession()) {
return;
}
$this->dispatcher->removeListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
$this->registered = false;
-
- $request = $event->getRequest();
$session = $request->getSession();
if ((null === $token = $this->tokenStorage->getToken()) || $this->trustResolver->isAnonymous($token)) {
@@ -172,6 +183,19 @@ protected function refreshUser(TokenInterface $token)
$refreshedUser = $provider->refreshUser($user);
$token->setUser($refreshedUser);
+ // tokens can be deauthenticated if the user has been changed.
+ if (!$token->isAuthenticated()) {
+ if ($this->logoutOnUserChange) {
+ if (null !== $this->logger) {
+ $this->logger->debug('Token was deauthenticated after trying to refresh it.', array('username' => $refreshedUser->getUsername(), 'provider' => get_class($provider)));
+ }
+
+ return null;
+ }
+
+ @trigger_error('Refreshing a deauthenticated user is deprecated as of 3.4 and will trigger a logout in 4.0.', E_USER_DEPRECATED);
+ }
+
if (null !== $this->logger) {
$context = array('provider' => get_class($provider), 'username' => $refreshedUser->getUsername());
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
index 66cf4458bc4de..d27569fa3a0ba 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
@@ -249,7 +249,11 @@ public function testHandleRemovesTokenIfNoPreviousSessionWasFound()
$listener->handle($event);
}
- public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
+ /**
+ * @group legacy
+ * @expectedDeprecation Refreshing a deauthenticated user is deprecated as of 3.4 and will trigger a logout in 4.0.
+ */
+ public function testIfTokenIsDeauthenticatedTriggersDeprecations()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
@@ -258,11 +262,29 @@ public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
+ public function testIfTokenIsDeauthenticated()
+ {
+ $tokenStorage = new TokenStorage();
+ $refreshedUser = new User('foobar', 'baz');
+ $this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)), null, true);
+
+ $this->assertNull($tokenStorage->getToken());
+ }
+
+ public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
+ {
+ $tokenStorage = new TokenStorage();
+ $refreshedUser = new User('foobar', 'baz');
+ $this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)), $refreshedUser);
+
+ $this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
+ }
+
public function testNextSupportingUserProviderIsTriedIfPreviousSupportingUserProviderDidNotLoadTheUser()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
- $this->handleEventWithPreviousSession($tokenStorage, array(new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)));
+ $this->handleEventWithPreviousSession($tokenStorage, array(new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)), $refreshedUser);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
@@ -287,7 +309,7 @@ public function testAcceptsProvidersAsTraversable()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
- $this->handleEventWithPreviousSession($tokenStorage, new \ArrayObject(array(new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser))));
+ $this->handleEventWithPreviousSession($tokenStorage, new \ArrayObject(array(new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser))), $refreshedUser);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
@@ -320,16 +342,18 @@ protected function runSessionOnKernelResponse($newToken, $original = null)
return $session;
}
- private function handleEventWithPreviousSession(TokenStorageInterface $tokenStorage, $userProviders)
+ private function handleEventWithPreviousSession(TokenStorageInterface $tokenStorage, $userProviders, UserInterface $user = null, $logoutOnUserChange = false)
{
+ $user = $user ?: new User('foo', 'bar');
$session = new Session(new MockArraySessionStorage());
- $session->set('_security_context_key', serialize(new UsernamePasswordToken(new User('foo', 'bar'), '', 'context_key')));
+ $session->set('_security_context_key', serialize(new UsernamePasswordToken($user, '', 'context_key', array('ROLE_USER'))));
$request = new Request();
$request->setSession($session);
$request->cookies->set('MOCKSESSID', true);
$listener = new ContextListener($tokenStorage, $userProviders, 'context_key');
+ $listener->setLogoutOnUserChange($logoutOnUserChange);
$listener->handle(new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
}
}
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy