如何创建自定义的Access Denied Handler

3.4 版本
维护中的版本

当你的程序抛出一个 AccessDeniedException 异常时,你可以用一个服务来处理此异常,以返回一个自定义的响应。

每一个firewall context(防火墙上下文),可以定义它自己的自定义access denied handler(拒绝访问控制器):

1
2
3
4
5
# app/config/security.yml
firewalls:
    foo:
        # ...
        access_denied_handler: app.security.access_denied_handler
1
2
3
4
5
<config>
  <firewall name="foo">
    <access_denied_handler>app.security.access_denied_handler</access_denied_handler>
  </firewall>
</config>
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',
        ),
    ),
));

你的handler必须要实现 AccessDeniedHandlerInterface 接口。此接口定义了一个名为 handle() 的方法,它所实现的逻辑,将在“拒绝当前用户(发邮件、做日志、或者泛泛地返回一个自定义响应)访问时”被执行。

测试

测试。

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);
    }
}

然后将这个 access denied handler 注册为服务:

1
2
3
4
# app/config/services.yml
services:
    app.security.access_denied_handler:
        class: AppBundle\Security\AccessDeniedHandler
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>
1
2
3
4
5
// app/config/services.php
$container->register(
    'app.security.access_denied_handler',
    'AppBundle\Security\AccessDeniedHandler'
);

完成!被防火墙 foo 所抛出的任何 AccessDeniedException 现在将被你的服务来处理。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)