Skip to content

Commit 6ba8ec6

Browse files
committed
Added automatically CSRF protected authenticators
1 parent 37b70cc commit 6ba8ec6

File tree

4 files changed

+94
-10
lines changed

4 files changed

+94
-10
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@
6464
<argument /> <!-- stateless firewall keys -->
6565
</service>
6666

67+
<service id="Symfony\Component\Security\Http\EventListener\CsrfProtectionListener">
68+
<tag name="kernel.event_subscriber" />
69+
<argument type="service" id="security.csrf.token_manager" />
70+
</service>
71+
6772
<service id="security.listener.remember_me"
6873
class="Symfony\Component\Security\Http\EventListener\RememberMeListener"
6974
abstract="true">
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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\Authenticator;
13+
14+
/**
15+
* This interface can be implemented to automatically add CSF
16+
* protection to the authenticator.
17+
*
18+
* @author Wouter de Jong <wouter@wouterj.nl>
19+
*/
20+
interface CsrfProtectedAuthenticatorInterface
21+
{
22+
/**
23+
* An arbitrary string used to generate the value of the CSRF token.
24+
* Using a different string for each authenticator improves its security.
25+
*/
26+
public function getCsrfTokenId(): string;
27+
28+
/**
29+
* Returns the CSRF token contained in credentials if any.
30+
*
31+
* @param mixed $credentials The credentials returned by getCredentials()
32+
*/
33+
public function getCsrfToken($credentials): ?string;
34+
}

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* @final
3333
* @experimental in 5.1
3434
*/
35-
class FormLoginAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
35+
class FormLoginAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface, CsrfProtectedAuthenticatorInterface
3636
{
3737
use TargetPathTrait;
3838

@@ -113,17 +113,15 @@ public function getUser($credentials): ?UserInterface
113113
return $this->userProvider->loadUserByUsername($credentials['username']);
114114
}
115115

116-
/* @todo How to do CSRF protection?
117-
public function checkCredentials($credentials, UserInterface $user): bool
116+
public function getCsrfTokenId(): string
118117
{
119-
if (null !== $this->csrfTokenManager) {
120-
if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['csrf_token_id'], $credentials['csrf_token']))) {
121-
throw new InvalidCsrfTokenException('Invalid CSRF token.');
122-
}
123-
}
118+
return $this->options['csrf_token_id'];
119+
}
124120

125-
return $this->checkPassword($credentials, $user);
126-
}*/
121+
public function getCsrfToken($credentials): ?string
122+
{
123+
return $credentials['csrf_token'];
124+
}
127125

128126
public function createAuthenticatedToken(UserInterface $user, $providerKey): TokenInterface
129127
{
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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\EventListener;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
16+
use Symfony\Component\Security\Csrf\CsrfToken;
17+
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
18+
use Symfony\Component\Security\Http\Authenticator\CsrfProtectedAuthenticatorInterface;
19+
use Symfony\Component\Security\Http\Event\VerifyAuthenticatorCredentialsEvent;
20+
21+
class CsrfProtectionListener implements EventSubscriberInterface
22+
{
23+
private $csrfTokenManager;
24+
25+
public function __construct(CsrfTokenManagerInterface $csrfTokenManager)
26+
{
27+
$this->csrfTokenManager = $csrfTokenManager;
28+
}
29+
30+
public static function getSubscribedEvents(): array
31+
{
32+
return [VerifyAuthenticatorCredentialsEvent::class => ['verifyCredentials', 256]];
33+
}
34+
35+
public function verifyCredentials(VerifyAuthenticatorCredentialsEvent $event): void
36+
{
37+
$authenticator = $event->getAuthenticator();
38+
if (!$authenticator instanceof CsrfProtectedAuthenticatorInterface) {
39+
return;
40+
}
41+
42+
$csrfToken = new CsrfToken($authenticator->getCsrfTokenId(), $authenticator->getCsrfToken($event->getPreAuthenticatedToken()->getCredentials()));
43+
if (false === $this->csrfTokenManager->isTokenValid($csrfToken)) {
44+
throw new InvalidCsrfTokenException('Invalid CSRF token.');
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy