Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ public function addConfiguration(NodeDefinition $node)
$builder
->scalarNode('check_route')
->isRequired()
->info('Route that will validate the login link - e.g. app_login_link_verify.')
->info('Route that will validate the login link - e.g. "app_login_link_verify".')
->end()
->scalarNode('check_post_only')
->defaultFalse()
->info('If true, only HTTP POST requests to "check_route" will be handled by the authenticator.')
->end()
->arrayNode('signature_properties')
->isRequired()
Expand Down Expand Up @@ -128,6 +132,7 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
->replaceArgument(3, new Reference($this->createAuthenticationFailureHandler($container, $firewallName, $config)))
->replaceArgument(4, [
'check_route' => $config['check_route'],
'check_post_only' => $config['check_post_only'],
]);

return $authenticatorId;
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Security/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CHANGELOG
* Added translator to `\Symfony\Component\Security\Http\Authenticator\JsonLoginAuthenticator` and `\Symfony\Component\Security\Http\Firewall\UsernamePasswordJsonAuthenticationListener` to translate authentication failure messages
* Added a CurrentUser attribute to force the UserValueResolver to resolve an argument to the current user.
* Added `LoginThrottlingListener`.
* Added `LoginLinkAuthenticator`.

5.1.0
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,18 @@ public function __construct(LoginLinkHandlerInterface $loginLinkHandler, HttpUti
$this->httpUtils = $httpUtils;
$this->successHandler = $successHandler;
$this->failureHandler = $failureHandler;
$this->options = $options;
$this->options = $options + ['check_post_only' => false];
}

public function supports(Request $request): ?bool
{
return $this->httpUtils->checkRequestPath($request, $this->options['check_route']);
return ($this->options['check_post_only'] ? $request->isMethod('POST') : true)
&& $this->httpUtils->checkRequestPath($request, $this->options['check_route']);
}

public function authenticate(Request $request): PassportInterface
{
$username = $request->get('user');

if (!$username) {
throw new InvalidLoginLinkAuthenticationException('Missing user from link.');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ protected function setUp(): void
$this->failureHandler = $this->createMock(AuthenticationFailureHandlerInterface::class);
}

/**
* @dataProvider provideSupportData
*/
public function testSupport(array $options, $request, bool $supported)
{
$this->setUpAuthenticator($options);

$this->assertEquals($supported, $this->authenticator->supports($request));
}

public function provideSupportData()
{
yield [['check_route' => '/validate_link'], Request::create('/validate_link?hash=abc123'), true];
yield [['check_route' => '/validate_link'], Request::create('/login?hash=abc123'), false];
yield [['check_route' => '/validate_link', 'check_post_only' => true], Request::create('/validate_link?hash=abc123'), false];
yield [['check_route' => '/validate_link', 'check_post_only' => true], Request::create('/validate_link?hash=abc123', 'POST'), true];
}

public function testSuccessfulAuthenticate()
{
$this->setUpAuthenticator();
Expand Down