13

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.

3 Answers 3

42

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.

Sign up to request clarification or add additional context in comments.

2 Comments

And some documentation links? :)
@Jimbo added a link just for completeness.
11

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.

Comments

4

Your encoders section should look like this:

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

where Acme\UserBundle is your vendor and bundle namespace, of course.

For reference, a complete example security config can be found here.

EDIT: The way the encoder factory works (source code here, relevant lines start on line 33) is that in your config, you have given the framework a class, and an encoder to use for the class. It's Doctrine-independent, so just provide the fully-qualified class name of your user object in the config instead of a "user entity," and when your password is encoded, Symfony will know how to handle it.

6 Comments

Thanks for the quick reply, but I don't have an user entity nor entities at all and that's my problem.
Gotcha. How are you managing users, then? Also, I believe if you just reference the name of your user class in the config, Symfony will recognize it.
My users are stored in a Neo4j database and I've written my own UserProvider. I'll update my original post with my full security.yml.
I tried what you described but it gives me an error (see updated question)
Can you provide a gist or similar of your UserProvider class (and the service definition for it, if relevant)?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.