WARNING: You are browsing the documentation for Symfony 2.8 which is not maintained anymore. Consider upgrading your projects to Symfony 4.2.

How to Create a Custom Access Denied Handler

2.8 version

How to Create a Custom Access Denied Handler

When your application throws an AccessDeniedException, you can handle this exception with a service to return a custom response.

Each firewall context can define its own custom access denied handler:

  • YAML
    1
    2
    3
    4
    5
    # app/config/security.yml
    firewalls:
        foo:
            # ...
            access_denied_handler: app.security.access_denied_handler
    
  • XML
    1
    2
    3
    4
    5
    <config>
      <firewall name="foo">
        <access_denied_handler>app.security.access_denied_handler</access_denied_handler>
      </firewall>
    </config>
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // app/config/security.php
    $container->loadFromExtension('security', array(
        'firewalls' => array(
            'foo' => array(
                // ...
                'access_denied_handler' => 'app.security.access_denied_handler',
            ),
        ),
    ));
    

Your handler must implement the AccessDeniedHandlerInterface. This interface defines one method called handle() that implements the logic to execute when access is denied to the current user (send a mail, log a message, or generally return a custom response):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
namespace AppBundle\Security;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;

class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
    public function handle(Request $request, AccessDeniedException $accessDeniedException)
    {
        // ...

        return new Response($content, 403);
    }
}

Then, register the service for the access denied handler:

  • YAML
    1
    2
    3
    4
    # app/config/services.yml
    services:
        app.security.access_denied_handler:
            class: AppBundle\Security\AccessDeniedHandler
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    <!-- app/config/services.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <services>
            <service id="app.security.access_denied_handler"
                    class="AppBundle\Security\AccessDeniedHandler" />
        </services>
    </container>
    
  • PHP
    1
    2
    3
    4
    5
    // app/config/services.php
    $container->register(
        'app.security.access_denied_handler',
        'AppBundle\Security\AccessDeniedHandler'
    );
    

That's it! Any AccessDeniedException thrown by the foo firewall will now be handled by your service.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.