如何创建并启用自定义用户检查器
在一位用户被认证期间,可能还需要进行额外的检查,以验证是否允许该用户登录进来。通过定义一个自定义的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 ¶
剩下需要做的,就是去创建一个服务定义,并在防火墙配置信息中配置它。配置服务时,和其他服务的配法一样:
|
# app/config/services.yml
services:
app.user_checker:
class: AppBundle\Security\UserChecker |
|
<!-- 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> |
|
// app/config/services.php
$container->register('app.user_checker', 'AppBundle\Security\UserChecker'); |
剩下要做的,就是把checker添加到希望的防火墙,其取值是你的user checker之服务id:
|
# 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',
// ...
),
),
)); |