30

I am doing a check if there is a specific token in my request URI and throw a Symfony\Component\Security\Core\Exception\AccessDeniedException if there is no token or the token is wrong.

if(!isset($token) && $token != 'whatever') {
  throw new AccessDeniedException('No token given or token is wrong.');
}

But when I use this AccessDeniedException, Symfony2 simply redirects to the login page. Instead, I would like to have a dedicated 403 error page (I already created app/Resources/TwigBundle/views/Exceptions/error403.html.twig file).

What would I have to change in order to achieve this? Do I have to use a PHP native Exception? But how can I tell to pass a 403 error code?

Does Symfony2 maybe have a specific 403-Exception which doesn't simply redirect to login?

Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
  • Could you `catch` the Exception and in the catch roll an HTTP 403 error in a `header()` ? – CD001 Feb 21 '14 at 10:48
  • Symfony2 is ususally catching and handling all Exceptions. So I'm not really looking for workaround... – Gottlieb Notschnabel Feb 21 '14 at 10:50
  • Catch your response with onKernelResponse(). No ? – Baptiste Donaux Feb 21 '14 at 10:58
  • I'm not exactly an expert on Symfony so I'll leave it for someone better qualified to answer; I'm not sure if either of these will fit the bill but I thought I'd mention them in case you'd missed them : HttpException and AccessDeniedHttpException : http://api.symfony.com/2.4/Symfony/Component/HttpKernel/Exception.html – CD001 Feb 21 '14 at 11:03
  • Throw Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException. That will bypass the security system and give you a 403 response. – Cerad Feb 21 '14 at 12:40
  • 403 Access Denied means that the AUTHENTICATED user is not authorized to view the page. Therefore, that user must be logged in. If the user is logged in, and then doesn't have this token, they will be redirected to the 403 error page. – Sehael Feb 21 '14 at 15:12
  • @Sehael Actually no: If you throw Symfony's `AccessDeniedException` you're redirected to the login page no matter if you're authenticated or not. – Gottlieb Notschnabel Feb 22 '14 at 09:51

2 Answers2

60

Throw Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException.

That will bypass the security system and give you a 403 response which in turn will get picked up by the twig exception listener.

Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
Cerad
  • 48,157
  • 8
  • 90
  • 92
  • 10
    In Symfony 2.5 you can also use throw $this->createAccessDeniedException('You cannot access this page!'); (See http://symfony.com/blog/new-in-symfony-2-5-create-the-correct-denied-http-exception) – madc Nov 19 '14 at 21:15
  • surely this should be part of `HttpFoundation` and not `HttpKernel` – JamesHalsall Jan 20 '15 at 16:31
  • Cheers. I tried throwing `AccessDeniedHttpException` in an overridden `EntityUserProvider` but curiously it was still responding with a `401` - the exception must have been rethrown somewhere up the stack. I ended up using a [Voter](http://symfony.com/doc/current/cookbook/security/voters.html), which was actually quite a nice neat, easy to implement alternative. – Darragh Enright Jul 13 '15 at 18:44
3

As of Symfony 2.6 you can use the following controller shortcut that will trigger the good exception for you:

return $this->denyAccessUnlessGranted('ROLE_EDIT', $item, 'You cannot edit this item.');
COil
  • 7,201
  • 2
  • 50
  • 98