2
votes

With currented build of Symfony 2.1 it should be possible to use MongoDB as Userprovider for the SecurityBundle without using FOSUserBundle (as introduced here: mongodb symfony user authentication?).

Can't figure out, where is actually the problem in the code, but I can't login with the predefined user test:test.

My security.yml looks like this:

security:
    encoders:
        test\TestBundle\Document\User: plaintext
    providers:
        document_members:
            mongodb: { class: testTestBundle:User, property: username }
    firewalls:
        secured_area:
            pattern:    ^/
            http_basic:
                realm:    "Login to TEST"
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
    role_hierarchy:
        ROLE_ADMIN:     ROLE_USER

The test/TestBundle/Document/User.php-Document:


namespace test\TestBundle\Document;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document(collection="user", repositoryClass="test\TestBundle\Document\UserRepository")
 */
class User implements UserInterface, EquatableInterface
{

    /**
     * @ODM\Id
     */
    protected $id;

    /**
     * @ODM\String
     */
    protected $username;

    /**
     * @ODM\String
     */
    protected $password;

    /**
     * @ODM\Collection
     */
    protected $roles = array();

    /**
     * @ODM\String
     */
    protected $salt;

    /**
     * @ODM\Boolean
     */
    protected $isActive;

// Setter

    /**
     * @param String
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * @param String
     */
    public function setPassword($password)
    {
        $this->password = $password;
    }

    /**
     * @param String
     */
    public function setRole($role)
    {
        $this->roles[] = $role;
    }

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

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

// Getter

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

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

    /**
     * @return array
     */
    public function getRoles()
    {
        return $this->roles;
    }

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

// General

    public function __construct()
    {
        $this->isActive = true;
        $this->salt = '';
    }

    public function isEqualTo(UserInterface $user)
    {
        return $user->getUsername() === $this->username;
    }

    public function eraseCredentials()
    {
    }

}

the test/TestBundle/Document/UserRepository.php:

namespace test\TestBundle\Document;

use Doctrine\ODM\MongoDB\DocumentRepository;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;

class UserRepository extends DocumentRepository implements UserProviderInterface
{
    public function loadUserByUsername($username)
    {
        $q = $this->createQueryBuilder()
            ->field('username')->equals((string) $username)
            ->getQuery();

        try
        {
            $user = $q->getSingleResult();
        }
        catch (NoResultException $e)
        {
            throw new UsernameNotFoundException(sprintf('Can\'t find Username "%s"', $username), null, 0, $e);
        }

        return $user;
    }

    public function refreshUser(UserInterface $user)
    {
        $class = get_class($user);
        if (!$this->supportsClass($class)) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class));
        }

        return $this->loadUserByUsername($user->getUsername());
    }

    public function supportsClass($class)
    {
        return $class === 'test\TestBundle\Document\User';
    }
}

The specific route:

Admin:
    pattern:  /admin
    defaults: { _controller: testTestBundle:Test:index }

(will lead to an existing controller and view)

the predefined user-Document looks like this:

Array
(
    [_id] => 4f59b5731c911ab41e001234
    [username] => test
    [password] => test
    [roles] => Array
        (
            [0] => ROLE_ADMIN
        )

    [salt] => 
    [isActive] => 1
)

But I can't login with the username test and password test at /admin.

1

1 Answers

1
votes

problem is related to an issue with using symfony on apache + fastCGI (https://github.com/symfony/symfony/pull/3551).

Above code works as expected.