是什么阻止了注入的Symfony服务(FOSUserBundle)重新加密密码 [英] What is preventing passwords being rehashed with the injected Symfony services (FOSUserBundle)
问题描述
This is a follow up question to my original question where I am trying to rehash user passwords during authentication to migrate from a legacy database.
在此处执行有用的答案后.我现在遇到了另一个问题,我没有收到任何错误(使用以下代码),但是数据库中的密码和盐没有更新:
After implementing the helpful answer there. I have now hit another problem where I receive no error (with the below code) but the passwords and salt are not being updated in the database:
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()
的结果存储为用户密码的值,请使您的方法返回新密码:
If you want to store the result of PasswordRehash#rehash()
as the value of your user's password, make your method returning the new password:
function rehash($raw)
{
return parent::encodePassword($raw, null);
}
然后,要更新用户,您需要设置新密码并存储更改.
Then, to update the user, you need to set the new password and store the changes.
在您的服务中注入原则EntityManager:
Inject the doctrine EntityManager in your service:
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的好处.
But, I'm really not sure about the logic you are implementing. I don't see the benefit of extending the BcryptPasswordEncoder.
您应该查看这篇文章,该文章展示了一种快速的转换方法您的用户密码从旧版应用程序转换为FOSUserBundle兼容密码仅需一次,而无需在每次身份验证时都执行.
You should look at this post that shows a quick way to convert the password of your users from a legacy app to FOSUserBundle-compliant passwords in only one time, rather than do it on each authentication.
然后进一步了解如何在Symfony2 + .
希望对您有帮助.
Then look more at how to work with services in Symfony2+.
Hope this helps you.
这篇关于是什么阻止了注入的Symfony服务(FOSUserBundle)重新加密密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!