如何动态地选择Password Encoder的算法

3.4 版本
维护中的版本

通常,同一个password encoder(密码加密器)被用于所有用户,这是通过把它配置为“应用到一个特定的类的[全部实例]”而实现的:

1
2
3
4
5
# app/config/security.yml
security:
    # ...
    encoders:
        Symfony\Component\Security\Core\User\User: sha512
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 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>
        <!-- ... -->
        <encoder class="Symfony\Component\Security\Core\User\User"
            algorithm="sha512"
        />
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
// app/config/security.php
$container->loadFromExtension('security', array(
    // ...
    'encoders' => array(
        'Symfony\Component\Security\Core\User\User' => array(
            'algorithm' => 'sha512',
        ),
    ),
));

另一个选择是,使用一个“已命名的”encoder,然后选择你希望动态使用的encoder。

前例中,你已经设置 sha512 算法,用于 Acme\UserBundle\Entity\User。这对普通用户来说可能是足够安全的,但你更希望管理员们拥有更为强力的算法,例如 bcrypt。这可以使用“命名encoder”来完成:

1
2
3
4
5
6
7
# app/config/security.yml
security:
    # ...
    encoders:
        harsh:
            algorithm: bcrypt
            cost: 15
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>
        <!-- ... -->
        <encoder class="harsh"
            algorithm="bcrypt"
            cost="15" />
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
// app/config/security.php
$container->loadFromExtension('security', array(
    // ...
    'encoders' => array(
        'harsh' => array(
            'algorithm' => 'bcrypt',
            'cost'      => '15'
        ),
    ),
));

它创建了一个名为 harsh 的encoder。为了让 User 实例使用它,这个类必须要实现 EncoderAwareInterface 接口。此接口需要一个方法 - getEncoderName - 它应该返回要使用的encoder之名称:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Acme/UserBundle/Entity/User.php
namespace Acme\UserBundle\Entity;
 
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface;
 
class User implements UserInterface, EncoderAwareInterface
{
    public function getEncoderName()
    {
        if ($this->isAdmin()) {
            return 'harsh';
        }
 
        return null; // use the default encoder
    }
}

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

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