Reputation: 789
I'm working on a custom "Access Control", that has to do with certain logic, rather than roles.
If specific options has been set in the database, user can proceed, if not he needs to be redirect to a certain page from any place in the system, regardless of the way (navigation, direct URL, etc.).
So far I've created a SecurityListener that basically pulls the options from the database via the onSecurityInteractiveLogin()
method and stores them in the Security context, so that I can access them at any time, from anywhere. That part works as expected.
Now I don't know where to add the logic for redirecting. I was thinking about adding new reponse listener and modifying the onKernelResponse()
method, but it doesn't seem to work. This is what I have so far:
namespace MyProj\UserBundle\EventListener;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
class ResponseListener
{
public function __construct(SecurityContextInterface $security, Session $session, RouterInterface $router)
{
$this->security = $security;
$this->session = $session;
$this->router = $router;
}
public function onKernelResponse(FilterResponseEvent $event)
{
//$response = $event->getResponse();
//$event->setResponse($response);
return new RedirectResponse($this->router->generate('intro_page'));
}
In my service.xml file I describe the service as follows:
<service id="response.listener" class="MyProj\UserBundle\EventListener\ResponseListener">
<tag name="kernel.event_listener" event="response" method="onKernelResponse" />
<argument type="service" id="security.context" />
<argument type="service" id="session" />
<argument type="service" id="router" />
</service>
It doesn't really do anything. Am I missing something and am I using the correct approach? I'm open to any suggestion, thanks.
Upvotes: 1
Views: 618
Reputation: 9546
Try with AccessListener
like this:
class AccessListener
{
private$security;
private $router;
public function __construct($security, $router)
{
$this->security = $security;
$this->router = $router;
}
public function onKernelRequest(GetResponseEvent $event)
{
if ($this->security->isGranted('PINK_UNICORN')) {
$url = $this->router->generate('pink_unicorn_totorial');
$event->setResponse(new RedirectResponse($url));
}
}
}
Add it to your services.yml :
services:
access_listener:
class: Acme\DemoBundle\Listener\AccessListener
arguments: [ @security.context, @router ]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
Upvotes: 0
Reputation: 900
Not sure about sf 2.5 but i think your event name should be "kernel.response" not just "response".
Also i would use rather kernelRequest instead of Response, so you will save some process which in definitive are not relevant.
Upvotes: 0