Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 The user provider must return a UserInterface object on login

Tags:

php

symfony

I'm actually trying to create a login form matching with my database.

The form works well but I've a problem using a UserRepository. Symfony gives me the following error:

The user provider must return a UserInterface object.
exception 'Symfony\Component\Security\Core\Exception\AuthenticationServiceException' with message 'The user provider must return a UserInterface object.' in C:\wamp\www\php\Promocast\Symfony\vendor\symfony\src\Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider.php:101

But as you can see below, my user entity is implemented by UserInterface so I really don't understand what's the mistake here.

My user entity:

    <?php

    namespace Promocast\UtilisateurBundle\Entity;

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

    /**
     * Promocast\UtilisateurBundle\Entity\ImUser
     * 
     * @ORM\Entity(repositoryClass="Promocast\UtilisateurBundle\Entity\ImUserRepository")
     */
    class ImUser implements UserInterface
    {

        /**
        * Here all my var and getter/setter
        * ...
        */

        /**
         * Fonctions UserInterface
         * 
         */
        public function eraseCredentials()
        {
        }
        public function getRoles()
        {
            return $this->idrole;
        }
        public function equals(UserInterface $user)
        {
            return $user->getUsername() === $this->login;
        }
        public function getUsername()
        {
            return $this->login;
        }
        public function getSalt()
        {
            return '';
        }

    }

My user repository:

    <?php

    namespace Promocast\UtilisateurBundle\Entity;

    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;
    use Doctrine\ORM\EntityRepository;
    use Doctrine\ORM\NoResultException;

    class ImUserRepository extends EntityRepository implements UserProviderInterface
    {
        public function loadUserByUsername($login)
        {
            $user = $this->findBy(array("login" => $login));

            if (!$user) {
                throw new UsernameNotFoundException(sprintf('No user with name "%s" was found.', $login));
            }

            return $user;
        }

        public function refreshUser(UserInterface $user)
        {
            return $this->loadUserByUsername($user->getUsername());
        }

        public function supportsClass($class)
        {
            return $class === 'Promocast\UtilisateurBundle\Entity\ImUser';
        }
    }

And my security.yml:

    security:
        encoders:
            Promocast\UtilisateurBundle\Entity\ImUser: plaintext
            #Promocast\UtilisateurBundle\Security\Provider\LoginWebService: plaintext

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

        providers:
            main:
                entity: { class: PromocastUtilisateurBundle:ImUser }
                #entity: { class: Promocast\UtilisateurBundle\Entity\ImUser, property: login }
                #id: webservice_user_provider


        firewalls:
            dev:
                pattern:  ^/(_(profiler|wdt)|css|images|js)/
                security: false
            login:
                pattern:   ^/(login$|register|resetting) 
                anonymous: true                          
            main:
                pattern: ^/                      
                form_login:                      
                    login_path: /login              
                    check_path: /login_check            
                    username_parameter: _login
                    password_parameter: _password
                remember_me:
                    key:         %secret%       
                anonymous:       true           
                provider:        main
                logout:          true            
                logout:
                    path: /logout
                    target: /

        access_control:
            #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
            #- { path: ^/_internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }
            #- { path: /.*, role: ROLE_USER }
            #- { path: /login, role: IS_AUTHENTICATED_ANONYMOUSLY }

Thanks a lot!

like image 746
Snroki Avatar asked Dec 04 '25 11:12

Snroki


1 Answers

It looks like your problem is here:

public function loadUserByUsername($login)
{
    $user = $this->findBy(array("login" => $login));
    if (!$user) {
        throw new UsernameNotFoundException(sprintf('No user with name "%s" was found.', $login));
    }

    return $user;
}

$this->findBy() is probably returning a cursor/resultset rather than one row as you intended (even if the resultset contains only one row).

Try just using $this->findOneBy() instead.

Based on your code, it looks like you are following the cookbook tutorial on How to load Security Users from the Database (the Entity Provider) - but if you're not, that is a helpful resource in this case.

like image 134
leek Avatar answered Dec 07 '25 01:12

leek