Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to attach a password encoder to a User Interface in Silex?

Tags:

php

symfony

silex

So I am trying to create a new Silex application and use the Security bundle included. For simplicities sake I was going to go with the basic password encoding.

Per the Silex documentation http://silex.sensiolabs.org/doc/providers/security.html I have created a custom User Provider. However this user interface does not seem to use the default password encoding.

I can successfully get a password out of

$password = $app['security.encoder.digest']->encodePassword('foo');

However when I use the example

// find the encoder for a UserInterface instance
$encoder = $app['security.encoder_factory']->getEncoder($user);

// compute the encoded password for foo
$password = $encoder->encodePassword('foo', $user->getSalt());

I get the

RuntimeException: No encoder has been configured for account

In symfony2, I would use something like the following

encoders:
        somename:
            class: Acme\DemoBundle\Entity\User
        Acme\DemoBundle\Entity\User: sha512
        Acme\DemoBundle\Entity\User: plaintext
        Acme\DemoBundle\Entity\User:
            algorithm: sha512
            encode_as_base64: true
            iterations: 5000
        Acme\DemoBundle\Entity\User:
            id: my.custom.encoder.service.id

But that doesnt seem to be the case here. I can't seem to find any type of setEncoder method so I am a bit stumped.

like image 854
fafnirbcrow Avatar asked Jan 08 '13 17:01

fafnirbcrow


2 Answers

You need to reconstruct the EncoderFactory to add your custom implementation:

<?php

$app = new Silex\Application();
$app['myapp.encoder.base64'] = new Base64PasswordEncoder();
$app['security.encoder_factory'] = $app->share(function ($app) {
    return new EncoderFactory(
        array(
            'Symfony\Component\Security\Core\User\UserInterface' => $app['security.encoder.digest'],
            'MyApp\Model\UserInterface'                          => $app['myapp.encoder.base64'],
        )
    );
});

(oh and please, don't use a Base64Encoder() for password ;))

like image 139
Boris Guéry Avatar answered Oct 17 '22 19:10

Boris Guéry


I was able to use the accepted answer to fix my problem, but I couldn't assign it to security.encoder_factory directly, so I'm just sharing what I found to work.

instead of:

$app['security.encoder_factory'] = $app->share(function($app) {
    //..see above...//
});

I had to use:

$app->register(new Silex\Provider\SecurityServiceProvider(),array(
    'security.encoder_factory' => $app->share(function($app) {
    //... same as above ...//
    })
));

I'm too new to Silex to know why it didn't work as above for me. My initial guess would be a version difference (question was asked over two years ago). I can assign to security.provider.default before the call to register the module, but I can't seem to assign to security.encoder_factory . I also seem to have to put security.firewalls in the register call.

like image 1
Ghost8472 Avatar answered Oct 17 '22 20:10

Ghost8472