Symfony2:获取"用户名"登录尝试失败后

时间:2015-04-30 16:42:47

标签: symfony fosuserbundle brute-force

我使用Symfony2和FOSUserBundle。

我想防止登录页面上的暴力攻击。

为此我在事件上创建了一个监听器:

AuthenticationEvents::AUTHENTICATION_FAILURE

除了IP之外我还希望得到"用户名"用户在尝试记录时通过了。通过这种方式,我可以获得一些黑客试图入侵该帐户的用户。同时考虑到同一个IP可以属于多个用户,我可以通过这种方式进行区分,如果我在一秒内完成5次尝试,如果我真的面临攻击,或者只是有5个用户大致同时失败进行身份验证(但可能"背后"该地址有150个用户,因此可能会发生;))。

有什么方法可以获得表单中传递的用户名吗?

当然,在记录IP,用户名和时间戳之后,我需要实现将可疑IP添加到黑名单表的部分。然后,我必须决定是否实施选民,或者禁止IP使我的应用程序编写Apache配置文件。

谢谢!

1 个答案:

答案 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