Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 custom Password Encoder (bcrypt)

Tags:

bcrypt

symfony

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.

like image 948
prehfeldt Avatar asked Nov 21 '11 14:11

prehfeldt


2 Answers

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.

like image 196
Seldaek Avatar answered Nov 12 '22 03:11

Seldaek


As of November 2011, before Symfony 2.2, this is not directly supported.

Instead of reinventing the wheel, I suggest you to use the Blowfish Password Encoder bundle I wrote (ElnurBlowfishPasswordEncoderBundle), which solves the same problem. Or, at least, you can see how it's implemented.

If you're using Symfony 2.2 or later, see Seldaek's answer for configuration instructions.

like image 11
Elnur Abdurrakhimov Avatar answered Nov 12 '22 02:11

Elnur Abdurrakhimov