Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 60d396f

Browse filesBrowse files
committed
Added automatically CSRF protected authenticators
1 parent bf1a452 commit 60d396f
Copy full SHA for 60d396f

File tree

Expand file treeCollapse file tree

4 files changed

+99
-10
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+99
-10
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.xml
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@
6464
<argument type="abstract">stateless firewall keys</argument>
6565
</service>
6666

67+
<service id="security.listener.csrf_protection" class="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">
+34Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php
+8-10Lines 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 AbstractLoginFormAuthenticator implements PasswordAuthenticatedInterface
35+
class FormLoginAuthenticator extends AbstractLoginFormAuthenticator 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
{
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 function verifyCredentials(VerifyAuthenticatorCredentialsEvent $event): void
31+
{
32+
$authenticator = $event->getAuthenticator();
33+
if (!$authenticator instanceof CsrfProtectedAuthenticatorInterface) {
34+
return;
35+
}
36+
37+
$csrfTokenValue = $authenticator->getCsrfToken($event->getCredentials());
38+
if (null === $csrfTokenValue) {
39+
return;
40+
}
41+
42+
$csrfToken = new CsrfToken($authenticator->getCsrfTokenId(), $csrfTokenValue);
43+
if (false === $this->csrfTokenManager->isTokenValid($csrfToken)) {
44+
throw new InvalidCsrfTokenException('Invalid CSRF token.');
45+
}
46+
}
47+
48+
public static function getSubscribedEvents(): array
49+
{
50+
return [VerifyAuthenticatorCredentialsEvent::class => ['verifyCredentials', 256]];
51+
}
52+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.