Symfony2:登录尝试失败后获取 "username"
Symfony2: Getting the "username" after an unsuccessful login attempt
我使用 Symfony2 和 FOSUserBundle。
我想防止对登录页面的暴力攻击。
为此,我在事件上创建了一个侦听器:
AuthenticationEvents::AUTHENTICATION_FAILURE
除了 IP,我还想获得用户在尝试登录时传递的 "username"。这样我就可以得到一些黑客试图破解帐户的用户。还考虑到同一个 IP 可以属于多个用户,我可以通过这种方式区分,如果我在一秒钟内进行 5 次尝试,如果我真的面临攻击,或者只是有 5 个用户大致同时无法通过身份验证(但也许 "behind" 该地址有 150 个用户,所以它可能会发生;))。
有什么方法可以获取表单中传递的用户名吗?
当然,在记录IP、用户名和时间戳后,我需要实现将可疑IP添加到黑名单的部分table。然后我必须决定是实施选民,还是禁止 IP 我让我的应用程序写入 Apache 配置文件。
谢谢!
我惊讶地发现解决方案围绕我正在做的 类 进行了一些挖掘。
我只需要做:
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 只是登录数据库
我使用 Symfony2 和 FOSUserBundle。
我想防止对登录页面的暴力攻击。
为此,我在事件上创建了一个侦听器:
AuthenticationEvents::AUTHENTICATION_FAILURE
除了 IP,我还想获得用户在尝试登录时传递的 "username"。这样我就可以得到一些黑客试图破解帐户的用户。还考虑到同一个 IP 可以属于多个用户,我可以通过这种方式区分,如果我在一秒钟内进行 5 次尝试,如果我真的面临攻击,或者只是有 5 个用户大致同时无法通过身份验证(但也许 "behind" 该地址有 150 个用户,所以它可能会发生;))。
有什么方法可以获取表单中传递的用户名吗?
当然,在记录IP、用户名和时间戳后,我需要实现将可疑IP添加到黑名单的部分table。然后我必须决定是实施选民,还是禁止 IP 我让我的应用程序写入 Apache 配置文件。
谢谢!
我惊讶地发现解决方案围绕我正在做的 类 进行了一些挖掘。
我只需要做:
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 只是登录数据库