2015-04-15 2 views
4

Я использую Symfony 2.6.6, и в настоящее время я пытаюсь использовать соль для пользователей моей базы данных. В процессе регистрации я делаю следующий хэш, сохраняя информацию пользователя через Doctrine.Symfony using salt in encodePassword

SRC/AppBundle/Форма/RegisterFormType.php

<?php 

$account->setSalt(base_convert(sha1(uniqid(mt_rand(), true)), 16, 36)); 
$account->setPassword($this->encodePassword($account, $account->getPlainPassword())); 

В этом же файле у меня есть эта функция:

<?php 

private function encodePassword(Account $account, $plainPassword) 
{ 
    $encoder = $this->container->get('security.encoder_factory')->getEncoder($account); 

    return $encoder->encodePassword($plainPassword, $account->getSalt()); 
} 

Это мой security.yml файл:

приложение/Config/security.yml

security: 
    encoders: 
     AppBundle\Entity\Account: bcrypt 

    providers: 
     database_users: 
      entity: { class: AppBundle:Account } 

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

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

     prod: 
      pattern: ^/ 
      form_login: 
       check_path: account_login_check 
       login_path: account_login 
       csrf_provider: form.csrf_provider 
      logout: 
       path: account_logout 
       target: home 
      anonymous: ~ 
      switch_user: ~ 
      remember_me: 
       key: "%secret%" 

    access_control: 
     - { path: ^/account/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/account/register, roles: IS_AUTHENTICATED_ANONYMOUSLY } 
     - { path: ^/account/logout, roles: IS_AUTHENTICATED_FULLY } 

В моей Сущности, эти соли ключи:

SRC/AppBundle/Entity/Account.php

<?php // src/AppBundle/Entity/Account.php 

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Security\Core\Role\Role; 
use Symfony\Component\Security\Core\User\AdvancedUserInterface; 
use Serializable; 
use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 

/** 
* @ORM\Table(name="accounts") 
* @ORM\Entity(repositoryClass="AppBundle\Entity\AccountRepository") 
* @UniqueEntity(fields="username", message="That username is taken!") 
* @UniqueEntity(fields="email", message="That email is taken!") 
*/ 
class Account implements AdvancedUserInterface, Serializable 
{ 
    /** 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\Column(name="username", type="string", length=30) 
    * @Assert\NotBlank(message="Give us at least 3 characters") 
    * @Assert\Length(min=3, minMessage="Give us at least 3 characters!") 
    */ 
    private $username; 

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

    /** 
    * @ORM\Column(name="salt", type="string") 
    */ 
    private $salt; 

    /** 
    * @ORM\Column(type="string", length=120) 
    * @Assert\NotBlank 
    * @Assert\Email 
    */ 
    private $email; 

    /** 
    * @ORM\Column(type="json_array") 
    */ 
    private $roles = array(); 

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

    /** 
    * @Assert\NotBlank 
    * @Assert\Regex(
    *  pattern="/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).*$/", 
    *  message="Use 1 upper case letter, 1 lower case letter, and 1 number" 
    *) 
    */ 
    private $plainPassword; 

    /** 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * @return string 
    */ 
    public function getUsername() 
    { 
     return $this->username; 
    } 

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

     return $this; 
    } 

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

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

     return $this; 
    } 

    /** 
    * @return string 
    */ 
    public function getPassword() 
    { 
     return $this->password; 
    } 

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

     return $this; 
    } 

    /** 
    * @return string 
    */ 
    public function getPlainPassword() 
    { 
     return $this->plainPassword; 
    } 

    /** 
    * @param $plainPassword 
    * @return string 
    */ 
    public function setPlainPassword($plainPassword) 
    { 
     $this->plainPassword = $plainPassword; 

     return $this; 
    } 

    /** 
    * @return array Role 
    */ 
    public function getRoles() 
    { 
     $roles = $this->roles; 
     $roles[] = 'ROLE_USER'; 

     return array_unique($roles); 
    } 

    /** 
    * @param array $roles 
    * @return Role 
    */ 
    public function setRoles(array $roles) 
    { 
     $this->roles = $roles; 

     return $this; 
    } 

    /** 
    * Removes sensitive data from the user 
    */ 
    public function eraseCredentials() 
    { 
     $this->setPlainPassword(null); 
    } 

    /** 
    * @return string 
    */ 
    public function getSalt() 
    { 
     return $this->salt; 
    } 

    /** 
    * @param $salt 
    * @return Account 
    */ 
    public function setSalt($salt) 
    { 
     $this->salt = $salt; 

     return $this; 
    } 

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

    /** 
    * @param boolean $isActive 
    */ 
    public function setIsActive($isActive) 
    { 
     $this->isActive = $isActive; 
    } 

    public function isAccountNonExpired() 
    { 
     return true; 
    } 

    public function isAccountNonLocked() 
    { 
     return true; 
    } 

    public function isCredentialsNonExpired() 
    { 
     return true; 
    } 

    public function isEnabled() 
    { 
     return $this->getIsActive(); 
    } 

    public function serialize() 
    { 
     return serialize(array(
      $this->id, 
      $this->username, 
      $this->password, 
      $this->salt 
     )); 
    } 

    public function unserialize($serialized) 
    { 
     list (
      $this->id, 
      $this->username, 
      $this->password, 
      $this->salt 
     ) = unserialize($serialized); 
    } 
} 

Когда я вхожу в систему, он работает, но Профилер говорит мне, что Authenticated? говорит: нет. Когда я меняю соль на что-то другое в базе данных, пользователь все равно может войти в систему.

Есть ли что-то, что мне не хватает в документации по Symfony или мне нужно изменить весь способ соления?

EDIT: Извините, я не включил, что я сериализую и несериализую $this->password, $this->salt.

EDIT 2: Включено app/config/security.yml и отправлено полностью src/AppBundle/Entity/Account.php файл от пользователя: ghanbari.

Спасибо, что прочитали мой вопрос.

+0

может разместить кодировщики и провайдеры в составе вашего security.yml здесь? – ghanbari

+0

и plz введите свой класс сущности учетной записи здесь, спасибо – ghanbari

+0

в symfony 2.6, вы можете использовать услугу «security.password_encoder», что проще – ghanbari

ответ

4

Прежде всего, ваш объект User должен реализовать интерфейс Serializable, и вы должны сериализовать идентификатор & соли.

Прочитано this.


EDIT: ваш класс объектов должен быть таким:

<?php // src/AppBundle/Entity/Account.php 

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Security\Core\Role\Role; 
use Symfony\Component\Security\Core\User\AdvancedUserInterface; 
use Serializable; 
use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 

/** 
* @ORM\Table(name="accounts") 
* @ORM\Entity(repositoryClass="AppBundle\Entity\AccountRepository") 
* @UniqueEntity(fields="username", message="That username is taken!") 
* @UniqueEntity(fields="email", message="That email is taken!") 
*/ 
class Account implements AdvancedUserInterface, Serializable 
{ 
    /** 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\Column(name="username", type="string", length=30) 
    * @Assert\NotBlank(message="Give us at least 3 characters") 
    * @Assert\Length(min=3, minMessage="Give us at least 3 characters!") 
    */ 
    private $username; 

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

    /** 
    * @ORM\Column(name="salt", type="string") 
    */ 
    private $salt; 

    /** 
    * @ORM\Column(type="string", length=120) 
    * @Assert\NotBlank 
    * @Assert\Email 
    */ 
    private $email; 

    /** 
    * @ORM\Column(type="json_array") 
    */ 
    private $roles = array(); 

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

    /** 
    * @Assert\NotBlank 
    * @Assert\Regex(
    *  pattern="/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).*$/", 
    *  message="Use 1 upper case letter, 1 lower case letter, and 1 number" 
    *) 
    */ 
    private $plainPassword; 

    /** 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * @return string 
    */ 
    public function getUsername() 
    { 
     return $this->username; 
    } 

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

     return $this; 
    } 

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

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

     return $this; 
    } 

    /** 
    * @return string 
    */ 
    public function getPassword() 
    { 
     return $this->password; 
    } 

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

     return $this; 
    } 

    /** 
    * @return string 
    */ 
    public function getPlainPassword() 
    { 
     return $this->plainPassword; 
    } 

    /** 
    * @param $plainPassword 
    * @return string 
    */ 
    public function setPlainPassword($plainPassword) 
    { 
     $this->plainPassword = $plainPassword; 

     return $this; 
    } 

    /** 
    * @return array Role 
    */ 
    public function getRoles() 
    { 
     $roles = $this->roles; 
     $roles[] = 'ROLE_USER'; 

     return array_unique($roles); 
    } 

    /** 
    * @param array $roles 
    * @return Role 
    */ 
    public function setRoles(array $roles) 
    { 
     $this->roles = $roles; 

     return $this; 
    } 

    /** 
    * Removes sensitive data from the user 
    */ 
    public function eraseCredentials() 
    { 
     $this->setPlainPassword(null); 
    } 

    /** 
    * @return string 
    */ 
    public function getSalt() 
    { 
     return null; 
    } 

    /** 
    * @param $salt 
    * @return Account 
    */ 
    public function setSalt($salt) 
    { 
     $this->salt = $salt; 

     return $this; 
    } 

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

    /** 
    * @param boolean $isActive 
    */ 
    public function setIsActive($isActive) 
    { 
     $this->isActive = $isActive; 
    } 

    public function isAccountNonExpired() 
    { 
     return true; 
    } 

    public function isAccountNonLocked() 
    { 
     return true; 
    } 

    public function isCredentialsNonExpired() 
    { 
     return true; 
    } 

    public function isEnabled() 
    { 
     return $this->getIsActive(); 
    } 

    public function serialize() 
    { 
     return serialize(array(
      $this->id, 
      $this->username, 
      $this->password, 
      $this->salt, 
      $this->isActive 
     )); 
    } 

    public function unserialize($serialized) 
    { 
     list (
      $this->id, 
      $this->username, 
      $this->password, 
      $this->salt, 
      $this->isActive 
      ) = unserialize($serialized); 
    } 
} 
+1

Спасибо за ваш комментарий. Я следил за этой статьей поваренной книги, чтобы создать свою систему учета, я забыл добавить эту информацию к моему вопросу. Я делаю сериализацию пароля и соли. –

1

Вы должны использовать Serializble интерфейс и implments его методы называются сериализации и unserializable. Определите свою солевую вариабельность внутри обеих функций.

+0

Спасибо за ваш комментарий. Я забыл добавить эту информацию к моему вопросу, я делаю сериализацию пароля и соли. –