src/EventSubscriber/SecuritySubscriber.php line 69

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\Log;
  4. use App\Entity\SysUsers;
  5. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  6. use Symfony\Component\Security\Core\AuthenticationEvents;
  7. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  8. /*use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;*/
  9. use Symfony\Component\Security\Http\Event\LoginFailureEvent;
  10. use Symfony\Component\Security\Core\Event\AuthenticationEvent;
  11. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  12. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  13. use Symfony\Component\Security\Http\SecurityEvents;
  14. use Symfony\Component\HttpFoundation\RequestStack;
  15. use Doctrine\ORM\EntityManagerInterface;
  16. use Psr\Log\LoggerInterface;
  17. /**
  18.  * Subscribes to the following security events :
  19.  *      - AuthenticationEvents::AUTHENTICATION_FAILURE
  20.  *      - SecurityEvents::INTERACTIVE_LOGIN
  21.  *
  22.  * So it can log successful and failed login
  23.  * Some informations here: https://thisdata.com/blog/subscribing-to-symfonys-security-events/
  24.  *
  25.  * Class SecuritySubscriber
  26.  * @package App\EventSubscriber
  27.  */
  28. class SecuritySubscriber implements EventSubscriberInterface
  29. {
  30.     private $entityManager;
  31.     private $tokenStorage;
  32.     private $authenticationUtils;
  33.     private $logger;
  34.     private $requestStack;
  35.     public function __construct(LoggerInterface $logger, EntityManagerInterface $entityManager, TokenStorageInterface $tokenStorage, AuthenticationUtils $authenticationUtils, RequestStack $requestStack)
  36.     {
  37.         $this->entityManager = $entityManager;
  38.         $this->tokenStorage = $tokenStorage;
  39.         $this->authenticationUtils = $authenticationUtils;
  40.         $this->logger = $logger;
  41.         $this->requestStack = $requestStack;
  42.     }
  43.     public static function getSubscribedEvents()
  44.     {
  45.         return array(
  46.             //AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthenticationFailure',
  47.             SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
  48.         );
  49.     }
  50.     public function onAuthenticationFailure( LoginFailureEvent $event )
  51.     {
  52.         $username = $this->authenticationUtils->getLastUsername();
  53.         $existingUser = $this->entityManager->getRepository(SysUsers::class)->findOneBy(['username' => $username]);
  54.         if ($existingUser) {
  55.             $message = "Log In Denied: Wrong password for User #" . $existingUser->getId()  . " (" . $existingUser->getEmail() . ")";
  56.             $this->logger->error($message);
  57.         } else {
  58.             $message = "Log In Denied: User doesn't exist: " . $username;
  59.             $this->logger->error($message);
  60.         }
  61.         $this->addEntry($message, $username);
  62.     }
  63.     public function onSecurityInteractiveLogin( InteractiveLoginEvent $event )
  64.     {
  65.         $user = $this->tokenStorage->getToken()->getUser();
  66.         $message = "Log In Granted: User #" . $user->getId()  . " (" . $user->getEmail() . ")";
  67.         $this->logger->info($message);
  68.         $this->addEntry($message, $user->getEmail());
  69.     }
  70.     private function addEntry($message, $username="")
  71.     {
  72.         $ip = $this->requestStack->getCurrentRequest()->getClientIp();
  73.         if($ip == 'unknown'){
  74.             $ip = $_SERVER['REMOTE_ADDR'];
  75.         }
  76.         $entry = new Log();
  77.         $entry->setIp($ip);
  78.         $entry->setUsername($username);
  79.         $entry->setMessage($message);
  80.         $this->entityManager->persist($entry);
  81.         $this->entityManager->flush();
  82.     }
  83. }