这是我的original question的后续问题,我在尝试在身份验证过程中重新发送用户密码以从旧数据库迁移。
在那里实施了有用的答案。我现在遇到另一个问题,我没有收到任何错误(使用下面的代码),但密码和salt没有在数据库中更新:
security:
encoders:
AppBundle\Entity\Member:
id: club.hub_authenticator
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" ]
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 ;
}
}
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 ;
}
}
答案 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+ 希望这会对你有所帮助。