Symfony2 custom Password Encoder (bcrypt)

prehfeldt picture prehfeldt · Nov 21, 2011 · Viewed 9.3k times · Source

I've written my own password encoder which implements the 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;
    }
}

The encoder is registered as a service with the id bcrypt.password.encoder. But I don't know, how to tell symfony to user it. Currently the app/config/security.yml looks like this:

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 I'm not using any doctrine entities.

Edit: Symfony\Component\Security\Core\User\User is my UserObject. I modified the security.yml a bit:

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

which results in a fatal error:

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

Which doesn't make any sense for me.

Answer

Seldaek picture Seldaek · Mar 1, 2013

Starting from Symfony 2.2, BCrypt is natively supported, so you can configure it easily as such:

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

You may want to adjust the cost upwards if you have a fast enough server though.