> Symfony中文手册 > 如何创建并启用自定义用户检查器

如何创建并启用自定义用户检查器

在一位用户被认证期间,可能还需要进行额外的检查,以验证是否允许该用户登录进来。通过定义一个自定义的user checker,你可以定义哪个防火墙应该使用哪个检查器。

创建一个自定义的User Checker ¶

user checker是必须要实现 UserCheckerInterface 接口的类。此接口定义了两个方法,checkPreAuth()checkPostAuth(),分别在用户认证之前和之后去执行检查。如果有一或多个条件不满足,应抛出一个继承了 AccountStatusException 的异常。

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
28
29
30
31
32
33
34
35
36
namespace AppBundle\Security;
 
use AppBundle\Exception\AccountDeletedException;
use AppBundle\Security\User as AppUser;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
 
class UserChecker implements UserCheckerInterface
{
    public function checkPreAuth(UserInterface $user)
    {
        if (!$user instanceof AppUser) {
            return;
        }
 
        // user is deleted, show a generic Account Not Found message.
        // 用户被删除了,显示一个通用的 Account Not Found 信息。
        if ($user->isDeleted()) {
            throw new AccountDeletedException('...');
        }
    }
 
    public function checkPostAuth(UserInterface $user)
    {
        if (!$user instanceof AppUser) {
            return;
        }
 
        // user account is expired, the user may be notified
        // 用户账号过期,用户将被通知
        if ($user->isExpired()) {
            throw new AccountExpiredException('...');
        }
    }
}

启用自定义的user checker ¶

剩下需要做的,就是去创建一个服务定义,并在防火墙配置信息中配置它。配置服务时,和其他服务的配法一样:

1
2
3
4
# app/config/services.yml
services:
    app.user_checker:
        class: AppBundle\Security\UserChecker
1
2
3
4
5
6
7
8
9
10
<!-- 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.user_checker" class="AppBundle\Security\UserChecker" />
    </services>
</container>
1
2
// app/config/services.php
$container->register('app.user_checker', 'AppBundle\Security\UserChecker');

剩下要做的,就是把checker添加到希望的防火墙,其取值是你的user checker之服务id:

1
2
3
4
5
6
7
8
9
# app/config/security.yml
 
# ...
security:
    firewalls:
        secured_area:
            pattern: ^/
            user_checker: app.user_checker
            # ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 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="secured_area" pattern="^/">
            <user-checker>app.user_checker</user-checker>
            <!-- ... -->
        </firewall>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
// app/config/security.php
 
// ...
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'secured_area' => array(
            'pattern' => '^/',
            'user_checker' => 'app.user_checker',
            // ...
        ),
    ),
));

附加配置 ¶

每个防火墙可以有不同的user checker。

1
2
3
4
5
6
7
8
9
10
11
12
# app/config/security.yml
 
# ...
security:
    firewalls:
        admin:
            pattern: ^/admin
            user_checker: app.admin_user_checker
            # ...
        secured_area:
            pattern: ^/
            user_checker: app.user_checker
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 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="admin" pattern="^/admin">
            <user-checker>app.admin_user_checker</user-checker>
            <!-- ... -->
        </firewall>
        <firewall name="secured_area" pattern="^/">
            <user-checker>app.user_checker</user-checker>
            <!-- ... -->
        </firewall>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// app/config/security.php
 
// ...
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'admin' => array(
            'pattern' => '^/admin',
            'user_checkers' => 'app.admin_user_checker'
            // ...
        ),
        'secured_area' => array(
            'pattern' => '^/',
            'user_checker' => 'app.user_checker',
            // ...
        ),
    ),
));