Symfony http basic auth for debugging on live server
When deploying a Symfony application you usually remove the dev environment for security reasons. Which of course makes it more difficult to debug the system if there are errors occurring.
An easy solution would be to hide the dev environment behind a http basic auth. Unfortunately there doesn't seem to be a way with the security concept of Symfony as this is geared towards always logging in a user as soon as you authenticate against any kind of user provider.
After hours of trail and error I found an alternative solution. I've added a separate environment debugging
for this use case. It has the debug flag set to true in the AppKernel.php
. The configuration and security components look similar to the dev environment with the following changes:
config_debugging.yml
imports:
- { resource: config.yml }
- { resource: security_debugging.yml }
- ...
services:
my.debugging.exception_listener:
class: My\Bundle\AppBundle\EventListener\DebuggingExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception }
my.debugging.access_listener:
class: My\Bundle\AppBundle\EventListener\DebuggingAccessListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
arguments: [ '@security.authorization_checker', '@security.token_storage' ]
security_debugging.yml
security:
firewalls:
app_resources:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
...
main:
pattern: ^/
http_basic:
provider: fos_userbundle
access_control:
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/, role: ROLE_DEBUGGING }
role_hierarchy:
ROLE_ADMIN: [ROLE_USER,ROLE_DEBUGGING,ROLE_SONATA_ADMIN]
ROLE_SUPER_ADMIN: ROLE_ADMIN
The two listener are there to check for the right role ROLE_DEBUGGING. Every admin is then always able to login and when debugging a specific user, the use has to have the specific role set for him.
DebuggingExceptionListener.php
...
public function onKernelException(GetResponseForExceptionEvent $event)
{
// You get the exception object from the received event
$exception = $event->getException();
if ($exception instanceof AccessDeniedHttpException) {
$event->setResponse(new RedirectResponse('/'));
}
}
...
DebuggingAccessListener.php
...
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
if ($this->tokenStorage->getToken() === null) {
return;
}
if ($this->authorizationChecker->isGranted('ROLE_DEBUGGING')) {
return;
}
$event->setResponse(new RedirectResponse('/'));
}
...
This way it's possible to check nearly the hole application still secured by a login. It's not possible to debug all components that involve the usual login components or any AccessDeniedHttpExceptions
. But for now it's the best solution I could come up with. I still hope there is a better solution out there.