Migrate from sfGuard to FOSUserBundle
Aug 16th, 2011Passwords are not stored the same way by sfGuard (symfony 1) and FOSUserBundle (Symfony2). You will not be able to check with FOSUserBundle the password created with sfGuard for two reasons (if you keep default values):
- hashing algorithm: sfGuard uses sha1 to hash passwords whereas FOSUserBundle uses sha512.
- password and salt merging: sfGuard is doing
$salt . $password
whereas FOSUserBundle is doing$password . '{' . $salt . '}'
.
I will show you how to change default in your new Symfony2 application to deal with passwords the way sfGuard do.
Hashing Algorithm
The bundle FOSAdvancedEncoderBundle allows you to use different encoders on a per-instance basis, whereas Symfony security component uses encoders on a per-class basis.
Install FOSAdvancedEncoderBundle following the instructions in the bundle documentation. Then, specify in config.yml
the two encoders you want to use.
# app/config/config.yml
fos_advanced_encoder:
encoders:
# default values for FOSUserBundle (Symfony2)
# see http://symfony.com/doc/current/reference/configuration/security.html
default:
algorithm: sha512
iterations: 5000
encode_as_base64: true
# legacy encoder used by sfGuard (symfony 1)
legacy:
algorithm: sha1
iterations: 1
encode_as_base64: false
Then, you have to tell your application which encoder use for which
instance of your entity User
. For that, make User
implement the
interface EncoderAwareInterface and the function User::getEncoderName
has to return the name of the encoder to use. For instance, you can add
a field algorithm
like this.
Password and salt merging
We are going to overwrite the method used to merge passwords. Create a
new folder Security/
in your bundle and add the file
MessageDigestPasswordEncoder.php
:
Don’t forget to change Acme\SiteBundle
according to your names. Then add to your config file this line telling your app that we want to use that class instead of the
default one:
parameters:
security.encoder.digest.class: Acme\SiteBundle\Security\MessageDigestPasswordEncoder
Don’t forget, here again, to change Acme\SiteBundle
according to your
names.
That’s it
You may now write your script reading the sfGuard users and writing FOSUserBundle users. It will probably look like that:
If so, you will have to add the method setSalt()
to your User
entity:
Having some problems?
If you are having trouble, try the parameters for the encoder in this post (it’s in French, but just look for the Symfony2 config file).