symfonyauthorizationsymfony4symfony-voter

Token storage contains no authentication token and denyAccessUnlessGranted()


I'm having an error:

"The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.

Which is caused by denyAccessUnlessGranted() added to a controller. It happens on test environment as there is security: false. Is there a mechanism to handle an environment in such a case or what should I do with it?

Trace:

0 /backend/vendor/symfony/framework-bundle/Controller/ControllerTrait.php(179): Symfony\Component\Security\Core\Authorization\AuthorizationChecker->isGranted('read', Object(App\Entity\Company))
1 /backend/vendor/symfony/framework-bundle/Controller/ControllerTrait.php(192): Symfony\Bundle\FrameworkBundle\Controller\AbstractController->isGranted('read', Object(App\Entity\Company))
2 /backend/src/Controller/CompanyController.php(125): Symfony\Bundle\FrameworkBundle\Controller\AbstractController->denyAccessUnlessGranted('read', Object(App\Entity\Company))
3 /backend/vendor/symfony/http-kernel/HttpKernel.php(150): App\Controller\CompanyController->cget(Object(Symfony\Component\HttpFoundation\Request), Object(App\Service\CompanyService))
4 /backend/vendor/symfony/http-kernel/HttpKernel.php(67): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
5 /backend/vendor/symfony/http-kernel/Kernel.php(198): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
6 /backend/public/index.php(37): Symfony\Component\HttpKernel\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request))
7 {main}"

Solution

  • Why do you need to use security false in test environment. If you do this and you use denyAccessUnlessGranted() in your application you will get the result you mentioned. To fix this you have to use a try catch witch leaves you with 2 options, neither of them being a good one.

    denyAccessUnlessGranted trows 2 types o exceptions that you need to catch

    And this are the two options I mentioned

    1. you suppress the exceptions and let the script to run as nothing happened. If you do this you will not test your application security configuration, and even worse, if you take this code that suppresses the exceptions into your production environment, some production configuration mistake can leave your secured areas unprotected.

    2. You throw AccessDeniedException when you catch this exceptions. This will prevent access to areas in case of bad configuration in production environment of you app, but doing this will make this parts of the app inaccessible in test environment and i don't think you want that.

    The security component of the application is as much of a part of your applications as every other business feature. It should be active on every environment and configured identically. The only difference between your test, dev or prod environment should be in the parameters file (things like where are the users stored).

    Hope this helps, Alexandru Cosoi