Подтвердить что ты не робот

Symfony2 custom Password Encoder (bcrypt)

Я написал свой собственный пароль-кодер, который реализует PasswordEncoderInterface:

class BCryptPasswordEncoder implements PasswordEncoderInterface {
    protected $encoder;

    public function __construct(BCryptEncoder $encoder) {
        $this->encoder = $encoder;
    }

    public function encodePassword($raw, $salt) {
        return $this->encoder->encodeString($raw, $salt);
    }

    public function isPasswordValid($encoded, $raw, $salt) {
        return $this->encoder->encodeString($raw, $salt) == $encoded;
    }
}

Кодер зарегистрирован как служба с идентификатором bcrypt.password.encoder. Но я не знаю, как сказать symfony пользователю. В настоящее время app/config/security.yml выглядит следующим образом:

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        neo4j:
          id: security.user.provider.neo4j
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        secured_area:
            provider: neo4j
            pattern:    ^/.*
            form_login:
                check_path: /login_check
                login_path: /login
            logout:
                path:   /logout
                target: /
            anonymous: ~
    access_control:
        - { path: ^/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/.*, role: ROLE_ADMIN }

Btw Я не использую никаких объектов доктрины.

Изменить: Symfony\Component\Security\Core\User\User - это мой UserObject. Я немного изменил security.yml:

encoders:
    Symfony\Component\Security\Core\User\User: 
        id: bcrypt.password.encoder

что приводит к фатальной ошибке:

Catchable Fatal Error: Argument 1 passed to EMC3\Bundle\UserBundle\Neo4jUserProvider::__construct() must be an instance of EMC3\Bundle\UserBundle\UserManager, instance of EMC3\Bundle\UserBundle\BCryptEncoder given, called in /var/www/emc3/app/cache/dev/appDevDebugProjectContainer.php on line 227 and defined in /var/www/emc3/src/EMC3/Bundle/UserBundle/Neo4jUserProvider.php line 29

Это не имеет для меня никакого смысла.

4b9b3361

Ответ 1

По состоянию на ноябрь 2011 года, перед Symfony 2.2, это не поддерживается напрямую.

Вместо того, чтобы изобретать колесо, я предлагаю вам использовать Boderfish Password Encoder bundle, который я написал (ElnurBlowfishPasswordEncoderBundle), который решает та же проблема. Или, по крайней мере, вы можете увидеть, как это реализовано.

Если вы используете Symfony 2.2 или новее, см. ответ Seldaek для инструкций по настройке.

Ответ 2

Начиная с Symfony 2.2, BCrypt поддерживает изначально поддерживаемый, поэтому вы можете легко настроить его как таковой:

security:
    encoders:
        Symfony\Component\Security\Core\User\User:
            algorithm: bcrypt
            cost: 7

Возможно, вы захотите отрегулировать стоимость вверх, если у вас есть достаточно быстрый сервер.

Ответ 3

Ваш раздел encoders должен выглядеть следующим образом:

encoders:
    Acme\UserBundle\Entity\User:
        id: bcrypt.password.encoder

где Acme\UserBundle - ваше пространство имен поставщиков и пакетов, конечно.

Для справки, полный пример конфигурации безопасности можно найти здесь.

EDIT: Как работает кодер factory (исходный код здесь, соответствующие строки начинаются в строке 33 ) заключается в том, что в вашей конфигурации вы предоставили инфраструктуре класс и кодер для использования в классе. Он не зависит от Doctrine, поэтому просто укажите полное имя класса вашего пользовательского объекта в config вместо "пользовательского объекта", а когда ваш пароль закодирован, Symfony будет знать, как с ним справиться.