是什么阻止了使用注入的 Symfony 服务 (FOSUserBundle) 重新散列密码

What is preventing passwords being rehashed with the injected Symfony services (FOSUserBundle)

这是我的 的后续问题,我在其中尝试在身份验证期间重新散列用户密码以从旧数据库迁移。

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

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 ;
    }
}

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

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

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

在您的服务中注入学说 EntityManager:

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

在你的 class 中:

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+
希望对你有帮助。