是什么阻止了使用注入的 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+。
希望对你有帮助。
这是我的
在那里实施了有用的答案之后。我现在遇到了另一个问题,我没有收到任何错误(使用以下代码)但是密码和盐没有在数据库中更新:
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+。
希望对你有帮助。