2014-09-09 6 views
2

Si vous avez une base de code existante avec les utilisateurs et leurs mots de passe, comment pouvez-vous changer l'encodeur de mot de passe et mettre à jour les mots de passe des utilisateurs? En d'autres termes, disons que tous les mots de passe des utilisateurs sont dans MD5 et que vous voulez passer à PBKDF2. La stratégie commune consiste à simplement redéfinir le mot de passe à chaque fois que l'utilisateur se connecte.Symfony2 - Modifier les encodeurs pour les utilisateurs existants

Cependant, je ne suis pas sûr de savoir comment faire cela dans Symfony. Serait-ce fait dans le contrôleur de connexion? Ou existe-t-il un moyen de le faire dans l'objet EncoderInterface?

Répondre

3

Découvrez ce blog ... semble que c'est ce que vous cherchez ...

How to change the way Symfony2 encodes passwords

Vous devez étendre la classe MessageDigestPasswordEncoder, remplacer ses méthodes et copier cette classe à la sécurité dossier dans votre paquet (créer un si ne pas exister) Découvrez l'exemple suivant de la façon d'étendre MessageDigestPasswordEncoder

use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder as  BaseMessageDigestPasswordEncoder; 

class MessageDigestPasswordEncoder extends BaseMessageDigestPasswordEncoder 
{ 
    private $algorithm; 
    private $encodeHashAsBase64; 

    public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 5000) 
    { 
     $this->algorithm = $algorithm; 
     $this->encodeHashAsBase64 = $encodeHashAsBase64; 
     $this->iterations = $iterations; 
    } 

    protected function mergePasswordAndSalt($password, $salt) 
    { 
     if (empty($salt)) { 
      return $password; 
     } 

     return $salt.$password; // or do whatever you need with the password and salt 
    } 

    public function encodePassword($raw, $salt) 
    { 
     // this is the original code from the extended class, change it as needed 

     if (!in_array($this->algorithm, hash_algos(), true)) { 
      throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); 
     } 

     $salted = $this->mergePasswordAndSalt($raw, $salt); 
     $digest = hash($this->algorithm, $salted, true); 

     // "stretch" hash 
     for ($i = 1; $i < $this->iterations; $i++) { 
      $digest = hash($this->algorithm, $digest.$salted, true); 
     } 

     return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest); 
    } 
} 

une fois que vous avez votre classe mise à jour de votre prêt config.yml

# app/config/config.yml 
# ... 

parameters: 
    security.encoder.digest.class: Ens\TestBundle\Security\MessageDigestPasswordEncoder 
+0

On ne sait pas de cette réponse si Symfony se chargera automatiquement la situation spécifique du demandeur: la transition d'un mot de passe encodage à un autre, avec les mots de passe existants stockés. Symfony config vous permet de changer l'encodeur assez facilement, mais ce qui se passera la prochaine fois que l'utilisateur se connecte n'est pas décrit. Idéalement, l'encodage choisi aurait été stocké dans l'enregistrement de l'utilisateur, de sorte qu'il pourrait décoder l'ancienne façon jusqu'à ce qu'il soit mis à jour, puis encoder la nouvelle façon de réinitialiser le mot de passe (qui pourrait être déclenchée par l'application). Est-ce que ça fait ça? – frumious

+1

Le demandeur a demandé d'où cela devrait être fait dans Symfony "Serait-ce fait dans le contrôleur de connexion ou y a-t-il un moyen de le faire dans l'objet EncoderInterface?" et non comment, il sait comment depuis il a décrit la manière commune de faire tel. La réponse décrivent comment et comment faire le re-hash dans Symfony seulement. – iPeleg

+0

De ce que je peux dire, il y a une EncoderAwareInterface, donc il est possible d'avoir l'encodeur basé sur l'objet User donné. La vraie question est de savoir où l'emplacement approprié pour mettre la logique de mise à jour est, à savoir, ressasser le mot de passe dans le nouveau format. – parent5446

Questions connexes