Skip to content

Commit afc2ed8

Browse files
committed
Also use authentication failure/success handlers in FormLoginAuthenticator
1 parent bdadfe2 commit afc2ed8

File tree

3 files changed

+29
-46
lines changed

3 files changed

+29
-46
lines changed

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
}

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
}

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)