Проблема аутентификации Symfony2 - PullRequest
1 голос
/ 09 сентября 2011

Попытка реализовать пользовательский доступ на основе ролей в Symfony2, но каким-то образом Symfony2 не извлекает пользователя из базы данных.Все, что я получаю, это ошибка Bad Credentials.Когда я пытаюсь войти в систему как пользователь в памяти - он работает нормально.Я что-то упустил?

Мой security.yml

security:
encoders:
    Symfony\Component\Security\Core\User\User:
        algorithm: sha512
        encode-as-base64: true
        iterations: 3

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

providers:
    in_memory:
        users:
            user:  { password: userpass, roles: [ 'ROLE_USER' ] }
    main:
        entity: { class: Web20CMSBundle:User, property: username }              

firewalls:    
    secured_area:        
        pattern: /admin.*|/login_check
        anonymous: ~
        form_login:
            check_path: /login_check
            login_path: /login
        logout: { path: /admin/logout, target: / }
        security: true
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false
access_control:        
    - { path: /admin/.*, role: ROLE_ADMIN }
    - { path: /.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: /login.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

мой routing.yml

_security_login:
    pattern:  /login
    defaults: { _controller: Web20CMSBundle:Security:login }

_security_check:
    pattern:  /login_check

_security_logout:
    pattern:  /admin/logout

index:
    pattern: /
    defaults: { _controller: JutaShopBundle:Default:index }

мой объект роли

<?php
namespace Web20\CMSBundle\Entity;

use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="role")
 */
class Role implements RoleInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

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

    /**
     * @ORM\Column(name="createdAt", type="datetime", name="created_at")
     */
    protected $createdAt;

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

    /**
     * @return string The name.
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $value The name.
     */
    public function setName($value)
    {
        $this->name = $value;
    }

    /**
     * @return DateTime A DateTime object.
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Constructs a new instance of Role.
     */
    public function __construct()
    {
        $this->createdAt = new \DateTime();
    }

    /**
     * Implementation of getRole for the RoleInterface.
     * 
     * @return string The role.
     */
    public function getRole()
    {
        return $this->getName();
    }
}

МойSecurityController

<?php

namespace Web20\CMSBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
use Web20\CMSBundle\Entity\Category;

class SecurityController extends Controller
{
    public function loginAction()
    {
        if ($this->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
            $error = $this->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
        } else {
            $error = $this->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
        }

        //$em = $this->getDoctrine()->getEntityManager();
        //$salt = $em->getRepository('Web20\CMSBundle\Entity\User')->findOneById(1);
        //print_r($salt->getSalt());

        return $this->render('Web20CMSBundle:Default:login.html.twig', array(
            'last_username' => $this->get('request')->getSession()->get(SecurityContext::LAST_USERNAME),
            'error' => $error
        ));
    }

}

Сущность «Мой пользователь»

<?php
namespace Web20\CMSBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;

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

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

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

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

    /**  
     * @ORM\ManyToMany(targetEntity="Role")
     * @ORM\JoinTable(name="user_role",
     *     joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")}, 
     *     inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
     * )
     * @var ArrayCollection $role
     * !IMPORTANTE!: onDelete="cascade" is necessary
     */
    private $userRoles;

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

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

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

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

    /**
     * @param string $value The username.
     */
    public function setUsername($value)
    {
        $this->username = $value;
    }

    /**
     * @param string $value The first name.
     */
    public function setFirstName($value)
    {
        $this->firstName = $value;
    }

    /**
     * @param string $value The last name.
     */
    public function setLastName($value)
    {
        $this->lastName = $value;
    }   

    /**
     * @param string $value The email address.
     */
    public function setEmail($value)
    {
        $this->email = $value;
    }       

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

    /**
     * @param string $value The password.
     */
    public function setPassword($value)
    {
        $this->password = $value;
    }

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

    /**
     * @param string $value The salt.
     */
    public function setSalt($value)
    {
        $this->salt = $value;
    }

    /**
     * @return ArrayCollection A Doctrine ArrayCollection
     */
    public function getUserRoles()
    {
        return $this->userRoles;
    }

    /**
     * Constructs a new instance of User
     */
    public function __construct()
    {
        $this->userRoles = new ArrayCollection();
        $this->createdAt = new \DateTime();
    }

    /**
     * Erases the user credentials.
     */
    public function eraseCredentials()
    {

    }

    /**
     * @return array An array of Role objects
     */
    public function getRoles()
    {
        return $this->getUserRoles()->toArray();
    }

    /**
     * Compares this user to another to determine if they are the same.
     * 
     * @param UserInterface $user The user
     * @return boolean True if equal, false othwerwise.
     */
    public function equals(UserInterface $user)
    {
        return md5($this->getUsername()) == md5($user->getUsername());
    } 
}

Важная часть login.html.twig выглядит следующим образом:

        <label for="_username">Username:</label>
            <input type="text" name="_username" id="username" value="{{ last_username }}"/>
        <label for="_password">Password:</label>
            <input type="password" name="_password" id="password"/>

, когда пользователь создается какэто:

    $role = new Role();
    $role->setName('ROLE_ADMIN');

    $role1 = new Role();
    $role1->setName('ROLE_CUSTOMER');


$role2 = new Role();
$role2->setName('ROLE_SALESMAN');       

$role3 = new Role();
$role3->setName('ROLE_CONTENT_ADMIN');              

$manager->persist($role); 
    $manager->persist($role1); 
    $manager->persist($role2); 
    $manager->persist($role3); 

$user = new User();
$user->setFirstName('FirstName');
$user->setLastName('LastName');
$user->setEmail('lulz@roflmao.com');
$user->setUsername('admin');
$user->setSalt(md5(time()));

$encoder = new MessageDigestPasswordEncoder('sha512', true, 3);
$password = $encoder->encodePassword('admin', $user->getSalt());
$user->setPassword($password);

$user->getUserRoles()->add($role);


    $manager->persist($user);
$manager->flush();

1 Ответ

2 голосов
/ 01 октября 2011

У меня нет времени, чтобы проверить весь ваш код, но я вижу две вещи: 1) Ваш пользователь 'user' не сможет войти в систему, потому что вы дали ему пароль: 'userpass', хотя вы установили пароли в 3 раза, sha512 и затем base64. Вы должны закодировать свой пароль, а затем использовать закодированный в файле настроек. 2) У меня была проблема с «encode-as-base64: true». Если вы не можете войти после устранения первой проблемы, попробуйте использовать «encode-as-base64: false». Конечно, на этот раз вы должны предоставить пароль, не закодированный как base64.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...