我使用Symfony2和FOSUserBundle。
我想防止登录页面上的暴力攻击。
为此我在事件上创建了一个监听器:
AuthenticationEvents::AUTHENTICATION_FAILURE
除了IP之外我还希望得到"用户名"用户在尝试记录时通过了。通过这种方式,我可以获得一些黑客试图入侵该帐户的用户。同时考虑到同一个IP可以属于多个用户,我可以通过这种方式进行区分,如果我在一秒内完成5次尝试,如果我真的面临攻击,或者只是有5个用户大致同时失败进行身份验证(但可能"背后"该地址有150个用户,因此可能会发生;))。
有什么方法可以获得表单中传递的用户名吗?
当然,在记录IP,用户名和时间戳之后,我需要实现将可疑IP添加到黑名单表的部分。然后,我必须决定是否实施选民,或者禁止IP使我的应用程序编写Apache配置文件。
谢谢!
答案 0 :(得分:6)
我惊讶地发现解决方案在我正在做的事情上挖掘了一些类。
我只需要这样做:
public function onAuthenticationFailure( AuthenticationFailureEvent $event )
{
$token = $event->getAuthenticationToken();
$username = $token->getUsername();
// DO STUFF ON DB
}
编辑:我的听众的完整代码
class LoginListener implements EventSubscriberInterface
{
protected $entityManager;
protected $container;
protected $logger;
public function __construct($entityManager, $container, $logger)
{
$this->em = $entityManager;
$this->container = $container;
$this->logger = $logger;
}
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::SECURITY_IMPLICIT_LOGIN => 'onImplicitLogin',
SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthenticationFailure',
);
}
public function onImplicitLogin(UserEvent $event)
{
// LOG THE SUCCESSFUL LOGIN
$user = $event->getUser();
$this->writeSuccessfulLog($user);
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
// LOG THE SUCCESSFUL LOGIN
$user = $event->getAuthenticationToken()->getUser(); // the difference with the one above is $user = $event->getUser();
$this->writeSuccessfulLog($user);
}
public function onAuthenticationFailure( AuthenticationFailureEvent $event )
{
// LOG THE FAILED LOGIN
$token = $event->getAuthenticationToken();
$username = $token->getUsername();
$container = $this->container;
$em = $this->em;
$request = $container->get('request');
$ip = $request->getClientIp();
$userAgent = $request->headers->get('User-Agent');
$now = new \DateTime();
$failedLogin = new FailedLogin();
$failedLogin->setIp($ip);
$failedLogin->setTimestamp($now);
$failedLogin->setUsername($username);
$failedLogin->setUserAgent($userAgent);
$em->persist($failedLogin);
$em->flush();
}
方法writeSuccessfulLog只需登录DB