8000 [Security] made it possible to override the default success/failure h… · symfony/symfony@167c3f2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 167c3f2

Browse files
committed
[Security] made it possible to override the default success/failure handler (take 2)
1 parent 36116fc commit 167c3f2

File tree

8 files changed

+149
-90
lines changed

8 files changed

+149
-90
lines changed

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,17 @@ protected function createListener($container, $id, $config, $userProvider)
170170

171171
protected function createAuthenticationSuccessHandler($container, $id, $config)
172172
{
173+
$successHandlerId = $this->getSuccessHandlerId($id);
174+
$options = array_intersect_key($config, $this->defaultSuccessHandlerOptions);
175+
173176
if (isset($config['success_handler'])) {
174-
$successHandlerId = $config['success_handler'];
175-
$successHandler = $container->findDefinition($successHandlerId);
177+
$successHandler = $container->setDefinition($successHandlerId, new DefinitionDecorator('security.authentication.custom_success_handler'));
178+
$successHandler->replaceArgument(0, new Reference($config['success_handler']));
179+
$successHandler->replaceArgument(1, $options);
180+
$successHandler->replaceArgument(2, $id);
176181
} else {
177-
$successHandlerId = $this->getSuccessHandlerId($id);
178182
$successHandler = $container->setDefinition($successHandlerId, new DefinitionDecorator('security.authentication.success_handler'));
179-
}
180-
181-
if ($successHandler instanceof DefinitionDecorator && 'security.authentication.success_handler' === $successHandler->getParent()) {
182-
$successHandler->addMethodCall('setOptions', array(array_intersect_key($config, $this->defaultSuccessHandlerOptions)));
183+
$successHandler->addMethodCall('setOptions', array($options));
183184
$successHandler->addMethodCall('setProviderKey', array($id));
184185
}
185186

@@ -188,16 +189,16 @@ protected function createAuthenticationSuccessHandler($container, $id, $config)
188189

189190
protected function createAuthenticationFailureHandler($container, $id, $config)
190191
{
192+
$id = $this->getFailureHandlerId($id);
193+
$options = array_intersect_key($config, $this->defaultFailureHandlerOptions);
194+
191195
if (isset($config['failure_handler'])) {
192-
$id = $config['failure_handler'];
193-
$failureHandler = $container->findDefinition($id);
196+
$failureHandler = $container->setDefinition($id, new DefinitionDecorator('security.authentication.custom_failure_handler'));
197+
$failureHandler->replaceArgument(0, new Reference($config['failure_handler']));
198+
$failureHandler->replaceArgument(1, $options);
194199
} else {
195-
$id = $this->getFailureHandlerId($id);
196200
$failureHandler = $container->setDefinition($id, new DefinitionDecorator('security.authentication.failure_handler'));
197-
}
198-
199-
if ($failureHandler instanceof DefinitionDecorator && 'security.authentication.failure_handler' === $failureHandler->getParent()) {
200-
$failureHandler->addMethodCall('setOptions', array(array_intersect_key($config, $this->defaultFailureHandlerOptions)));
201+
$failureHandler->addMethodCall('setOptions', array($options));
201202
}
202203

203204
return $id;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646

4747
<parameter key="security.authentication.success_handler.class">Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler</parameter>
4848
<parameter key="security.authentication.failure_handler.class">Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler</parameter>
49+
<parameter key="security.authentication.custom_success_handler.class">Symfony\Component\Security\Http\Authentication\CustomAuthenticationSuccessHandler</parameter>
50+
<parameter key="security.authentication.custom_failure_handler.class">Symfony\Component\Security\Http\Authentication\CustomAuthenticationFailureHandler</parameter>
4951
<parameter key="security.authentication.simple_success_failure_handler.class">Symfony\Component\Security\Http\Authentication\SimpleAuthenticationHandler</parameter>
5052
</parameters>
5153

@@ -120,11 +122,22 @@
120122
<argument type="service" id="event_dispatcher" on-invalid="null" />
121123
</service>
122124

125+
<service id="security.authentication.custom_success_handler" class="%security.authentication.custom_success_handler.class%" abstract="true" public="false">
126+
<argument /> <!-- The custom success handler service id -->
127+
<argument type="collection" /> <!-- Options -->
128+
<argument /> <!-- Provider-shared Key -->
129+
</service>
130+
123131
<service id="security.authentication.success_handler" class="%security.authentication.success_handler.class%" abstract="true" public="false">
124132
<argument type="service" id="security.http_utils" />
125133
<argument type="collection" /> <!-- Options -->
126134
</service>
127135

136+
<service id="security.authentication.custom_failure_handler" class="%security.authentication.custom_failure_handler.class%" abstract="true" public="false">
137+
<argument /> <!-- The custom failure handler service id -->
138+
<argument type="collection" /> <!-- Options -->
139+
</service>
140+
128141
<service id="security.authentication.failure_handler" class="%security.authentication.failure_handler.class%" abstract="true" public="false">
129142
<tag name="monolog.logger" channel="security" />
130143
<argument type="service" id="http_kernel" />

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ public function testCreate()
3636
$definition = $container->getDefinition('abstract_listener.foo');
3737
$this->assertEquals(array(
3838
'index_4' => 'foo',
39-
'index_5' => new Reference('custom_success_handler'),
40-
'index_6' => new Reference('custom_failure_handler'),
39+
'index_5' => new Reference('security.authentication.success_handler.foo.abstract_factory'),
40+
'index_6' => new Reference('security.authentication.failure_handler.foo.abstract_factory'),
4141
'index_7' => array(
4242
'use_forward' => true,
4343
),
@@ -50,7 +50,7 @@ public function testCreate()
5050
/**
5151
* @dataProvider getFailureHandlers
5252
*/
53-
public function testDefaultFailureHandler($handlerId, $serviceId, $defaultHandlerInjection)
53+
public function testDefaultFailureHandler($serviceId, $defaultHandlerInjection)
5454
{
5555
$options = array(
5656
'remember_me' => true,
@@ -65,7 +65,7 @@ public function testDefaultFailureHandler($handlerId, $serviceId, $defaultHandle
6565

6666
$definition = $container->getDefinition('abstract_listener.foo');
6767
$arguments = $definition->getArguments();
68-
$this->assertEquals(new Reference($handlerId), $arguments['index_6']);
68+
$this->assertEquals(new Reference('security.authentication.failure_handler.foo.abstract_factory'), $arguments['index_6']);
6969
$failureHandler = $container->findDefinition((string) $arguments['index_6']);
7070

7171
$methodCalls = $failureHandler->getMethodCalls();
@@ -80,16 +80,15 @@ public function testDefaultFailureHandler($handlerId, $serviceId, $defaultHandle
8080
public function getFailureHandlers()
8181
{
8282
return array(
83-
array('security.authentication.failure_handler.foo.abstract_factory', null, true),
84-
array('custom_failure_handler_default', 'custom_failure_handler_default', true),
85-
array('custom_failure_handler', 'custom_failure_handler', false),
83+
array(null, true),
84+
array('custom_failure_handler', false),
8685
);
8786
}
8887

8988
/**
9089
* @dataProvider getSuccessHandlers
9190
*/
92-
public function testDefaultSuccessHandler($handlerId, $serviceId, $defaultHandlerInjection)
91+
public function testDefaultSuccessHandler($serviceId, $defaultHandlerInjection)
9392
{
9493
$options = array(
9594
'remember_me' => true,
@@ -104,7 +103,7 @@ public function testDefaultSuccessHandler($handlerId, $serviceId, $defaultHandle
104103

105104
$definition = $container->getDefinition('abstract_listener.foo');
106105
$arguments = $definition->getArguments();
107-
$this->assertEquals(new Reference($handlerId), $arguments['index_5']);
106+
$this->assertEquals(new Reference('security.authentication.success_handler.foo.abstract_factory'), $arguments['index_5']);
108107
$successHandler = $container->findDefinition((string) $arguments['index_5']);
109108
$methodCalls = $successHandler->getMethodCalls();
110109

@@ -121,9 +120,8 @@ public function testDefaultSuccessHandler($handlerId, $serviceId, $defaultHandle
121120
public function getSuccessHandlers()
122121
{
123122
return array(
124-
array('security.authentication.success_handler.foo.abstract_factory', null, true),
125-
array('custom_success_handler_default', 'custom_success_handler_default', true),
126-
array('custom_success_handler', 'custom_success_handler', false),
123+
array(null, true),
124+
array('custom_success_handler', false),
127125
);
128126
}
129127

@@ -151,8 +149,6 @@ protected function callFactory($id, $config, $userProviderId, $defaultEntryPoint
151149
$container->register('auth_provider');
152150
$container->register('custom_success_handler');
153151
$container->register('custom_failure_handler');
154-
$container->setDefinition('custom_success_handler_default', new DefinitionDecorator('security.authentication.success_handler'));
155-
$container->setDefinition('custom_failure_handler_default', new DefinitionDecorator('security.authentication.failure_handler'));
156152

157153
list($authProviderId, $listenerId, $entryPointId) = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId);
158154

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/localized_form_failure_handler.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
imports:
22
- { resource: ./../config/default.yml }
33

4-
services:
5-
localized_form_failure_handler: { class: stdClass }
6-
74
security:
85
encoders:
96
Symfony\Component\Security\Core\User\User: plaintext
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Http\Authentication;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
16+
17+
/**
18+
* @author Fabien Potencier <fabien@symfony.com>
19+
*/
20+
class CustomAuthenticationFailureHandler implements AuthenticationFailureHandlerInterface
21+
{
22+
private $handler;
23+
24+
/**
25+
* Constructor.
26+
*
27+
* @param array $options Options for processing a failed authentication attempt
28+
*/
29+
public function __construct(AuthenticationFailureHandlerInterface $handler, array $options)
30+
{
31+
$this->handler = $handler;
32+
if (method_exists($handler, 'setOptions')) {
33+
$this->handler->setOptions($options);
34+
}
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
41+
{
42+
return $this->handler->onAuthenticationFailure($request, $exception);
43+
}
44+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Http\Authentication;
13+
14+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
15+
use Symfony\Component\HttpFoundation\Request;
16+
17+
/**
18+
* @author Fabien Potencier <fabien@symfony.com>
19+
*/
20+
class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
21+
{
22+
private $handler;
23+
24+
/**
25+
* Constructor.
26+
*
27+
* @param array $options Options for processing a successful authentication attempt
28+
* @param string $providerKey The provider key
29+
*/
30+
public function __construct(array $options, $providerKey)
31+
{
32+
$this->handler = $handler;
33+
if (method_exists($handler, 'setOptions')) {
34+
$this->handler->setOptions($options);
35+
}
36+
if (method_exists($providerKey, 'setProviderKey')) {
37+
$this->handler->setProviderKey($providerKey);
38+
}
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
45+
{
46+
return $this->handler->onAuthenticationSuccess($request, $token);
47+
}
48+
}

src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationFailureHandler.php

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
3434
protected $httpUtils;
3535
protected $logger;
3636
protected $options;
37-
protected $defaultOptions = array(
38-
'failure_path' => null,
39-
'failure_forward' => false,
40-
'login_path' => '/login',
41-
'failure_path_parameter' => '_failure_path',
42-
);
4337

4438
/**
4539
* Constructor.
@@ -49,32 +43,18 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
4943
* @param array $options Options for processing a failed authentication attempt.
5044
* @param LoggerInterface $logger Optional logger
5145
*/
52-
public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options = array(), LoggerInterface $logger = null)
46+
public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options, LoggerInterface $logger = null)
5347
{
5448
$this->httpKernel = $httpKernel;
55-
$this->httpUtils = $httpUtils;
56-
$this->logger = $logger;
57-
$this->setOptions($options);
58-
}
49+
$this->httpUtils = $httpUtils;
50+
$this->logger = $logger;
5951

60-
/**
61-
* Gets the options.
62-
*
63-
* @return array An array of options
64-
*/
65-
public function getOptions()
66-
{
67-
return $this->options;
68-
}
69-
70-
/**
71-
* Sets the options.
72-
*
73-
* @param array $options An array of options
74-
*/
75-
public function setOptions(array $options)
76-
{
77-
$this->options = array_merge($this->defaultOptions, $options);
52+
$this->options = array_merge(array(
53+
'failure_path' => null,
54+
97AE 'failure_forward' => false,
55+
'login_path' => '/login',
56+
'failure_path_parameter' => '_failure_path',
57+
), $options);
7858
}
7959

8060
/**

src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,24 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
2727
protected $httpUtils;
2828
protected $options;
2929
protected $providerKey;
30-
protected $defaultOptions = array(
31-
'always_use_default_target_path' => false,
32-
'default_target_path' => '/',
33-
'login_path' => '/login',
34-
'target_path_parameter' => '_target_path',
35-
'use_referer' => false,
36-
);
3730

3831
/**
3932
* Constructor.
4033
*
4134
* @param HttpUtils $httpUtils
4235
* @param array $options Options for processing a successful authentication attempt.
4336
*/
44-
public function __construct(HttpUtils $httpUtils, array $options = array())
37+
public function __construct(HttpUtils $httpUtils, array $options)
4538
{
46-
$this->httpUtils = $httpUtils;
47-
$this->setOptions($options);
39+
$this->httpUtils = $httpUtils;
40+
41+
$this->options = array_merge(array(
42+
'always_use_default_target_path' => false,
43+
'default_target_path' => '/',
44+
'login_path' => '/login',
45+
'target_path_parameter' => '_target_path',
46+
'use_referer' => false,
47+
), $options);
4848
}
4949

5050
/**
@@ -55,26 +55,6 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token)
5555
return $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request));
5656
}
5757

58-
/**
59-
* Gets the options.
60-
*
61-
* @return array An array of options
62-
*/
63-
public function getOptions()
64-
{
65-
return $this->options;
66-
}
67-
68-
/**
69-
* Sets the options.
70-
*
71-
* @param array $options An array of options
72-
*/
73-
public function setOptions(array $options)
74-
{
75-
$this->options = array_merge($this->defaultOptions, $options);
76-
}
77-
7858
/**
7959
* Get the provider key.
8060
*

0 commit comments

Comments
 (0)
0