Я работаю над пользовательским «Контролем доступа», который связан с определенной логикой, а не ролями.
Если в базе данных были заданы определенные параметры, пользователь может продолжить, если нет необходимости перенаправлять его на определенную страницу из любой размещать в системе независимо от способа (навигация, прямой URL и т. д.).
До сих пор я создал SecurityListener который в основном тянет варианты из базы данных через onSecurityInteractiveLogin()
метод и сохраняет их в контексте безопасности, так что я могу получить к ним доступ в любое время, из любого места. Эта часть работает как ожидалось.
Теперь я не знаю, где добавить логику для перенаправления. Я думал о добавлении нового слушателя отклика и модификации onKernelResponse()
метод, но это не похоже на работу. Это то, что я до сих пор:
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'));
}
В моем service.xml Файл, описывающий услугу следующим образом:
<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>
Это на самом деле ничего не делает. Я что-то упустил, и я использую правильный подход? Я открыт для любых предложений, спасибо.
Не уверен насчет sf 2.5, но я думаю, что ваше имя события должно быть «kernel.response», а не просто «response».
Также я бы использовал скорее kernelRequest вместо Response, так что вы сохраните некоторый процесс, который в окончательном виде не имеет отношения к делу.
Попробуй с AccessListener
как это:
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));
}
}
}
Добавьте его в ваши services.yml:
services:
access_listener:
class: Acme\DemoBundle\Listener\AccessListener
arguments: [ @security.context, @router ]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }