【问题标题】:Why credentials are null when erase_credentials is false?当erase_credentials 为假时,为什么凭据为空?
【发布时间】:2021-08-02 14:56:37
【问题描述】:

Symfony 5.3

security.yaml

security:
    ...
    erase_credentials: false

LoginListener.php

<?php

namespace App\EventListener;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class LoginListener
{
    private $passwordHasherFactory;
    private $em;

    public function __construct(PasswordHasherFactoryInterface $passwordHasherFactory, EntityManagerInterface $em)
    {
        $this->passwordHasherFactory = $passwordHasherFactory;
        $this->em = $em;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();
        $token = $event->getAuthenticationToken();

        // Migrate the user to the new hashing algorithm if is using the legacy one
        if ($user->hasLegacyPassword()) {
            // Credentials can be retrieved thanks to the false value of
            // the erase_credentials parameter in security.yml
            $plainPassword = $token->getCredentials();
            file_put_contents('darius.txt', 'test'.$plainPassword, FILE_APPEND); // why null?

        }

        $token->eraseCredentials();
    }
}

https://symfony.com/doc/current/reference/configuration/security.html#erase-credentials

如果为真,则调用用户对象的 eraseCredentials() 方法 认证后。

所以如果为假,它不应该被删除?为什么要擦除? 收到密码是因为登录有效。我只是在某个时候消失了。

更新

问题是为什么在调用之前凭据为空

$token->eraseCredentials();

【问题讨论】:

  • 您自己在 LoginListener 中调用了 eraseCredentials。这是故意的吗?
  • 我也对此感到困惑,但我认为问题是为什么$plainPasswordnull。那是在eraseCredentials() 之前。
  • @dbrumann - 但它是在 file_put_contents 调用之后,所以仍然应该有密码

标签: symfony


【解决方案1】:

设法安装了xdebug,发现创建令牌时没有设置凭据:

JsonLoginAuthenticator:

public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface
    {
        return new UsernamePasswordToken($passport->getUser(), null, $firewallName, $passport->getUser()->getRoles());
    }

用户名密码令牌:

public function __construct($user, $credentials, string $firewallName, array $roles = [])
    {
        parent::__construct($roles);

        if ('' === $firewallName) {
            throw new \InvalidArgumentException('$firewallName must not be empty.');
        }

        $this->setUser($user);
        $this->credentials = $credentials;
        $this->firewallName = $firewallName;

        parent::setAuthenticated(\count($roles) > 0);
    }

所以我想这就是问题 - 在安全性 - 防火墙下有这样的设置:

main:
        lazy: true
        provider: app_user_provider
        logout:
            path: logout
            target: after_logout
        json_login:
            check_path: /login
        entry_point: App\Security\AuthenticationEntryPoint

所以我可能已经回答了为什么没有凭据的问题。我现在只是想念如何在登录时为密码创建新的密码哈希,但这可能是针对不同的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 2016-09-11
    • 2023-04-02
    相关资源
    最近更新 更多