To capture the request before the controller I have done:
public function onKernelController (ControllerEvent $ event)
And there I can return an error (401) or do nothing and let it continue to the controller.
$event->getRequest()->attributes->set('id', '33');
I don't know how to pass an object as a parameter to the controller. But the main problem is that the method is executed 2 times with each request, and I don't know why
To validate the token I call a micro service.
Listen to these 2 events on services.yalm:
App\Listener\FirewallTokenController:
tags:
- { name: kernel.event_listener, event: kernel.controller }
App\Listener\FirewallTokenRequest:
tags:
- { name: kernel.event_listener, event: kernel.request }
FirewallTokenRequest runs first. In it you can retrieve the token or tokens and perform the verification. If the token is correct we do nothing and let the execution continue, but if the token is not correct we introduce a custom error that we can recover in FirewallTokenController and do the redirection.
If in FirewallTokenRequest the token is not correct we insert the error:
public function onKernelRequest(RequestEvent $event) {
$request = $event->getRequest();
...
.....
if (badToken){
$request->attributes->set("FirewallTokenEvent", "401");
} else {
//Enter the user or any data that is needed in the Controller
$request->attributes->set("idUser", $idUser);
$request->attributes->set("email", $email);
$request->attributes->set("locale", $locale);
}
}
From FirewallTokenController we look for the error, if we find it we can redirect:
$this->classesExcluded = array("Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController");
public function onKernelController(ControllerEvent $event) {
$controller = $event->getController(); (deprecated)
//In each request this class is executed 2 times, this makes it possible to execute it only once.
if (!is_array($controller) || HttpKernelInterface::MASTER_REQUEST != $event->getRequestType() || in_array(get_class($controller[0]), $this->classesExcluded)) {
return;
}
if ($request->attributes->has('FirewallTokenEvent')) {
$response = intval($request->attributes->get('FirewallTokenEvent'));
if ($response == 401) { //Unathorizated
$redirectUrl = 'unauthorized';
$event->setController(function () use($redirectUrl) {
return new RedirectResponse($redirectUrl);
});
}
Retrieve the user (or any data) entered in FirewallTokenRequest from the Controller:
$idUser = intval($request->attributes->get('idUser'));
$email = $request->attributes->get('email');
$locale = $request->attributes->get('locale');