【问题标题】:How to access the user Token in an injected service to reencode passwords?如何访问注入服务中的用户令牌以重新编码密码?
【发布时间】:2016-04-17 20:07:40
【问题描述】:

我有以下代码,我试图在用户登录时重新编码密码(数据库已从旧网站迁移)。但是,我不确定自己做错了什么,因为我不断收到错误:

尝试调用“AppBundle\Service\HubAuthenticator”类的名为“forward”的未定义方法。

我的设置如下:

security.yml

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

services.yml

services:
    //This should be central service than then calls the second
    club.hub_authenticator:
        class: AppBundle\Service\HubAuthenticator

    club.password_rehash:
        class: AppBundle\Service\PasswordRehash

Hubauthenticator.php

namespace AppBundle\Service;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;

class HubAuthenticator extends \Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder implements PasswordEncoderInterface
{
    function __construct($cost=13)
    {
        parent::__construct($cost);
    }

    function isPasswordValid($encoded, $raw, $salt)
    {
        // Test for legacy authentication (and conditionally rehash the password stored in the database if true)
        if ($this->comparePasswords($encoded, sha1("saltA".$raw."saltB"))) {
            $this->forward('club.password_rehash:rehash');
        }

        // Test for Symfony's Bcrypt authentication (any passwords just rehashed in previous step should work here)
        if (parent::isPasswordValid($cost=13, $encoded,$raw,$salt)) return true ;
    }
}

PasswordRehash.php

namespace AppBundle\Service;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;

class PasswordRehash extends \Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder
{
    // Customises BCryptPasswordEncoder class to use legacy SHA method
    function rehash($member, $raw, $salt)
    {
        //Salt is null as Symfony documentation says it is better to generate a new one
        parent::encodePassword($member->getPlainPassword, $salt=null ) ;
    }
}

之前的一些其他完整性尝试:

我的猜测是问题在于我误解了我可以使用哪些对象。我的理解是用户此时尚未通过身份验证,因此尝试并删除了以下尝试:

尝试将$member 注入HubAuthenticator 服务:

function __construct($cost=13)
{
    parent::__construct($cost, \Member $member);
}

当试图让普通密码重新散列时:

$this->get('security.context')->getToken()->getUser()->getPlainPassword();

【问题讨论】:

  • 在调用forward() 方法(不存在)时,您打算在HubAuthenticator 类中实现什么?为什么这个类完全扩展了BcryptPasswordEncoder
  • 嗨@xabbuh - forward() 错了 - 我只是在尝试不同的尝试来让它工作(!)。 BcryptPasswordEncoder 我尝试按照您的建议删除,但我收到“错误:无法访问父级::”....因为我有 if (parent::isPasswordValid(...)) return true 在其中

标签: fosuserbundle symfony


【解决方案1】:

在您的服务中,您只能访问您注入的依赖项。

因此,要访问当前用户对象,您需要将其作为参数传递:

服务:

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

构造函数:

use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

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

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

        $this->storage = $storage;
        // Now you can use:
        // $user = $this->storage->getToken()->getUser();
    }
}

然后,要访问第二个服务,以同样的方式注入它。

将其添加到服务参数中:

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

将其添加到您的构造函数中:

private $storage;
private $passwordRehash

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

    $this->storage = $storage;
    $this->passwordRehash = $passwordRehash;
    // Now you can use:
    // $this->passwordRehash->rehash(...);
}

希望对你有所帮助。

【讨论】:

  • 感谢@chalasr - 帮助了 :) 它现在使用旧密码登录用户(没有错误),但不会重新散列。你知道有什么问题吗? function rehash($raw) { parent::encodePassword($raw, $salt=null);return true; }
  • 是不是只有认证完成后才能将密码rehash到数据库中? ...但是$raw 普通密码仅在身份验证期间可用?
  • @Bendy 抱歉,如果不了解更多信息,我无法帮助您,也许您应该针对这个特定问题提出一个新问题
  • 感谢@chalasr 的快速回复 - 我在这里发布了另一个关于我的情况的问题:stackoverflow.com/questions/36703134/…
猜你喜欢
  • 2014-08-24
  • 2020-03-06
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 2013-02-18
  • 2015-12-18
  • 2013-09-06
  • 1970-01-01
相关资源
最近更新 更多