【问题标题】:Symfony2 UserPassword constraint gets a NULL passwordSymfony2 UserPassword 约束获取 NULL 密码
【发布时间】:2015-03-24 11:27:54
【问题描述】:

我只想允许用户在我的应用程序中更改他们的密码。我已经构建了一个表单来编辑密码,但验证从未通过,因为 UserPassword 约束中当前用户的密码始终为 NULL:

<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Security\Core\Validator\Constraints;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

class UserPasswordValidator extends ConstraintValidator
{
    private $securityContext;
    private $encoderFactory;

    public function __construct(SecurityContextInterface $securityContext, EncoderFactoryInterface $encoderFactory)
    {
        $this->securityContext = $securityContext;
        $this->encoderFactory = $encoderFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function validate($password, Constraint $constraint)
    {
        if (!$constraint instanceof UserPassword) {
            throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UserPassword');
        }

        $user = $this->securityContext->getToken()->getUser();

        if (!$user instanceof UserInterface) {
            throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.');
        }

        $encoder = $this->encoderFactory->getEncoder($user);

        //I tried to print $user->getPassword from here and it is always NULL
        if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) {
            $this->context->addViolation($constraint->message);
        }
    }
}

这是我用来更改密码的表格:

class UserPasswordEditType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('oldPassword', 'password', array(
            'constraints' => array(
                new UserPassword(array(
                        'message' => 'password_current.invalid',
                        'groups' => 'user-password-edit'
                    )
                ),
                new NotBlank(array(
                    'message' => 'not_blank',
                    'groups' => 'user-password-edit'
                ))
            ),
            'mapped' => false,
            'required' => true,
        ))
            ->add('password', 'repeated', array(
                'type' => 'password',
                'invalid_message' => 'password_repeat.invalid',
                'required' => true,
                'first_options' => array('label' => 'password.label'),
                'second_options' => array('label' => 'password_repeat.label'),
            ))
            ->add('save', 'submit', array(
                'label' => 'save.label'
            ));
    }

    public function getName()
    {
        return 'user_edit_password';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'validation_groups' => array('user-password-edit'),
        ));
    }
}

这是security.yml的一部分

  security:
      encoders: 
          Symfony\Component\Security\Core\User\User: plaintext
          XXX\PrivateApplication\Bundle\UserBundle\Entity\User: plaintext

  role_hierarchy:
      ROLE_ADMIN:       ROLE_USER
      ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

  providers:
      chain_provider:
        chain:
            providers: [in_memory, user_db]
      in_memory:
          memory:
              users:
                  API_DOC:  { password: @aaa, roles: [ 'ROLE_API_DOC' ] }
      user_db:
          entity: { class: XXX\PrivateApplication\Bundle\UserBundle\Entity\User, property: username }

为什么在约束条件下登录用户的密码始终为 NULL?如果我从控制器打印它就可以工作......我不使用 FOSUserBundle。

谢谢

PS: 我发现了一个类似的问题Using Symfony2 UserPassword validator in form type,但没有回复...

【问题讨论】:

  • 您找到解决方案了吗?我遇到了同样的问题。

标签: forms validation symfony constraints


【解决方案1】:

为什么在约束条件下登录用户的密码始终为 NULL?如果我从控制器打印它,它就可以工作......

问题是,$password 是表单中的纯密码,而不是 getPassword()!您从安全上下文的令牌中检索“登录”用户,并且编码的密码为 NULL。这意味着,getUsername() 也可能为 NULL,getRoles() 只是匿名或访客(现在不知道)。

然后登录根本不起作用,令牌只是匿名的。

【讨论】:

  • 不。在控制器中,我可以使用 $this->getUser()->getPassword() 打印密码。并且用户已完全登录,我可以从约束中打印其他信息(如用户名等)。
  • 你使用 fos_user 吗?也许您使用不同的安全上下文?
  • 我已经更新了插入有关 security.yml 的信息的问题。不,我不使用 fos_user。
  • 请同时添加来自services.yml的行如何创建UserPasswordValidator
  • 我不能,这不是自定义验证器。 UserPassword 验证器包含在 Symfony 约束套件中:symfony.com/en/doc/current/reference/constraints/…
猜你喜欢
  • 1970-01-01
  • 2014-07-23
  • 2019-08-05
  • 2021-12-17
  • 2015-08-07
  • 1970-01-01
  • 2020-10-28
  • 2012-08-28
  • 1970-01-01
相关资源
最近更新 更多