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 69c0089

Browse filesBrowse files
author
Kevin Weber
committed
Merge branch '4373_Document_Security_Events' of github.com:kevintweber/symfony-docs into 4373_Document_Security_Events
2 parents a14bd07 + f15bea4 commit 69c0089
Copy full SHA for 69c0089

File tree

Expand file treeCollapse file tree

2 files changed

+118
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+118
-0
lines changed

‎cookbook/security/index.rst

Copy file name to clipboardExpand all lines: cookbook/security/index.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ Security
2222
csrf_in_login_form
2323
access_control
2424
multiple_user_providers
25+
throttle_failed_login
+117Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
.. index::
2+
single: Security; Throttle Failed Login
3+
4+
How to Throttle Failed Login Attempts
5+
=====================================
6+
7+
Sometimes, it's useful to throttle login attempts when you encounter multiple
8+
recent failed logins. This can be useful in combatting brute-force
9+
password-guessing login attacks. This can be done by implementing a
10+
``security.authentication.failure`` listener to log failed login attempts, and
11+
a security provider decorator to deny login attempts from the same IP address.
12+
13+
Authentication Failure Listener
14+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15+
16+
The purpose of this authentication failure listener is to persist the ip address
17+
and any other data of the client. The example here uses a doctrine table to
18+
persist the data, but you could use another method (Redis, for example).
19+
20+
.. code-block:: php
21+
22+
namespace AppBundle\Security\Authentication\Listener;
23+
24+
use Doctrine\ORM\EntityRepositoryInterface;
25+
use Symfony\Component\HttpFoundation\RequestStack;
26+
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
27+
28+
class LogFailedLoginAttempt
29+
{
30+
/**
31+
* The doctrine repository to which the failed login attempt will be
32+
* persisted.
33+
*
34+
* @var EntityRepositoryInterface
35+
*/
36+
private $repository;
37+
38+
/**
39+
* The current request contains the ip address and other $_SERVER globals
40+
* to persist.
41+
*
42+
* @var RequestStack
43+
*/
44+
private $requestStack;
45+
46+
public function __construct(RequestStack $requestStack, EntityRepositoryInterface $repository)
47+
{
48+
$this->repository = $repository;
49+
$this->requestStack = $requestStack;
50+
}
51+
52+
public function onAuthenticationFailureEvent(AuthenticationFailureEvent $event)
53+
{
54+
$this->repository->logAuthenicationFailure(
55+
$event->getToken(),
56+
$this->requestStack->getCurrentRequest()
57+
);
58+
}
59+
}
60+
61+
Now you are logging all the relevant details about every failed login attempt.
62+
63+
Security Provider Decorator
64+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
65+
66+
This security provider will decorate another security provider and will reject
67+
any authentication attempts it needs to throttle.
68+
69+
.. code-block:: php
70+
71+
namespace AppBundle\Security\Authentication\Provider;
72+
73+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
74+
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
75+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
76+
77+
class LoginThrottleProvider implements AuthenticationProviderInterface
78+
{
79+
/**
80+
* @var AuthenticationProviderInterface
81+
*/
82+
private $decoratedProvider;
83+
84+
/**
85+
* The throttle service decides whether to throttle a certain
86+
* ip address or not.
87+
*/
88+
private $throttleService;
89+
90+
public function __construct(AuthenticationProviderInterface $provider, $throttleService)
91+
{
92+
$this->decoratedProvider = $provider;
93+
$this->throttleService = $throttleService;
94+
}
95+
96+
public function authenticate(TokenInterface $token)
97+
{
98+
if ($this->throttleService->isThrottled($token)) {
99+
throw new AuthenticationException(
100+
'Too many failed authentication attempts.'
101+
);
102+
}
103+
104+
return $this->decoratedProvider->authenticate($token);
105+
}
106+
107+
public function supports(TokenInterface $token)
108+
{
109+
return $this->decoratedProvider->supports($token);
110+
}
111+
}
112+
113+
The implementation of the throttle service is outside the scope of this
114+
documentation and will depend on your application's needs. It is common
115+
for an application to require additional means of authentication when
116+
multiple failed logins are detected, such as the addition of a CAPTCHA
117+
to the login page, or requiring two-factor authentication.

0 commit comments

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