Symfony2 安全,使用 sha512,不工作。收到错误凭据消息

Posted

技术标签:

【中文标题】Symfony2 安全,使用 sha512,不工作。收到错误凭据消息【英文标题】:Symfony2 Security, Using sha512, not working. Receiving Bad Credentials message 【发布时间】:2013-12-08 17:40:21 【问题描述】:

我正在尝试将我的安全编码器从纯文本更改为 sha512。我已经完成了手册指示的所有内容以及我在网络上可以找到的所有内容。

我已经将密码和盐的字段大小增加到 255。我试过加盐和不加盐...我也试过 sha1 和 md5。

谁能看看我的代码并给我一些可能的解决方案的想法? 如果您需要任何其他信息,请告诉我。

安全配置

security:
encoders:
    Symfony\Component\Security\Core\User\User: plaintext
    Mortolian\Bundle\SecurityBundle\Entity\User:
        algorithm: sha512
        encode_as_base64: true
        iterations: 3

role_hierarchy:
    # ROLE_B - Business Role
    # ROLE_ADMIN - Administrators Role

    ROLE_B:  ROLE_B
    ROLE_ADMIN: [ROLE_B, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

providers:
    chain_provider:
        chain:
            providers: [user_db, in_memory]
    in_memory:
        memory:
            users:
                gideon:   password: 2open1, roles: [ 'ROLE_B' ] 
                admin:  password: admin, roles: [ 'ROLE_ADMIN' ] 
    user_db:
        entity:  class: Mortolian\Bundle\SecurityBundle\Entity\User, property: username 

firewalls:
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false

    login:
        pattern:  ^/$
        security: false

    backoffice_security:
        pattern: ^(/business/|/security/)
        form_login:
            check_path: mrt_security_check
            login_path: spacecom_business_homepage 
            always_use_default_target_path: true
            default_target_path: spacecom_business_dashboard 
        logout:
            path: mrt_security_logout
            target: /
        anonymous: ~
        #http_basic:
        #    realm: "Secured Demo Area"

access_control:
    -  path: ^/security/, roles: ROLE_ADMIN 
    -  path: ^/business/, roles: ROLE_B 
    #-  path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https 

用户实体

<?php

namespace Mortolian\Bundle\SecurityBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
* User
*
* @ORM\Table()
* @ORM\Entity()
*/
class User implements AdvancedUserInterface, \Serializable 
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255)
 */
private $fullname;

/**
 * @ORM\Column(type="string", length=255)
 */
private $telephone;

/**
 * @ORM\Column(type="string", length=25, unique=true)
 */
private $username;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 */
private $salt;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\Length(max = 4096)
 */
private $password;

/**
 * @ORM\Column(type="string", length=60, unique=true)
 */
private $email;

/**
 * @ORM\Column(name="is_active", type="boolean")
 */
private $isActive;

/**
 * @var \Doctrine\Common\Collections\ArrayCollection $userRoles
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
 */
private $userRoles;


/*
 * CLASS MAGIC FUNCTIONS
 */
public function __construct() 
    $this->userRoles = new \Doctrine\Common\Collections\ArrayCollection();
    //$this->salt = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);


public function __toString() 
    return $this->username;



/*
 * GETTERS AND SETTERS
*/
/**
 * @inheritDoc
 */
public function getId() 
    return $this->id;


/**
 * @return string
 */
public function getFullname() 
    return $this->fullname;


/**
 * @return string
 */
public function getTelephone() 
    return $this->telephone;


/**
 * @inheritDoc
 */
public function getUsername() 
    return $this->username;


/**
 * @inheritDoc
 */
public function getSalt() 
    return $this->salt;


/**
 * @inheritDoc
 */
public function getPassword() 
    return $this->password;


/**
 * Get roles
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getUserRoles() 
    return $this->userRoles;


/**
 * Get roles
 *
 * @return array
 */
public function getRoles() 
    return $this->userRoles->toArray();


/**
 * @inheritDoc
 */
public function eraseCredentials() 


/**
 *
 * @see \Serializable::serialize()
 */
public function serialize() 
    return serialize ( array (
            $this->id 
    ) );


/**
 * @see \Serializable::unserialize()
 */
public function unserialize($serialized) 
    list ( $this->id, ) = unserialize ( $serialized );


/**
 * @inheritDoc
 */
public function isAccountNonExpired() 
    return true;


/**
 * @inheritDoc
 */
public function isAccountNonLocked() 
    return true;


/**
 * @inheritDoc
 */
public function isCredentialsNonExpired() 
    return true;


/**
 * @inheritDoc
 */
public function isEnabled() 
    return $this->isActive;


/**
 * Set fullname
 *
 * @param string $fullname          
 * @return User
 */
public function setFullname($fullname) 
    $this->fullname = $fullname;

    return $this;


/**
 * Set telephone
 *
 * @param string $telephone         
 * @return User
 */
public function setTelephone($telephone) 
    $this->telephone = $telephone;

    return $this;


/**
 * Set username
 *
 * @param string $username          
 * @return User
 */
public function setUsername($username) 
    $this->username = $username;

    return $this;


/**
 * Set salt
 *
 * @param string $salt          
 * @return User
 */
public function setSalt($salt) 
    $this->salt = $salt;

    return $this;


/**
 * Set password
 *
 * @param string $password          
 * @return User
 */
public function setPassword($password) 
    $this->password = $password;

    return $this;


/**
 * Set email
 *
 * @param string $email         
 * @return User
 */
public function setEmail($email) 
    $this->email = $email;

    return $this;


/**
 * Get email
 *
 * @return string
 */
public function getEmail() 
    return $this->email;


/**
 * Set isActive
 *
 * @param boolean $isActive         
 * @return User
 */
public function setIsActive($isActive) 
    $this->isActive = $isActive;

    return $this;


/**
 * Get isActive
 *
 * @return boolean
 */
public function getIsActive() 
    return $this->isActive;


/**
 * Add roles
 *
 * @param \Mortolian\Bundle\SecurityBundle\Entity\Role $roles           
 * @return User
 */
public function addUserRole(\Mortolian\Bundle\SecurityBundle\Entity\Role $userRoles) 
    $this->userRoles [] = $userRoles;

    return $this;


/**
 * Remove roles
 *
 * @param \Mortolian\Bundle\SecurityBundle\Entity\Role $userRoles           
 */
public function removeUserRole(\Mortolian\Bundle\SecurityBundle\Entity\Role $userRoles) 
    $this->roles->removeElement ( $userRoles );


用于创建新用户的代码

/**
 * Creates a new User entity.
 *
 * @Route("/", name="user_create")
 * @Method("POST")
 * @Template("MortolianSecurityBundle:User:new.html.twig")
 */
public function createAction(Request $request)

    $entity = new User();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) 
        //encrypt user password
        $factory = $this->get('security.encoder_factory');
        $encoder = $factory->getEncoder($entity);

        //generate password
        $password = $encoder->encodePassword($form["password"]->getData(), $entity->getSalt());

        if (!$encoder->isPasswordValid($password, $form["password"]->getData(), $entity->getSalt())) 
            throw new \Exception('Password incorrectly encoded during user registration');
         else 
            $entity->setPassword($password);
        

        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('user_show', array('id' => $entity->getId())));
    

    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );

【问题讨论】:

您是如何在数据库中插入密码的?它已经编码了吗? 我使用编码方式插入密码。在对密码进行编码后,我还检查了它是否具有正确的编码。如果您需要更多详细信息,请在上面发布插入操作。我还将盐插入数据库。 盐:gxmc6n4wq74kg08sscgc4gogsocw4kc,密码:27bf6cc2f96533920a473e141c7398e17f7d1fe4d8869872eeda4fb107e8e6baadf9101a253beeb485ad08d8063a55287a7ccee94e8ae3ac67c7312c43da6ade 跨度> 我删除了 base 64 编码并重新创建了所有用户,以防您怀疑编码和编码器不匹配。 【参考方案1】:

啊……我找到了。拆开 Symfony 安全包后,我发现它从来没有真正从数据库中获得记录,我确认它在那里。我比较了在方法 (retrieveUser()) 中结束的用户名,该方法检查了这一点,果然,当用户名最终出现在从数据库中检索记录以确认凭据有效性的部分时,用户名不正确。

最初我将实体设置为使用电子邮件地址字段作为用户名。当您使用纯文本时,不知何故这仍然有效。我仍然需要弄清楚为什么会这样。

在 DaoAuthenticationProvider.php -> retrieveUser() 中检查您的用户名。还要添加一个 die();就在 AuthenticationProviderManager() 中调用匿名提供者之前。

最终:检查您的实体设置是否正确。

【讨论】:

以上是关于Symfony2 安全,使用 sha512,不工作。收到错误凭据消息的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SecureString 创建 SHA1 或 SHA512 哈希?

symfony2:使用 fosuserbundle 登录后使用引用

图解HTTPS建立过程

如何在 Java 中使用 SHA-512 对密码进行哈希处理?

图解HTTPS建立过程

密码学hash函数-SHA256-512