mrohnstock
mrohnstock

Reputation: 450

Using mongodb for user authentication in symfony 2.1

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.

Upvotes: 2

Views: 3448

Answers (1)

mrohnstock
mrohnstock

Reputation: 450

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

Above code works as expected.

Upvotes: 1

Related Questions