Reputation: 800
I'm attempting to write a custom auth checker for Symfony5. This is to run on selected Controllers, all of which have an AuthenticationControllerInterface
which includes numerous other bits of relevant code.
I am attempting to use an EventSubscriber bound to the ControllerEvent
. This checks for this interface and identifies correctly the relevant controllers.
Please see the below for context:
class BearerTokenSubscriber implements EventSubscriberInterface
{
public function onKernelController(ControllerEvent $event)
{
$controller = $event->getController();
// load the controller
if (is_array($controller)) {
$controller = $controller[0];
if ($controller instanceof AuthenticationControllerInterface) {
if(
// my assorted auth functionality: works as expected
) {
//... where my question lies:
}
}
}
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
];
}
}
At "where my question lies": is the point I want to do a redirect... in the following ways (in order of preference):
Thanks in advance.
Upvotes: 0
Views: 985
Reputation: 800
The specific answer in my case was:
if (/* some test logic */) {
$event->stopPropagation();
$event->setController(
static function () use ($controller) {
return $controller->some403ErrorResponse();
}
);
}
Many thanks to Jeroen who pointed me in the correct direction. Have marked his as correct also.
Upvotes: 0
Reputation: 724
You can use ControllerEvent::setController($myController)
to provide a controller of your choice once your conditions are met:
class TestControllerEventSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
$events = [];
$events[KernelEvents::CONTROLLER] = ['onKernelController', 0];
return $events;
}
public function onKernelController(ControllerEvent $event): void
{
$controller = $this->getControllerObjectFromEvent($event);
// Check if your conditions are met
if ($controller instanceof AuthenticationControllerInterface && $whateverElse) {
$event->stopPropagation();
// Set your custom controller that produces a 403 response
$event->setController(static function () {
return new Response(null, 403);
});
}
}
private function getControllerObjectFromEvent(ControllerEvent $event): ?object
{
$controller = $event->getController();
if (true === is_object($controller)) {
return (object) $controller;
}
if (false === is_array($controller)) {
return null;
}
foreach ($controller as $value) {
if (true === is_object($value)) {
return $value;
}
}
return null;
}
}
Upvotes: 1