<?php/** * Security Subscriber * * @author Gideon Oudhuis <g.oudhuis@visualmedia.nl> */namespace VisualMedia\UserBundle\EventSubscriber;use Symfony\Component\Cache\Adapter\AdapterInterface;use Symfony\Component\HttpFoundation\RequestStack;use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;use Symfony\Component\Security\Core\AuthenticationEvents;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\Security\Core\Exception\AccessDeniedException;use Symfony\Component\Security\Http\SecurityEvents;use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;/** * Security Subscriber * * Subscriber to monitor the failed login attempts. * * @deprecated since bugfix/ssi-login-validation, system using cache login block attemps build into * BaseLoginFormAuthenticator method onAuthenticationFailure => bruteForceSecurity */class SecuritySubscriber implements EventSubscriberInterface{ /** * Cache * @var AdapterInterface */ protected $cache; /** * Request Stack * @var RequestStack */ protected $requestStack; /** * Constructor * * @param AdapterInterface $cache * @param RequestStack $requestStack */ public function __construct(AdapterInterface $cache, RequestStack $requestStack) { $this->cache = $cache; $this->requestStack = $requestStack; } /** * Get Subscribed Events * * getSubscribedEvents Event withs te subscriber listens to. */ public static function getSubscribedEvents(): array { return array( AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthenticationFailure', SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin', ); } /** * On Security Interactive login * * onSecurityInteractiveLogin register if login user has to many login _attemps. * * @param InteractiveLoginEvent $event * * @throws \Psr\Cache\InvalidArgumentException */ public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void { $request = $this->requestStack->getCurrentRequest(); $count = 0; $route = $request->get('_route'); $ip = $request->getClientIp(); $cacheitem = $this->cache->getItem(sprintf('%s_%s_attemps', $route, $ip)); $cache_count = $cacheitem->get(); if ($cache_count['count'] ?? null) { $count = $cache_count['count']; } if ($count >= 1){ throw new AccessDeniedException('Login has been blocked'); } } /** * On Authentication Failure * * onAuthenticationFailure event that trigger if a users authentication fails. * * @param AuthenticationFailureEvent $event * * @throws \Psr\Cache\InvalidArgumentException */ public function onAuthenticationFailure(AuthenticationFailureEvent $event): void { $request = $this->requestStack->getCurrentRequest(); $route = $request->get('_route'); $ip = $request->getClientIp(); $cacheitem = $this->cache->getItem(sprintf('%s_%s_attemps', $route, $ip)); $cacheitem->expiresAfter(300); $cache_count = $cacheitem->get(); $count = $cache_count[$ip]; if ($count === null) { $count = 0; } $count++; $cacheitem->set(array( $this->requestStack->getCurrentRequest()->getClientIp() => $count, )); $this->cache->save($cacheitem); }}