Symfony2安全性,使用sha512,无法正常工作。接收Bad Credentials消息

时间:2013-11-23 22:22:10

标签: php security symfony encoder sha512

我正在尝试将我的安全编码器从明文更改为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(),
    );
}

1 个答案:

答案 0 :(得分:1)

啊,啊......我找到了。拆开Symfony Security捆绑包后,我发现它从未真正从数据库中获取记录,我确认在那里。我比较了在方法(retrieveUser())中检查过的用户名,并且当用户在从数据库中检索记录的部分结束以确认凭证的有效性时,用户名是不正确的。 / p>

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

在DaoAuthenticationProvider.php中查看您的用户名 - &gt; retrieveUser()。还要加一个die();就在AuthenticationProviderManager()中调用匿名提供程序之前。

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