Description
Description
Depending on the used firewall I want to implement some logic. Currently there is no good way to get the current name of the firewall.
The firewall listener does set a attribute called _firewall_context
which is for example firewall name extranet
something like security.firewall.map.context.extranet
so it would be something like if (str_ends_with(...
check which feels very strange.
Also in my case the _firewall_context
attribute is not set at the time I need to register mycustom listener. I need to control a custom $request->attribute
depending on the firewall name before the UserProvider
is called. It seems the listener which calls the UserProvider and is setting the _firewall_context
is the same. So no way to inject between.
The current workaround here I found:
This requires to inject the FirewallMap
and call a method which is not part of the FirewallMapInterface
and so can make problems if is somebody would decorate that service (logger).
What would be the expected behaviour. I think the best would be have first a listener which would set the a _firewall_name
attribute on the $request
object. With a higher priority then the FirewallListener
itself. So somebody can create a listener between matching of the firewall and calling firewall specific logic (userprovider, login, logout, ...).
Another way would providing an additoinal method on the Security
service to return the current FirewallName
.
Example
Custom Listener
This shows the following example of such a listener
<?php
declare(strict_types=1);
namespace App\Access\Infrastructure\Sulu\Security;
use App\Access\Infrastructure\Sulu\Admin\ExtranetAdmin;
use Sulu\Bundle\SecurityBundle\System\SystemStoreInterface;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Http\FirewallMapInterface;
class SecuritySystemSubscriber implements EventSubscriberInterface
{
private FirewallMap $map;
private SystemStoreInterface $systemStore;
public function __construct(
SystemStoreInterface $systemStore,
FirewallMapInterface $map,
) {
$this->systemStore = $systemStore;
if (!$map instanceof FirewallMap) {
throw new \LogicException(\sprintf('Expected "%s" but got "%s".', FirewallMap::class, \get_class($map)));
}
$this->map = $map;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => [
// need to be after @see \Sulu\Bundle\SecurityBundle\EventListener\SystemListener::getSubscribedEvents
// need to be before @see \Symfony\Bundle\SecurityBundle\EventListener\FirewallListener::getSubscribedEvents
['processSecuritySystem', 9],
],
];
}
public function processSecuritySystem(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}
// this is strange as it is not part of the FirewallMapInterface
$config = $this->map->getFirewallConfig($event->getRequest());
if (!$config) {
return;
}
if ('extranet' === $config->getName()) {
$this->systemStore->setSystem(ExtranetAdmin::SYSTEM);
}
}
}