8000 Also use authentication failure/success handlers in FormLoginAuthenti… · symfony/symfony@9ea32c4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9ea32c4

Browse files
committed
Also use authentication failure/success handlers in FormLoginAuthenticator
1 parent 0fe5083 commit 9ea32c4

File tree

6 files changed

+36
-49
lines changed

6 files changed

+36
-49
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ abstract class AbstractFactory implements SecurityFactoryInterface
3030
'check_path' => '/login_check',
3131
'use_forward' => false,
3232
'require_previous_session' => false,
33+
'login_path' => '/login',
3334
];
3435

3536
protected $defaultSuccessHandlerOptions = [

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,13 @@ public function createEntryPoint(ContainerBuilder $container, string $id, array
100100
public function createAuthenticator(ContainerBuilder $container, string $id, array $config, string $userProviderId): string
101101
{
102102
$authenticatorId = 'security.authenticator.form_login.'.$id;
103-
$defaultOptions = array_merge($this->defaultSuccessHandlerOptions, $this->options);
104-
$options = array_merge($defaultOptions, array_intersect_key($config, $defaultOptions));
103+
$options = array_intersect_key($config, $this->options);
105104
$container
106105
->setDefinition($authenticatorId, new ChildDefinition('security.authenticator.form_login'))
107106
->replaceArgument(1, new Reference($userProviderId))
108-
->replaceArgument(2, $options);
107+
->replaceArgument(2, new Reference($this->createAuthenticationSuccessHandler($container, $id, $config)))
108+
->replaceArgument(3, new Reference($this->createAuthenticationFailureHandler($container, $id, $config)))
109+
->replaceArgument(4, $options);
109110

110111
return $authenticatorId;
111112
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@
9595
abstract="true">
9696
<argument type="service" id="security.http_utils" />
9797
<argument type="abstract">user provider</argument>
98+
<argument type="abstract">authentication success handler</argument>
99+
<argument type="abstract">authentication failure handler</argument>
98100
<argument type="abstract">options</argument>
99101
</service>
100102

src/Symfony/Component/Security/Http/Authenticator/AbstractLoginFormAuthenticator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ abstract class AbstractLoginFormAuthenticator extends AbstractAuthenticator impl
3030
/**
3131
* Return the URL to the login page.
3232
*/
33-
abstract protected function getLoginUrl(): string;
33+
abstract protected function getLoginUrl(Request $request): string;
3434

3535
/**
3636
* Override to change what happens after a bad username/password is submitted.
@@ -41,7 +41,7 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio
4141
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
4242
}
4343

44-
$url = $this->getLoginUrl();
44+
$url = $this->getLoginUrl($request);
4545

4646
return new RedirectResponse($url);
4747
}
@@ -52,7 +52,7 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio
5252
*/
5353
public function start(Request $request, AuthenticationException $authException = null): Response
5454
{
55-
$url = $this->getLoginUrl();
55+
$url = $this->getLoginUrl($request);
5656

5757
return new RedirectResponse($url);
5858
}

src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
1717
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1818
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
19+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
1920
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
2021
use Symfony\Component\Security\Core\Security;
2122
use Symfony\Component\Security\Core\User\UserInterface;
2223
use Symfony\Component\Security\Core\User\UserProviderInterface;
24+
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
25+
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
2326
use Symfony\Component\Security\Http\HttpUtils;
2427
use Symfony\Component\Security\Http\ParameterBagUtils;
25-
use Symfony\Component\Security\Http\Util\TargetPathTrait;
2628

2729
/**
2830
* @author Wouter de Jong <wouter@wouterj.nl>
@@ -33,34 +35,32 @@
3335
*/
3436
class FormLoginAuthenticator extends AbstractLoginFormAuthenticator implements PasswordAuthenticatedInterface, CsrfProtectedAuthenticatorInterface
3537
{
36-
use TargetPathTrait;
37-
38-
private $options;
3938
private $httpUtils;
4039
private $userProvider;
40+
private $successHandler;
41+
private $failureHandler;
42+
private $options;
4143

42-
public function __construct(HttpUtils $httpUtils, UserProviderInterface $userProvider, array $options)
44+
public function __construct(HttpUtils $httpUtils, UserProviderInterface $userProvider, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options)
4345
{
4446
$this->httpUtils = $httpUtils;
47+
$this->userProvider = $userProvider;
48+
$this->successHandler = $successHandler;
49+
$this->failureHandler = $failureHandler;
4550
$this->options = array_merge([
4651
'username_parameter' => '_username',
4752
'password_parameter' => '_password',
48-
'csrf_parameter' => '_csrf_token',
49-
'csrf_token_id' => 'authenticate',
53+
'check_path' => '/login_check',
5054
'post_only' => true,
5155

52-
'always_use_default_target_path' => false,
53-
'default_target_path' => '/',
54-
'login_path' => '/login',
55-
'target_path_parameter' => '_target_path',
56-
'use_referer' => false,
56+
'csrf_parameter' => '_csrf_token',
57+
'csrf_token_id' => 'authenticate',
5758
], $options);
58-
$this->userProvider = $userProvider;
5959
}
6060

61-
protected function getLoginUrl(): string
61+
protected function getLoginUrl(Request $request): string
6262
{
63-
return $this->options['login_path'];
63+
return $this->httpUtils->generateUri($request, $this->options['login_path']);
6464
}
6565

6666
public function supports(Request $request): bool
@@ -122,36 +122,13 @@ public function createAuthenticatedToken(UserInterface $user, $providerKey): Tok
122122
return new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());
123123
}
124124

125-
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): Response
125+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response
126126
{
127-
return $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request, $providerKey));
127+
return $this->successHandler->onAuthenticationSuccess($request, $token);
128128
}
129129

130-
private function determineTargetUrl(Request $request, string $providerKey)
130+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): Response
131131
{
132-
if ($this->options['always_use_default_target_path']) {
133-
return $this->options['default_target_path'];
134-
}
135-
136-
if ($targetUrl = ParameterBagUtils::getRequestParameterValue($request, $this->options['target_path_parameter'])) {
137-
return $targetUrl;
138-
}
139-
140-
if ($targetUrl = $this->getTargetPath($request->getSession(), $providerKey)) {
141-
$this->removeTargetPath($request->getSession(), $providerKey);
142-
143-
return $targetUrl;
144-
}
145-
146-
if ($this->options['use_referer'] && $targetUrl = $request->headers->get('Referer')) {
147-
if (false !== $pos = strpos($targetUrl, '?')) {
148-
$targetUrl = substr($targetUrl, 0, $pos);
149-
}
150-
if ($targetUrl && $targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) {
151-
return $targetUrl;
152-
}
153-
}
154-
155-
return $this->options['default_target_path'];
132+
return $this->failureHandler->onAuthenticationFailure($request, $exception);
156133
}
157134
}

src/Symfony/Component/Security/Http/Tests/Authenticator/FormLoginAuthenticatorTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,23 @@
1717
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
1818
use Symfony\Component\Security\Core\Security;
1919
use Symfony\Component\Security\Core\User\UserProviderInterface;
20+
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
21+
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
2022
use Symfony\Component\Security\Http\Authenticator\FormLoginAuthenticator;
2123
use Symfony\Component\Security\Http\HttpUtils;
2224

2325
class FormLoginAuthenticatorTest extends TestCase
2426
{
2527
private $userProvider;
28+
private $successHandler;
29+
private $failureHandler;
2630
private $authenticator;
2731

2832
protected function setUp(): void
2933
{
3034
$this->userProvider = $this->createMock(UserProviderInterface::class);
35+
$this->successHandler = $this->createMock(AuthenticationSuccessHandlerInterface::class);
36+
$this->failureHandler = $this->createMock(AuthenticationFailureHandlerInterface::class);
3137
}
3238

3339
/**
@@ -123,7 +129,7 @@ public function postOnlyDataProvider()
123129

124130
private function setUpAuthenticator(array $options = [])
125131
{
126-
$this->authenticator = new FormLoginAuthenticator(new HttpUtils(), $this->userProvider, $options);
132+
$this->authenticator = new FormLoginAuthenticator(new HttpUtils(), $this->userProvider, $this->successHandler, $this->failureHandler, $options);
127133
}
128134

129135
private function createSession()

0 commit comments

Comments
 (0)
0