Ich arbeite daran, die Audit-Protokollierung zu einem Symfony2-Projekt hinzuzufügen, das alle Seitenladevorgänge protokolliert und Anforderungen in eine benutzerdefinierte Audit-Tabelle schreibt. Das Projekt verwendet die Standard-Abmelderoute für Symfony2 (Besuch/Abmeldung), die die Sitzung zerstört und dann zur Route/login umleitet.Symfony2 Logout Event Listener Problem
Für onKernelRequest ist ein Ereignis-Listener eingerichtet, der die richtigen Daten in die Tabelle schreibt. In der Datei security.yml habe ich für die Abmelderoute folgendes aufgelistet:
security:
firewalls:
main:
logout:
path: /logout
target: /login
Die Überwachungsprotokollierung funktioniert für alle Seiten außer dem Abmeldeereignis. Nach dem Abmelden habe ich versucht, den Profiler zu besuchen und dann die '/ logout' Aktion aus der "Letzte 10" Option in der Seitenleiste auszuwählen. Wenn Sie auf "Events" klicken, werden die Standard-Symfony-Ereignisse für kernel.request wie der DebugHandler und der ProfileListener aufgelistet, aber mein benutzerdefinierter Callback wird unter der Registerkarte "Nicht aufgerufene Listener" angezeigt.
Es gibt einen success_handler, der der security.yml-Datei hinzugefügt werden kann, aber ich würde eine Methode benötigen, die meinen Ereignis-Listener ausführen kann, bevor die Sitzung zerstört wird. Gibt es eine Möglichkeit, den vorhandenen Listener auch das Abmeldeereignis aufzuzeichnen, bevor Symfony die Abmeldung durchführt?
bearbeiten
<?php
// src/AuditBundle/EventListener/AuditListener.php
namespace AuditBundle\EventListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RequestStack;
use AuditBundle\Entity\AuditLog;
class AuditListener
{
protected $requestStack;
protected $em;
protected $tokenStorage;
protected $authorizationChecker;
public function __construct(RequestStack $requestStack, \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage $tokenStorage, $authorizationChecker, \Doctrine\ORM\EntityManager $em = NULL)
{
$this->requestStack = $requestStack;
$this->em = $em;
$this->tokenStorage = $tokenStorage;
$this->authorizationChecker = $authorizationChecker;
}
public function onKernelRequest(GetResponseEvent $response)
{
$request = $response->getRequest();
if (strpos($request->getRequestUri(), 'fonts') !== false)
return;
if (strpos($request->getRequestUri(), 'css') !== false)
return;
if (strpos($request->getRequestUri(), '_wdt') !== false)
return;
if (strpos($request->getRequestUri(), 'js') !== false)
return;
if (strpos($request->getRequestUri(), '_profiler') !== false)
return;
$this->log('Request', $request);
}
public function postUpdate(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->em = $args->getEntityManager();
$className = $this->em->getClassMetadata(get_class($entity))->getName();
if ($entity instanceof \AuditBundle\Entity\AuditLog)
return;
$this->log($className.' Updated', $this->requestStack->getCurrentRequest(), $entity);
}
public function postPersist(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->em = $args->getEntityManager();
$className = $this->em->getClassMetadata(get_class($entity))->getName();
if ($entity instanceof \AuditBundle\Entity\AuditLog)
return;
$this->log($className.' Created', $this->requestStack->getCurrentRequest(), $entity);
}
public function postDelete(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->em = $args->getEntityManager();
$className = $this->em->getClassMetadata(get_class($entity))->getName();
if ($entity instanceof \AuditBundle\Entity\AuditLog)
return;
$this->log($className.' Deleted', $this->requestStack->getCurrentRequest());
}
protected function log($message, $request, $entity = NULL)
{
$log = new AuditLog();
$log->setType($request->getRealMethod());
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY'))
{
$log->setUser($this->tokenStorage->getToken()->getUser());
}
if ($entity)
{
$log->setEntityId($entity->getId());
}
$log->setUriString($request->getRequestUri());
$log->setMessage($message);
$log->setDatetime(new \DateTime());
$log->setIp($request->getClientIp());
$log->setBrowser(isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
$this->em->persist($log);
$this->em->flush();
}
}
services.yml
services:
audits.audit_listener:
class: AuditBundle\EventListener\AuditListener
arguments: [@request_stack, @security.token_storage, @security.authorization_checker, @doctrine.orm.entity_manager]
tags:
- { name: kernel.event_listener, event: kernel.request }
Können Sie Ihre benutzerdefinierte Callback-Klasse und ihren Service bieten? – Jeet
Sie müssen LogoutHandlerInterface implementieren und der Config mitteilen, dass Sie einen Abmelde-Handler haben, siehe meine Antwort unten – Prof83