Log auth success only on login on stateful firewalls

master
Lars Vierbergen 7 years ago
parent 85e202506a
commit 8375e626d3
  1. 59
      EventListener/AuthenticationStatsListener.php
  2. 1
      EventListener/LoginStatsListener.php
  3. 1
      Resources/config/services.xml

@ -28,6 +28,10 @@ use vierbergenlars\AuthserverStatsBundle\Entity\AuthenticationEntry;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class AuthenticationStatsListener implements EventSubscriberInterface
{
@ -44,35 +48,66 @@ class AuthenticationStatsListener implements EventSubscriberInterface
*/
private $requestStack;
/**
*
* @var FirewallMapInterface
*/
private $firewallMap;
public static function getSubscribedEvents()
{
return [
StatsEvent::class => [
[
'getAuthStats',
-1
]
],
AuthenticationEvents::AUTHENTICATION_SUCCESS => [
'onAuthSuccess'
'getAuthStats',
-1
],
AuthenticationEvents::AUTHENTICATION_FAILURE => [
'onAuthFailure'
]
AuthenticationEvents::AUTHENTICATION_SUCCESS => 'onAuthSuccess',
AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthFailure',
SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin'
];
}
public function __construct(RegistryInterface $registry, RequestStack $requestStack)
public function __construct(RegistryInterface $registry, RequestStack $requestStack, FirewallMapInterface $firewallMap)
{
$this->registry = $registry;
$this->requestStack = $requestStack;
$this->firewallMap = $firewallMap;
}
public function onInteractiveLogin(InteractiveLoginEvent $event)
{
if ($this->isStatelessFirewall())
return;
$request = $this->requestStack->getMasterRequest();
$authSuccess = new AuthenticationEntry($request->getClientIp(), true);
$em = $this->registry->getManagerForClass(AuthenticationEntry::class);
$em->persist($authSuccess);
$em->flush($authSuccess);
}
private function isStatelessFirewall()
{
$request = $this->requestStack->getMasterRequest();
if ($this->firewallMap instanceof FirewallMap) {
$config = $this->firewallMap->getFirewallConfig($request);
/* @var $config \Symfony\Bundle\SecurityBundle\Security\FirewallConfig */
if ($config) {
if ($config->isStateless())
return true;
}
}
return false;
}
public function onAuthSuccess(AuthenticationEvent $event)
{
if ($event->getAuthenticationToken() instanceof AnonymousToken)
return;
$authSuccess = new AuthenticationEntry($this->requestStack->getMasterRequest()->getClientIp(), true);
if (!$this->isStatelessFirewall())
return;
$request = $this->requestStack->getMasterRequest();
$authSuccess = new AuthenticationEntry($request->getClientIp(), true);
$em = $this->registry->getManagerForClass(AuthenticationEntry::class);
$em->persist($authSuccess);
$em->flush($authSuccess);

@ -25,7 +25,6 @@ use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use vierbergenlars\AuthserverStatsBundle\Entity\LoginEntry;
use Symfony\Component\Security\Core\AuthenticationEvents;
class LoginStatsListener implements EventSubscriberInterface
{

@ -34,6 +34,7 @@
<service class="vierbergenlars\AuthserverStatsBundle\EventListener\AuthenticationStatsListener">
<argument type="service" id="doctrine" />
<argument type="service" id="request_stack" />
<argument type="service" id="security.firewall.map" />
<tag name="kernel.event_subscriber" />
</service>
</services>