Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bc4a692

Browse files
committed
Merge branch '3.4'
* 3.4: [FrameworkBundle] Register a NullLogger from test kernels [SecurityBundle] Deprecate auto picking the first provider [Security] Add user impersonation support for stateless authentication
2 parents da0bf99 + cd91b8f commit bc4a692

File tree

21 files changed

+176
-19
lines changed

21 files changed

+176
-19
lines changed

UPGRADE-3.4.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,13 @@ SecurityBundle
316316

317317
* Deprecated the HTTP digest authentication: `HttpDigestFactory` will be removed in 4.0.
318318
Use another authentication system like `http_basic` instead.
319+
320+
* Deprecated setting the `switch_user.stateless` option to false when the firewall is `stateless`.
321+
Setting it to false will have no effect in 4.0.
322+
323+
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
324+
Using the first configured provider is deprecated since 3.4 and will throw an exception on 4.0.
325+
Explicitly configure the provider to use on your firewalls.
319326

320327
Translation
321328
-----------

UPGRADE-4.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,12 @@ SecurityBundle
693693

694694
* Removed the HTTP digest authentication system. The `HttpDigestFactory` class
695695
has been removed. Use another authentication system like `http_basic` instead.
696+
697+
* The `switch_user.stateless` option is now always true if the firewall is stateless.
698+
699+
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
700+
The first configured provider is not used anymore and an exception is thrown instead.
701+
Explicitly configure the provider to use on your firewalls.
696702

697703
Serializer
698704
----------

src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/Fixture/TestAppKernel.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Command\CacheClearCommand\Fixture;
1313

14+
use Psr\Log\NullLogger;
1415
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
1516
use Symfony\Component\Config\Loader\LoaderInterface;
17+
use Symfony\Component\DependencyInjection\ContainerBuilder;
1618
use Symfony\Component\HttpKernel\Kernel;
1719

1820
class TestAppKernel extends Kernel
@@ -33,4 +35,9 @@ public function registerContainerConfiguration(LoaderInterface $loader)
3335
{
3436
$loader->load(__DIR__.DIRECTORY_SEPARATOR.'config.yml');
3537
}
38+
39+
protected function build(ContainerBuilder $container)
40+
{
41+
$container->register('logger', NullLogger::class);
42+
}
3643
}

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AppKernel.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\app;
1313

14+
use Psr\Log\NullLogger;
1415
use Symfony\Component\Config\Loader\LoaderInterface;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
1517
use Symfony\Component\Filesystem\Filesystem;
1618
use Symfony\Component\HttpKernel\Kernel;
1719

@@ -72,6 +74,11 @@ public function registerContainerConfiguration(LoaderInterface $loader)
7274
$loader->load($this->rootConfig);
7375
}
7476

77+
protected function build(ContainerBuilder $container)
78+
{
79+
$container->register('logger', NullLogger::class);
80+
}
81+
7582
public function serialize()
7683
{
7784
return serialize(array($this->varDir, $this->testCase, $this->rootConfig, $this->getEnvironment(), $this->isDebug()));

src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Kernel;
1313

14+
use Psr\Log\NullLogger;
1415
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
1516
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
1617
use Symfony\Component\Config\Loader\LoaderInterface;
@@ -77,6 +78,7 @@ protected function configureRoutes(RouteCollectionBuilder $routes)
7778

7879
protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
7980
{
81+
$c->register('logger', NullLogger::class);
8082
$c->loadFromExtension('framework', array(
8183
'secret' => '$ecret',
8284
));

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ CHANGELOG
3030
* deprecated command `acl:set` along with `SetAclCommand` class
3131
* deprecated command `init:acl` along with `InitAclCommand` class
3232
* Added support for the new Argon2i password encoder
33+
* added `stateless` option to the `switch_user` listener
34+
* deprecated auto picking the first registered provider when no configured provider on a firewall and ambiguous
3335

3436
3.3.0
3537
-----

src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
254254
->scalarNode('provider')->end()
255255
->scalarNode('parameter')->defaultValue('_switch_user')->end()
256256
->scalarNode('role')->defaultValue('ROLE_ALLOWED_TO_SWITCH')->end()
257+
->booleanNode('stateless')->defaultValue(false)->end()
257258
->end()
258259
->end()
259260
;

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
262262
$defaultProvider = $providerIds[$normalizedName];
263263
} else {
264264
$defaultProvider = reset($providerIds);
265+
266+
if (count($providerIds) > 1) {
267+
@trigger_error(sprintf('Firewall "%s" has no "provider" set but multiple providers exist. Using the first configured provider (%s) is deprecated since 3.4 and will throw an exception in 4.0, set the "provider" key on the firewall instead.', $id, key($providerIds)), E_USER_DEPRECATED);
268+
}
265269
}
266270

267271
$config->replaceArgument(5, $defaultProvider);
@@ -359,7 +363,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
359363
// Switch user listener
360364
if (isset($firewall['switch_user'])) {
361365
$listenerKeys[] = 'switch_user';
362-
$listeners[] = new Reference($this->createSwitchUserListener($container, $id, $firewall['switch_user'], $defaultProvider));
366+
$listeners[] = new Reference($this->createSwitchUserListener($container, $id, $firewall['switch_user'], $defaultProvider, $firewall['stateless']));
363367
}
364368

365369
// Access listener
@@ -602,17 +606,23 @@ private function createExceptionListener($container, $config, $id, $defaultEntry
602606
return $exceptionListenerId;
603607
}
604608

605-
private function createSwitchUserListener($container, $id, $config, $defaultProvider)
609+
private function createSwitchUserListener($container, $id, $config, $defaultProvider, $stateless)
606610
{
607611
$userProvider = isset($config['provider']) ? $this->getUserProviderId($config['provider']) : $defaultProvider;
608612

613+
// in 4.0, ignore the `switch_user.stateless` key if $stateless is `true`
614+
if ($stateless && false === $config['stateless']) {
615+
@trigger_error(sprintf('Firewall "%s" is configured as "stateless" but the "switch_user.stateless" key is set to false. Both should have the same value, the firewall\'s "stateless" value will be used as default value for the "switch_user.stateless" key in 4.0.', $id), E_USER_DEPRECATED);
616+
}
617+
609618
$switchUserListenerId = 'security.authentication.switchuser_listener.'.$id;
610619
$listener = $container->setDefinition($switchUserListenerId, new ChildDefinition('security.authentication.switchuser_listener'));
611620
$listener->replaceArgument(1, new Reference($userProvider));
612621
$listener->replaceArgument(2, new Reference('security.user_checker.'.$id));
613622
$listener->replaceArgument(3, $id);
614623
$listener->replaceArgument(6, $config['parameter']);
615624
$listener->replaceArgument(7, $config['role']);
625+
$listener->replaceArgument(9, $config['stateless']);
616626

617627
return $switchUserListenerId;
618628
}

src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@
230230
<argument>_switch_user</argument>
231231
<argument>ROLE_ALLOWED_TO_SWITCH</argument>
232232
<argument type="service" id="event_dispatcher" on-invalid="null"/>
233+
<argument>false</argument> <!-- Stateless -->
233234
</service>
234235

235236
<service id="security.access_listener" class="Symfony\Component\Security\Http\Firewall\AccessListener">

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public function testFirewalls()
116116
array(
117117
'parameter' => '_switch_user',
118118
'role' => 'ROLE_ALLOWED_TO_SWITCH',
119+
'stateless' => true,
119120
),
120121
),
121122
array(

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@
6060
),
6161

6262
'firewalls' => array(
63-
'simple' => array('pattern' => '/login', 'security' => false),
63+
'simple' => array('provider' => 'default', 'pattern' => '/login', 'security' => false),
6464
'secure' => array('stateless' => true,
65+
'provider' => 'default',
6566
'http_basic' => true,
6667
'form_login' => true,
6768
'anonymous' => true,
68-
'switch_user' => true,
69+
'switch_user' => array('stateless' => true),
6970
'x509' => true,
7071
'remote_user' => true,
7172
'logout' => true,
@@ -74,6 +75,7 @@
7475
'logout_on_user_change' => true,
7576
),
7677
'host' => array(
78+
'provider' => 'default',
7779
'pattern' => '/test',
7880
'host' => 'foo\\.example\\.org',
7981
'methods' => array('GET', 'POST'),
@@ -82,6 +84,7 @@
8284
'logout_on_user_change' => true,
8385
),
8486
'with_user_checker' => array(
87+
'provider' => 'default',
8588
'user_checker' => 'app.user_checker',
8689
'anonymous' => true,
8790
'http_basic' => true,

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/no_custom_user_checker.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
'http_basic' => true,
1818
'form_login' => true,
1919
'anonymous' => true,
20-
'switch_user' => true,
20+
'switch_user' => array('stateless' => true),
2121
'x509' => true,
2222
'remote_user' => true,
2323
'logout' => true,

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,26 @@
4343
<chain providers="service, basic" />
4444
</provider>
4545

46-
<firewall name="simple" pattern="/login" security="false" />
46+
<firewall name="simple" pattern="/login" security="false" provider="default" />
4747

48-
<firewall name="secure" stateless="true">
48+
<firewall name="secure" stateless="true" provider="default">
4949
<http-basic />
5050
<form-login />
5151
<anonymous />
52-
<switch-user />
52+
<switch-user stateless="true" />
5353
<x509 />
5454
<remote-user />
5555
<user-checker />
5656
<logout />
5757
<remember-me secret="TheSecret"/>
5858
</firewall>
5959

60-
<firewall name="host" pattern="/test" host="foo\.example\.org" methods="GET,POST" logout-on-user-change="true">
60+
<firewall name="host" pattern="/test" host="foo\.example\.org" methods="GET,POST" logout-on-user-change="true" provider="default">
6161
<anonymous />
6262
<http-basic />
6363
</firewall>
6464

65-
<firewall name="with_user_checker" logout-on-user-change="true">
65+
<firewall name="with_user_checker" logout-on-user-change="true" provider="default">
6666
<anonymous />
6767
<http-basic />
6868
<user-checker>app.user_checker</user-checker>

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/no_custom_user_checker.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<http-basic />
1818
<form-login />
1919
<anonymous />
20-
<switch-user />
20+
<switch-user stateless="true" />
2121
<x509 />
2222
<remote-user />
2323
<user-checker />

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ security:
4343
firewalls:
4444
simple: { pattern: /login, security: false }
4545
secure:
46+
provider: default
4647
stateless: true
4748
http_basic: true
4849
form_login: true
4950
anonymous: true
50-
switch_user: true
51+
switch_user:
52+
stateless: true
5153
x509: true
5254
remote_user: true
5355
logout: true
@@ -56,6 +58,7 @@ security:
5658
user_checker: ~
5759

5860
host:
61+
provider: default
5962
pattern: /test
6063
host: foo\.example\.org
6164
methods: [GET,POST]
@@ -64,6 +67,7 @@ security:
6467
logout_on_user_change: true
6568

6669
with_user_checker:
70+
provider: default
6771
anonymous: ~
6872
http_basic: ~
6973
user_checker: app.user_checker

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/no_custom_user_checker.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ security:
1212
http_basic: true
1313
form_login: true
1414
anonymous: true
15-
switch_user: true
15+
switch_user:
16+
stateless: true
1617
x509: true
1718
remote_user: true
1819
logout: true

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,57 @@ public function testDeprecationForUserLogout()
148148
$container->compile();
149149
}
150150

151+
/**
152+
* @group legacy
153+
* @expectedDeprecation Firewall "some_firewall" is configured as "stateless" but the "switch_user.stateless" key is set to false. Both should have the same value, the firewall's "stateless" value will be used as default value for the "switch_user.stateless" key in 4.0.
154+
*/
155+
public function testSwitchUserNotStatelessOnStatelessFirewall()
156+
{
157+
$container = $this->getRawContainer();
158+
159+
$container->loadFromExtension('security', array(
160+
'providers' => array(
161+
'default' => array('id' => 'foo'),
162+
),
163+
164+
'firewalls' => array(
165+
'some_firewall' => array(
166+
'stateless' => true,
167+
'http_basic' => null,
168+
'switch_user' => array('stateless' => false),
169+
'logout_on_user_change' => true,
170+
),
171+
),
172+
));
173+
174+
$container->compile();
175+
}
176+
177+
/**
178+
* @group legacy
179+
* @expectedDeprecation Firewall "default" has no "provider" set but multiple providers exist. Using the first configured provider (first) is deprecated since 3.4 and will throw an exception in 4.0, set the "provider" key on the firewall instead.
180+
*/
181+
public function testDeprecationForAmbiguousProvider()
182+
{
183+
$container = $this->getRawContainer();
184+
185+
$container->loadFromExtension('security', array(
186+
'providers' => array(
187+
'first' => array('id' => 'foo'),
188+
'second' => array('id' => 'bar'),
189+
),
190+
191+
'firewalls' => array(
192+
'default' => array(
193+
'http_basic' => null,
194+
'logout_on_user_change' => true,
195+
),
196+
),
197+
));
198+
199+
$container->compile();
200+
}
201+
151202
protected function getRawContainer()
152203
{
153204
$container = new ContainerBuilder();

src/Symfony/Bundle/SecurityBundle/Tests/Functional/SwitchUserTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\SecurityBundle\Tests\Functional;
1313

14+
use Symfony\Component\HttpFoundation\JsonResponse;
1415
use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
1516

1617
class SwitchUserTest extends WebTestCase
@@ -50,6 +51,18 @@ public function testSwitchedUserExit()
5051
$this->assertEquals('user_can_switch', $client->getProfile()->getCollector('security')->getUser());
5152
}
5253

54+
public function testSwitchUserStateless()
55+
{
56+
$client = $this->createClient(array('test_case' => 'JsonLogin', 'root_config' => 'switchuser_stateless.yml'));
57+
$client->request('POST', '/chk', array('_switch_user' => 'dunglas'), array(), array('CONTENT_TYPE' => 'application/json'), '{"user": {"login": "user_can_switch", "password": "test"}}');
58+
$response = $client->getResponse();
59+
60+
$this->assertInstanceOf(JsonResponse::class, $response);
61+
$this->assertSame(200, $response->getStatusCode());
62+
$this->assertSame(array('message' => 'Welcome @dunglas!'), json_decode($response->getContent(), true));
63+
$this->assertSame('dunglas', $client->getProfile()->getCollector('security')->getUser());
64+
}
65+
5366
public function getTestParameters()
5467
{
5568
return array(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
imports:
2+
- { resource: ./config.yml }
3+
4+
security:
5+
providers:
6+
in_memory:
7+
memory:
8+
users:
9+
user_can_switch: { password: test, roles: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH] }
10+
firewalls:
11+
main:
12+
switch_user:
13+
stateless: true

0 commit comments

Comments
 (0)