2015-04-30 3 views
2

Я использую Symfony2 и FOSUserBundle.Symfony2: получение «имени пользователя» после неудачной попытки входа в систему

Я хочу предотвратить атаки грубой силы на странице входа.

Для этого я создал слушателя на событие:

AuthenticationEvents::AUTHENTICATION_FAILURE 

Помимо IP я хотел бы получить также «имя пользователя», что пользователь прошел при попытке войти. Таким образом, я могу получить пользователя, которого хакер пытается взломать. Также учитывая, что один и тот же IP-адрес может принадлежать нескольким пользователям, я могу таким образом различать, если я получу 5 попыток за секунду, если я действительно сталкиваюсь с атакой или просто есть 5 пользователей, которые примерно в то же время не могут аутентифицироваться (но, может быть, «позади» этого адреса есть 150 пользователей, так что это может произойти;)).

Есть ли способ получить имя пользователя в форме?

Конечно, после регистрации IP, имени пользователя и временной метки мне нужно реализовать часть, где я добавляю подозрительный IP-адрес в таблицу черного списка. Тогда мне нужно будет решить, следует ли реализовать Voter или запретить IP-адрес моего приложения, которое напишет файл конфигурации Apache.

Спасибо!

ответ

6

Я неожиданно обнаружил, что решение немного копается в классах вокруг того, что я делаю.

Я просто сделать:

public function onAuthenticationFailure(AuthenticationFailureEvent $event) 
{ 
    $token = $event->getAuthenticationToken(); 
    $username = $token->getUsername(); 
    // DO STUFF ON DB 
} 

EDIT: Полный код моего слушателя по просьбе

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 просто входит в БД

+0

Я перед тем же вопрос, так как вы являетесь одним из первых результатов в Google, не могли бы вы немного разобраться в своем решении? – BastienSander

+1

Там вы ходите @BastienSander;) –

 Смежные вопросы

  • Нет связанных вопросов^_^