I'm creating configured maintenance page.
I created an event subscriber:
public function onKernelRequest(RequestEvent $event)
{
$maintenance = $this->container->hasParameter('maintenance') ? $this->container->getParameter('maintenance') : false;
$underMaintenanceUntil = $this->container->hasParameter('underMaintenanceUntil') ? $this->container->getParameter('underMaintenanceUntil') : false;
if (!$event->isMasterRequest()){
return;
}
$debug = in_array($this->container->get('kernel')->getEnvironment(), ['test','dev']);
$uri = $event->getRequest()->getRequestUri();
if ($uri == '/login' || $uri == '/logout') {
return;
}
if ($maintenance && !$debug && !$this->container->get('security.authorization_checker')->isGranted('ROLE_ADMIN')) {
$engine = $this->container->get('twig');
$content = $engine->render('pages/maintenance.html.twig', array('underMaintenanceUntil' => $underMaintenanceUntil));
$event->setResponse(new Response($content, 503));
$event->stopPropagation();
}
}
And profiler bar doesn't work. I get
An error occurred while loading the web debug toolbar.
In log:
[Application] Oct 5 08:24:41 |INFO | REQUES Matched route "_wdt". method="GET" request_uri="https://localhost:8001/_wdt/914ef7" route="_wdt" route_parameters={"_controller":"web_profiler.controller.profiler::toolbarAction","_route":"_wdt","token":"914ef7"} [Application] Oct 5 08:24:41 |CRITICA| REQUES Uncaught PHP Exception Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException: "The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL." at /home/marcin/projects/indali/vendor/symfony/security-core/Authorization/AuthorizationChecker.php line 52
And even if I type /login
page I get the same error. Should't this if ($uri == '/login' || $uri == '/logout') {return;}
prevents to not executing further code if it is login uri?
This $this->container->get('security.authorization_checker')->isGranted('ROLE_ADMIN')
generates my errors because in dev firewall there is no auth token. I can check if token exists but why doesn't my code work?.
Your code doesn't work because the profiler is a separate request from the main request to either
/login
or/logout
.The profiler bar is loaded via an AJAX request to a different URL. If you check your security configuration, the default is usually:
Profiler calls are the ones that go through
_profiler
or_wdt
. So your check forlogin
orlogout
URL is simply not useful for this. It affects the main request, but no the profiler bar request:Some options are, from worse to better:
Check the token
As you mention, check that the token is not null, but that may not work as you expect, since it will end up allowing anonymous users reach your site when "under maintenance".
Check the URL Path
Cheap and simple: check the request path against the
dev
pattern (or against_(profiler|wdt)
at least). This should be easy to incorporate in your code, but could conceivably be problematic in the future if you end up adding another non-secured firewall:Check the
FirewallConfig
for the requestIf you want to do it cleanly, you should inject
FirewallMap
in your event subscriber, and get the firewall for the request.A simple example which you would need to adapt to your own needs:
Since the
FirewallMap
is not auto-wireable, you'll need to configure the service to inject it explicitly:or in old school YAML:
In your case, it seems you are doing away with dependency injection and retrieving the container directly. Albeit that's a bad practice and you should change it if possible, with your current code you could simply get it from
$this-container->get('security.firewall.map');