什么阻止密码与注入的Symfony服务(FOSUserBundle)重新混合

时间:2016-04-18 19:53:13

标签: fosuserbundle symfony

这是我的original question的后续问题,我在尝试在身份验证过程中重新发送用户密码以从旧数据库迁移。

在那里实施了有用的答案。我现在遇到另一个问题,我没有收到任何错误(使用下面的代码),但密码和salt没有在数据库中更新:

security.yml

security:
    encoders:
        AppBundle\Entity\Member:
        id: club.hub_authenticator

services.yml

services:
    club.hub_authenticator:
        class: AppBundle\Service\HubAuthenticator
        arguments: ["@security.token_storage" ,"@club.password_rehash"]

    club.password_rehash:
        class: AppBundle\Service\PasswordRehash
        arguments: [ "@security.token_storage" ]

HubAuthenticator.php

namespace AppBundle\Service;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class HubAuthenticator extends \Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder implements PasswordEncoderInterface
{
    private $storage ;
    private $passwordRehash ;

    function __construct(TokenStorageInterface $storage, PasswordRehash $passwordRehash, $cost = 13)
    {
        parent::__construct($cost);

        $this->storage=$storage ;
        $this->passwordRehash = $passwordRehash;
    }

    function isPasswordValid($encoded, $raw, $salt)
    {
        // Test for legacy authentication (and conditionally rehash the password in the database)
        if ($this->comparePasswords($encoded, sha1("SaltA".$raw."SaltB"))) {
            $this->passwordRehash->rehash($raw);
            return true ;
        }

        // Test for Bcrypt authentication
        if (parent::isPasswordValid($encoded,$raw,$salt)) return true ;
    }
}

PasswordRehash.php

namespace AppBundle\Service;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;


class PasswordRehash extends \Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder  implements PasswordEncoderInterface
{
    // private $storage ;

    function __construct(TokenStorageInterface $storage , $cost = 13)
    {
        parent::__construct($cost);
        // $this->storage=$storage ;
    }



    // Customises BCryptPasswordEncoder to use legacy Club SHA method
    function rehash($raw)
    {
        // Commented out as I THINK the $raw is the plainPassword I'm trying to use to reencode the password
        // $user=$this->storage->getToken()->getUser();
        // $token = $this->storage->getToken();

        //Salt left empty as have read this will auto-generate a new one (which is also better practice)
        parent::encodePassword($raw, $salt=null ) ;

        return true ;
    }
}

1 个答案:

答案 0 :(得分:1)

如果您想将PasswordRehash#rehash()的结果存储为用户密码的值,请让您的方法返回新密码:

function rehash($raw)
{        
    return parent::encodePassword($raw, null);
}

然后,要更新用户,您需要设置新密码并存储更改。

在您的服务中注入Doctrine EntityManager:

club.hub_authenticator:
    class: AppBundle\Service\HubAuthenticator
    arguments: ["@security.token_storage" ,"@club.password_rehash", "@doctrine.orm.entity_manager" ]

在你的班上:

use Doctrine\ORM\EntityManager;

function __construct(TokenStorageInterface $storage, PasswordRehash $passwordRehash, EntityManager $em, $cost = 13)
{
    parent::__construct($cost);

    $this->storage = $storage;
    $this->passwordRehash = $passwordRehash;
    $this->em = $em;
}

然后使用它:

if (!$token = $this->storage->getToken()) {
    return;
}

if ($this->comparePasswords($encoded, sha1("SaltA".$raw."SaltB"))) {
    // Retrieve the user
    $user = $token->getUser();
    // Change the user password
    $user->setPassword($this->passwordRehash->rehash($raw));
    // Save the changes
    $em->flush($user);
}

但是,我真的不确定你正在实施的逻辑。 我没有看到扩展BcryptPasswordEncoder的好处。

您应该查看this post,其中显示了一种快速方法,可以将您的用户密码从遗留应用程序转换为符合FOSUserBundle标准的密码,而不是在每次身份验证时执行此操作。

然后再看how to work with services in Symfony2+ 希望这会对你有所帮助。