开发者

Symfony2 authentification issue

Trying to implement role-based user access in Symfony2, but somehow Symfony2 does not fetch user from the database. All I get is Bad Credentials error. When I do try to log in as in-memory user - it works fine. Am I missing something?

My 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 }

my 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 }

my Role entity

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

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

}

My User entity

<?php
namespace Web20\CMSBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as O开发者_运维技巧RM;

/**
 * @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());
    } 
}

The important part of login.html.twig looks like that:

        <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"/>

while the user is created like this:

    $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();


I don't have the time to check all your code but I see two things : 1) Your user 'user' won't be able to login because you gave him a password : 'userpass' although you have set the passwords to be 3 times sha512 encoded and then base64 encoded. You should encode your password and then use the encoded in the settings file. 2) I had a problem with 'encode-as-base64: true' . If you can't login after fixing the first issue then try using 'encode-as-base64: false'. Of course you must provide the password not encoded as base64 this time.

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜