dook0034 2013-11-23 22:22
浏览 85

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

I am trying to change my security encoder from plaintext to sha512. I have done everything the manual indicated and everything I could find on the web.

I have already increased the field sizes to 255 for both password and salt. I have tried with and without salt... I have tried sha1 and md5 as well.

Can anyone have a look at my code and give me some ideas for a possible solution? Let me know if you require any other information.

Security Config

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 }

User Entity

<?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 );
}
}

Code used to create a new user

/**
 * 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条回答 默认 最新

  • dqysi86208 2013-11-24 09:39
    关注

    Ahhhh... i found it. After taking apart Symfony Security bundle, I saw that it never really got a record from the database, which I confirmed was there. I compared the username that ended up in the method (retrieveUser()) which checked this, and sure enough, the username was incorrect when it ended up at the part that retrieved the record from the database to confirm the validity of the credentials.

    Initially I setup the entity to use the email address field as the username. Somehow this still worked when you use plain text. I still have to figure out why that happened.

    Check your username in DaoAuthenticationProvider.php -> retrieveUser(). Also add a die(); just before the Anonymous provider is called in AuthenticationProviderManager().

    ULTIMATELY : check that your entity is set up correctly.

    评论

报告相同问题?

悬赏问题

  • ¥60 pb数据库修改或者求完整pb库存系统,需为pb自带数据库
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路