如何使用多个Guard Authenticators

3.4 版本
维护中的版本

Guard认证组件让你轻松使用多种不同的authenticator。

所谓入口点(译注:配置Guard时的entry_point键),是(你的authenticator的)一个service id,该服务的 start() 方法在被调用时,即启动认证进程。

超高难文档 本文体现了Symfony安全组件的一个重大特点,即,比较难于配置,一旦配好(当然也要在一定程度上理解内部机制),却十分易用,扩展时更是指哪儿打哪儿。愿学者精研之。

共享入口点的多authenticator 

有时你希望向用户提供不同的认证机制,像是一个登录表单和一个facebook登录,两个入口点都会把用户重定向至同一个登录页面。然而,在配置信息中你必须显式指定你希望使用的每一个入口点。

这就是security配置信息实际看起来的样子:

1
2
3
4
5
6
7
8
9
10
11
# app/config/security.yml
security:
     # ...
    firewalls:
        default:
            anonymous: ~
            guard:
                authenticators:
                    - app.form_login_authenticator
                    - app.facebook_connect_authenticator
                entry_point: app.form_login_authenticator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- app/config/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
 
    <config>
        <!-- ... -->
        <firewall name="default">
            <anonymous />
            <guard entry-point="app.form_login_authenticator">
                <authenticator>app.form_login_authenticator</authenticator>
                <authenticator>app.facebook_connect_authenticator</authenticator>
            </guard>
        </firewall>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// app/config/security.php
$container->loadFromExtension('security', array(
    // ...
    'firewalls' => array(
        'default' => array(
            'anonymous' => null,
            'guard' => array(
                'entry_point' => 'app.form_login_authenticator',
                'authenticators' => array(
                    'app.form_login_authenticator',
                    'app.facebook_connect_authenticator'
                ),
            ),
        ),
    ),
));

这种方法有一个限制 – 你只能使用一个入口点。

多个Authenticator各自使用单独的Entry Point 

然而,有些案例需要你的authenticator保护程序的不同部分。例如,你有一个登录表单,保护的是程序的前台部分,另有一个API入口,利用API token进行保护。由于在每个firewall中只能配置一个entry point,解决方案是将配置信息切分成两个独立的防火墙:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# app/config/security.yml
security:
    # ...
    firewalls:
        api:
            pattern: ^/api/
            guard:
                authenticators:
                    - app.api_token_authenticator
        default:
            anonymous: ~
            guard:
                authenticators:
                    - app.form_login_authenticator
    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: ROLE_API_USER }
        - { path: ^/, roles: ROLE_USER }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- app/config/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
 
    <config>
        <!-- ... -->
        <firewall name="api" pattern="^/api/">
            <guard>
                <authenticator>app.api_token_authenticator</authenticator>
            </guard>
        </firewall>
        <firewall name="default">
            <anonymous />
            <guard>
                <authenticator>app.form_login_authenticator</authenticator>
            </guard>
        </firewall>
        <rule path="^/login" role="IS_AUTHENTICATED_ANONYMOUSLY" />
        <rule path="^/api" role="ROLE_API_USER" />
        <rule path="^/" role="ROLE_USER" />
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// app/config/security.php
$container->loadFromExtension('security', array(
    // ...
    'firewalls' => array(
        'api' => array(
            'pattern' => '^/api',
            'guard' => array(
                'authenticators' => array(
                    'app.api_token_authenticator',
                ),
            ),
        ),
        'default' => array(
            'anonymous' => null,
            'guard' => array(
                'authenticators' => array(
                    'app.form_login_authenticator',
                ),
            ),
        ),
    ),
    'access_control' => array(
        array('path' => '^/login', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
        array('path' => '^/api', 'role' => 'ROLE_API_USER'),
        array('path' => '^/', 'role' => 'ROLE_USER'),
    ),
));

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

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