[Security] Deprecated not being logged out after user change
This commit is contained in:
parent
701d41cc33
commit
22f525b01f
@ -269,6 +269,10 @@ SecurityBundle
|
|||||||
as first argument. Not passing it is deprecated and will throw a `TypeError`
|
as first argument. Not passing it is deprecated and will throw a `TypeError`
|
||||||
in 4.0.
|
in 4.0.
|
||||||
|
|
||||||
|
* Added `logout_on_user_change` to the firewall options. This config item will
|
||||||
|
trigger a logout when the user has changed. Should be set to true to avoid
|
||||||
|
deprecations in the configuration.
|
||||||
|
|
||||||
Translation
|
Translation
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -642,6 +642,9 @@ Security
|
|||||||
|
|
||||||
* Support for defining voters that don't implement the `VoterInterface` has been removed.
|
* Support for defining voters that don't implement the `VoterInterface` has been removed.
|
||||||
|
|
||||||
|
* Calling `ContextListener::setLogoutOnUserChange(false)` won't have any
|
||||||
|
effect anymore.
|
||||||
|
|
||||||
SecurityBundle
|
SecurityBundle
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@ -660,6 +663,9 @@ SecurityBundle
|
|||||||
`Symfony\Component\Security\Acl\Model\MutableAclProviderInterfaceConnection`
|
`Symfony\Component\Security\Acl\Model\MutableAclProviderInterfaceConnection`
|
||||||
as first argument.
|
as first argument.
|
||||||
|
|
||||||
|
* The firewall option `logout_on_user_change` is now always true, which will
|
||||||
|
trigger a logout if the user changes between requests.
|
||||||
|
|
||||||
Serializer
|
Serializer
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -13,6 +13,9 @@ CHANGELOG
|
|||||||
* `SetAclCommand::__construct()` now takes an instance of
|
* `SetAclCommand::__construct()` now takes an instance of
|
||||||
`Symfony\Component\Security\Acl\Model\MutableAclProviderInterfaceConnection`
|
`Symfony\Component\Security\Acl\Model\MutableAclProviderInterfaceConnection`
|
||||||
as first argument
|
as first argument
|
||||||
|
* Added `logout_on_user_change` to the firewall options. This config item will
|
||||||
|
trigger a logout when the user has changed. Should be set to true to avoid
|
||||||
|
deprecations in the configuration.
|
||||||
|
|
||||||
3.3.0
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -252,6 +252,10 @@ class MainConfiguration implements ConfigurationInterface
|
|||||||
->scalarNode('provider')->end()
|
->scalarNode('provider')->end()
|
||||||
->booleanNode('stateless')->defaultFalse()->end()
|
->booleanNode('stateless')->defaultFalse()->end()
|
||||||
->scalarNode('context')->cannotBeEmpty()->end()
|
->scalarNode('context')->cannotBeEmpty()->end()
|
||||||
|
->booleanNode('logout_on_user_change')
|
||||||
|
->defaultFalse()
|
||||||
|
->info('When true, it will trigger a logout for the user if something has changed. This will be the default behavior as of Syfmony 4.0.')
|
||||||
|
->end()
|
||||||
->arrayNode('logout')
|
->arrayNode('logout')
|
||||||
->treatTrueLike(array())
|
->treatTrueLike(array())
|
||||||
->canBeUnset()
|
->canBeUnset()
|
||||||
@ -340,6 +344,17 @@ class MainConfiguration implements ConfigurationInterface
|
|||||||
return $firewall;
|
return $firewall;
|
||||||
})
|
})
|
||||||
->end()
|
->end()
|
||||||
|
->validate()
|
||||||
|
->ifTrue(function ($v) {
|
||||||
|
return (isset($v['stateless']) && true === $v['stateless']) || (isset($v['security']) && false === $v['security']);
|
||||||
|
})
|
||||||
|
->then(function ($v) {
|
||||||
|
// this option doesn't change behavior when true when stateless, so prevent deprecations
|
||||||
|
$v['logout_on_user_change'] = true;
|
||||||
|
|
||||||
|
return $v;
|
||||||
|
})
|
||||||
|
->end()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,14 +265,14 @@ class SecurityExtension extends Extension
|
|||||||
$providerIds = $this->createUserProviders($config, $container);
|
$providerIds = $this->createUserProviders($config, $container);
|
||||||
|
|
||||||
// make the ContextListener aware of the configured user providers
|
// make the ContextListener aware of the configured user providers
|
||||||
$definition = $container->getDefinition('security.context_listener');
|
$contextListenerDefinition = $container->getDefinition('security.context_listener');
|
||||||
$arguments = $definition->getArguments();
|
$arguments = $contextListenerDefinition->getArguments();
|
||||||
$userProviders = array();
|
$userProviders = array();
|
||||||
foreach ($providerIds as $userProviderId) {
|
foreach ($providerIds as $userProviderId) {
|
||||||
$userProviders[] = new Reference($userProviderId);
|
$userProviders[] = new Reference($userProviderId);
|
||||||
}
|
}
|
||||||
$arguments[1] = new IteratorArgument($userProviders);
|
$arguments[1] = new IteratorArgument($userProviders);
|
||||||
$definition->setArguments($arguments);
|
$contextListenerDefinition->setArguments($arguments);
|
||||||
|
|
||||||
$customUserChecker = false;
|
$customUserChecker = false;
|
||||||
|
|
||||||
@ -284,6 +284,12 @@ class SecurityExtension extends Extension
|
|||||||
$customUserChecker = true;
|
$customUserChecker = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isset($firewall['logout_on_user_change']) || !$firewall['logout_on_user_change']) {
|
||||||
|
@trigger_error('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.', E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
$contextListenerDefinition->addMethodCall('setLogoutOnUserChange', array($firewall['logout_on_user_change']));
|
||||||
|
|
||||||
$configId = 'security.firewall.map.config.'.$name;
|
$configId = 'security.firewall.map.config.'.$name;
|
||||||
|
|
||||||
list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
|
list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
|
||||||
|
@ -73,6 +73,7 @@ $container->loadFromExtension('security', array(
|
|||||||
'logout' => true,
|
'logout' => true,
|
||||||
'remember_me' => array('secret' => 'TheSecret'),
|
'remember_me' => array('secret' => 'TheSecret'),
|
||||||
'user_checker' => null,
|
'user_checker' => null,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
'host' => array(
|
'host' => array(
|
||||||
'pattern' => '/test',
|
'pattern' => '/test',
|
||||||
@ -80,11 +81,13 @@ $container->loadFromExtension('security', array(
|
|||||||
'methods' => array('GET', 'POST'),
|
'methods' => array('GET', 'POST'),
|
||||||
'anonymous' => true,
|
'anonymous' => true,
|
||||||
'http_basic' => true,
|
'http_basic' => true,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
'with_user_checker' => array(
|
'with_user_checker' => array(
|
||||||
'user_checker' => 'app.user_checker',
|
'user_checker' => 'app.user_checker',
|
||||||
'anonymous' => true,
|
'anonymous' => true,
|
||||||
'http_basic' => true,
|
'http_basic' => true,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -15,10 +15,12 @@ $container->loadFromExtension('security', array(
|
|||||||
'main' => array(
|
'main' => array(
|
||||||
'provider' => 'default',
|
'provider' => 'default',
|
||||||
'form_login' => true,
|
'form_login' => true,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
'other' => array(
|
'other' => array(
|
||||||
'provider' => 'with-dash',
|
'provider' => 'with-dash',
|
||||||
'form_login' => true,
|
'form_login' => true,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
@ -12,6 +12,7 @@ $container->loadFromExtension('security', array(
|
|||||||
'main' => array(
|
'main' => array(
|
||||||
'provider' => 'undefined',
|
'provider' => 'undefined',
|
||||||
'form_login' => true,
|
'form_login' => true,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
@ -11,6 +11,7 @@ $container->loadFromExtension('security', array(
|
|||||||
'firewalls' => array(
|
'firewalls' => array(
|
||||||
'main' => array(
|
'main' => array(
|
||||||
'form_login' => array('provider' => 'default'),
|
'form_login' => array('provider' => 'default'),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
@ -11,6 +11,7 @@ $container->loadFromExtension('security', array(
|
|||||||
'firewalls' => array(
|
'firewalls' => array(
|
||||||
'main' => array(
|
'main' => array(
|
||||||
'form_login' => array('provider' => 'undefined'),
|
'form_login' => array('provider' => 'undefined'),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
@ -11,6 +11,7 @@ $container->loadFromExtension('security', array(
|
|||||||
'main' => array(
|
'main' => array(
|
||||||
'form_login' => false,
|
'form_login' => false,
|
||||||
'http_basic' => null,
|
'http_basic' => null,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ $container->loadFromExtension('security', array(
|
|||||||
'form_login' => array(
|
'form_login' => array(
|
||||||
'login_path' => '/login',
|
'login_path' => '/login',
|
||||||
),
|
),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'role_hierarchy' => array(
|
'role_hierarchy' => array(
|
||||||
|
@ -12,7 +12,8 @@ $container->loadFromExtension('security', array(
|
|||||||
),
|
),
|
||||||
'firewalls' => array(
|
'firewalls' => array(
|
||||||
'simple' => array('pattern' => '/login', 'security' => false),
|
'simple' => array('pattern' => '/login', 'security' => false),
|
||||||
'secure' => array('stateless' => true,
|
'secure' => array(
|
||||||
|
'stateless' => true,
|
||||||
'http_basic' => true,
|
'http_basic' => true,
|
||||||
'http_digest' => array('secret' => 'TheSecret'),
|
'http_digest' => array('secret' => 'TheSecret'),
|
||||||
'form_login' => true,
|
'form_login' => true,
|
||||||
|
@ -13,6 +13,7 @@ $container->loadFromExtension('security', array(
|
|||||||
'catch_exceptions' => false,
|
'catch_exceptions' => false,
|
||||||
'token_provider' => 'token_provider_id',
|
'token_provider' => 'token_provider_id',
|
||||||
),
|
),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
@ -60,12 +60,12 @@
|
|||||||
<remember-me secret="TheSecret"/>
|
<remember-me secret="TheSecret"/>
|
||||||
</firewall>
|
</firewall>
|
||||||
|
|
||||||
<firewall name="host" pattern="/test" host="foo\.example\.org" methods="GET,POST">
|
<firewall name="host" pattern="/test" host="foo\.example\.org" methods="GET,POST" logout-on-user-change="true">
|
||||||
<anonymous />
|
<anonymous />
|
||||||
<http-basic />
|
<http-basic />
|
||||||
</firewall>
|
</firewall>
|
||||||
|
|
||||||
<firewall name="with_user_checker">
|
<firewall name="with_user_checker" logout-on-user-change="true">
|
||||||
<anonymous />
|
<anonymous />
|
||||||
<http-basic />
|
<http-basic />
|
||||||
<user-checker>app.user_checker</user-checker>
|
<user-checker>app.user_checker</user-checker>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</sec:providers>
|
</sec:providers>
|
||||||
|
|
||||||
<sec:firewalls>
|
<sec:firewalls>
|
||||||
<sec:firewall name="main" provider="with-dash">
|
<sec:firewall name="main" provider="with-dash" logout-on-user-change="true">
|
||||||
<sec:form_login />
|
<sec:form_login />
|
||||||
</sec:firewall>
|
</sec:firewall>
|
||||||
</sec:firewalls>
|
</sec:firewalls>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</sec:providers>
|
</sec:providers>
|
||||||
|
|
||||||
<sec:firewalls>
|
<sec:firewalls>
|
||||||
<sec:firewall name="main" provider="undefined">
|
<sec:firewall name="main" provider="undefined" logout-on-user-change="true">
|
||||||
<sec:form_login />
|
<sec:form_login />
|
||||||
</sec:firewall>
|
</sec:firewall>
|
||||||
</sec:firewalls>
|
</sec:firewalls>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</sec:providers>
|
</sec:providers>
|
||||||
|
|
||||||
<sec:firewalls>
|
<sec:firewalls>
|
||||||
<sec:firewall name="main">
|
<sec:firewall name="main" logout-on-user-change="true">
|
||||||
<sec:form_login provider="default" />
|
<sec:form_login provider="default" />
|
||||||
</sec:firewall>
|
</sec:firewall>
|
||||||
</sec:firewalls>
|
</sec:firewalls>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</sec:providers>
|
</sec:providers>
|
||||||
|
|
||||||
<sec:firewalls>
|
<sec:firewalls>
|
||||||
<sec:firewall name="main">
|
<sec:firewall name="main" logout-on-user-change="true">
|
||||||
<sec:form_login provider="undefined" />
|
<sec:form_login provider="undefined" />
|
||||||
</sec:firewall>
|
</sec:firewall>
|
||||||
</sec:firewalls>
|
</sec:firewalls>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<sec:config>
|
<sec:config>
|
||||||
<sec:provider name="default" id="foo" />
|
<sec:provider name="default" id="foo" />
|
||||||
|
|
||||||
<sec:firewall name="main" form-login="false">
|
<sec:firewall name="main" form-login="false" logout-on-user-change="true">
|
||||||
<sec:http-basic />
|
<sec:http-basic />
|
||||||
</sec:firewall>
|
</sec:firewall>
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
|
|
||||||
<config>
|
<config>
|
||||||
<firewall name="main">
|
<firewall name="main" logout-on-user-change="true">
|
||||||
<form-login login-path="/login" />
|
<form-login login-path="/login" />
|
||||||
</firewall>
|
</firewall>
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<sec:providers>
|
<sec:providers>
|
||||||
<sec:default id="foo"/>
|
<sec:default id="foo"/>
|
||||||
</sec:providers>
|
</sec:providers>
|
||||||
<sec:firewall name="main">
|
<sec:firewall name="main" logout-on-user-change="true">
|
||||||
<sec:form-login/>
|
<sec:form-login/>
|
||||||
<sec:remember-me secret="TheSecret" catch-exceptions="false" token-provider="token_provider_id" />
|
<sec:remember-me secret="TheSecret" catch-exceptions="false" token-provider="token_provider_id" />
|
||||||
</sec:firewall>
|
</sec:firewall>
|
||||||
|
@ -64,11 +64,13 @@ security:
|
|||||||
methods: [GET,POST]
|
methods: [GET,POST]
|
||||||
anonymous: true
|
anonymous: true
|
||||||
http_basic: true
|
http_basic: true
|
||||||
|
logout_on_user_change: true
|
||||||
|
|
||||||
with_user_checker:
|
with_user_checker:
|
||||||
anonymous: ~
|
anonymous: ~
|
||||||
http_basic: ~
|
http_basic: ~
|
||||||
user_checker: app.user_checker
|
user_checker: app.user_checker
|
||||||
|
logout_on_user_change: true
|
||||||
|
|
||||||
role_hierarchy:
|
role_hierarchy:
|
||||||
ROLE_ADMIN: ROLE_USER
|
ROLE_ADMIN: ROLE_USER
|
||||||
|
@ -11,6 +11,8 @@ security:
|
|||||||
main:
|
main:
|
||||||
provider: default
|
provider: default
|
||||||
form_login: true
|
form_login: true
|
||||||
|
logout_on_user_change: true
|
||||||
other:
|
other:
|
||||||
provider: with-dash
|
provider: with-dash
|
||||||
form_login: true
|
form_login: true
|
||||||
|
logout_on_user_change: true
|
||||||
|
@ -8,3 +8,4 @@ security:
|
|||||||
main:
|
main:
|
||||||
provider: undefined
|
provider: undefined
|
||||||
form_login: true
|
form_login: true
|
||||||
|
logout_on_user_change: true
|
||||||
|
@ -8,3 +8,4 @@ security:
|
|||||||
main:
|
main:
|
||||||
form_login:
|
form_login:
|
||||||
provider: default
|
provider: default
|
||||||
|
logout_on_user_change: true
|
||||||
|
@ -8,3 +8,4 @@ security:
|
|||||||
main:
|
main:
|
||||||
form_login:
|
form_login:
|
||||||
provider: undefined
|
provider: undefined
|
||||||
|
logout_on_user_change: true
|
||||||
|
@ -9,6 +9,7 @@ security:
|
|||||||
main:
|
main:
|
||||||
form_login: false
|
form_login: false
|
||||||
http_basic: ~
|
http_basic: ~
|
||||||
|
logout_on_user_change: true
|
||||||
|
|
||||||
role_hierarchy:
|
role_hierarchy:
|
||||||
FOO: [MOO]
|
FOO: [MOO]
|
||||||
|
@ -3,6 +3,7 @@ security:
|
|||||||
main:
|
main:
|
||||||
form_login:
|
form_login:
|
||||||
login_path: /login
|
login_path: /login
|
||||||
|
logout_on_user_change: true
|
||||||
|
|
||||||
role_hierarchy:
|
role_hierarchy:
|
||||||
FOO: BAR
|
FOO: BAR
|
||||||
|
@ -10,3 +10,4 @@ security:
|
|||||||
secret: TheSecret
|
secret: TheSecret
|
||||||
catch_exceptions: false
|
catch_exceptions: false
|
||||||
token_provider: token_provider_id
|
token_provider: token_provider_id
|
||||||
|
logout_on_user_change: true
|
||||||
|
@ -31,6 +31,7 @@ class MainConfigurationTest extends TestCase
|
|||||||
),
|
),
|
||||||
'firewalls' => array(
|
'firewalls' => array(
|
||||||
'stub' => array(),
|
'stub' => array(),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ class MainConfigurationTest extends TestCase
|
|||||||
'csrf_token_generator' => 'a_token_generator',
|
'csrf_token_generator' => 'a_token_generator',
|
||||||
'csrf_token_id' => 'a_token_id',
|
'csrf_token_id' => 'a_token_id',
|
||||||
),
|
),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -107,6 +109,7 @@ class MainConfigurationTest extends TestCase
|
|||||||
'firewalls' => array(
|
'firewalls' => array(
|
||||||
'stub' => array(
|
'stub' => array(
|
||||||
'user_checker' => 'app.henk_checker',
|
'user_checker' => 'app.henk_checker',
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -38,6 +38,7 @@ class SecurityExtensionTest extends TestCase
|
|||||||
'form_login' => array(
|
'form_login' => array(
|
||||||
'check_path' => '/some_area/login_check',
|
'check_path' => '/some_area/login_check',
|
||||||
),
|
),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -61,6 +62,7 @@ class SecurityExtensionTest extends TestCase
|
|||||||
'firewalls' => array(
|
'firewalls' => array(
|
||||||
'some_firewall' => array(
|
'some_firewall' => array(
|
||||||
'pattern' => '/.*',
|
'pattern' => '/.*',
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -88,6 +90,7 @@ class SecurityExtensionTest extends TestCase
|
|||||||
'some_firewall' => array(
|
'some_firewall' => array(
|
||||||
'pattern' => '/.*',
|
'pattern' => '/.*',
|
||||||
'http_basic' => array(),
|
'http_basic' => array(),
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -110,6 +113,7 @@ class SecurityExtensionTest extends TestCase
|
|||||||
'some_firewall' => array(
|
'some_firewall' => array(
|
||||||
'pattern' => '/.*',
|
'pattern' => '/.*',
|
||||||
'http_basic' => null,
|
'http_basic' => null,
|
||||||
|
'logout_on_user_change' => true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -119,6 +123,31 @@ class SecurityExtensionTest extends TestCase
|
|||||||
$this->assertFalse($container->hasDefinition('security.access.role_hierarchy_voter'));
|
$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()
|
protected function getRawContainer()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -6,6 +6,10 @@ CHANGELOG
|
|||||||
|
|
||||||
* Using voters that do not implement the `VoterInterface`is now deprecated in
|
* Using voters that do not implement the `VoterInterface`is now deprecated in
|
||||||
the `AccessDecisionManager` and this functionality will be removed in 4.0.
|
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
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -44,6 +44,7 @@ class ContextListener implements ListenerInterface
|
|||||||
private $dispatcher;
|
private $dispatcher;
|
||||||
private $registered;
|
private $registered;
|
||||||
private $trustResolver;
|
private $trustResolver;
|
||||||
|
private $logoutOnUserChange = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TokenStorageInterface $tokenStorage
|
* @param TokenStorageInterface $tokenStorage
|
||||||
@ -68,6 +69,16 @@ class ContextListener implements ListenerInterface
|
|||||||
$this->trustResolver = $trustResolver ?: new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class);
|
$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.
|
* Reads the Security Token from the session.
|
||||||
*
|
*
|
||||||
@ -122,14 +133,14 @@ class ContextListener implements ListenerInterface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$event->getRequest()->hasSession()) {
|
$request = $event->getRequest();
|
||||||
|
|
||||||
|
if (!$request->hasSession()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->dispatcher->removeListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
|
$this->dispatcher->removeListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
|
||||||
$this->registered = false;
|
$this->registered = false;
|
||||||
|
|
||||||
$request = $event->getRequest();
|
|
||||||
$session = $request->getSession();
|
$session = $request->getSession();
|
||||||
|
|
||||||
if ((null === $token = $this->tokenStorage->getToken()) || $this->trustResolver->isAnonymous($token)) {
|
if ((null === $token = $this->tokenStorage->getToken()) || $this->trustResolver->isAnonymous($token)) {
|
||||||
@ -172,6 +183,19 @@ class ContextListener implements ListenerInterface
|
|||||||
$refreshedUser = $provider->refreshUser($user);
|
$refreshedUser = $provider->refreshUser($user);
|
||||||
$token->setUser($refreshedUser);
|
$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) {
|
if (null !== $this->logger) {
|
||||||
$context = array('provider' => get_class($provider), 'username' => $refreshedUser->getUsername());
|
$context = array('provider' => get_class($provider), 'username' => $refreshedUser->getUsername());
|
||||||
|
|
||||||
|
@ -249,7 +249,11 @@ class ContextListenerTest extends TestCase
|
|||||||
$listener->handle($event);
|
$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();
|
$tokenStorage = new TokenStorage();
|
||||||
$refreshedUser = new User('foobar', 'baz');
|
$refreshedUser = new User('foobar', 'baz');
|
||||||
@ -258,11 +262,29 @@ class ContextListenerTest extends TestCase
|
|||||||
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
$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()
|
public function testNextSupportingUserProviderIsTriedIfPreviousSupportingUserProviderDidNotLoadTheUser()
|
||||||
{
|
{
|
||||||
$tokenStorage = new TokenStorage();
|
$tokenStorage = new TokenStorage();
|
||||||
$refreshedUser = new User('foobar', 'baz');
|
$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());
|
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
||||||
}
|
}
|
||||||
@ -287,7 +309,7 @@ class ContextListenerTest extends TestCase
|
|||||||
{
|
{
|
||||||
$tokenStorage = new TokenStorage();
|
$tokenStorage = new TokenStorage();
|
||||||
$refreshedUser = new User('foobar', 'baz');
|
$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());
|
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
||||||
}
|
}
|
||||||
@ -320,16 +342,18 @@ class ContextListenerTest extends TestCase
|
|||||||
return $session;
|
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 = 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 = new Request();
|
||||||
$request->setSession($session);
|
$request->setSession($session);
|
||||||
$request->cookies->set('MOCKSESSID', true);
|
$request->cookies->set('MOCKSESSID', true);
|
||||||
|
|
||||||
$listener = new ContextListener($tokenStorage, $userProviders, 'context_key');
|
$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));
|
$listener->handle(new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user