Symfony2 Поставщик пользователя должен вернуть объект UserInterface при входе в систему - PullRequest
3 голосов
/ 09 марта 2012

Я на самом деле пытаюсь создать форму входа, соответствующую моей базе данных.

Форма работает хорошо, но у меня проблема с использованием UserRepository.Symfony выдает мне следующую ошибку:

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

Но, как вы можете видеть ниже, моя сущность пользователя реализована с помощью UserInterface, поэтому я действительно не понимаю, в чем здесь ошибка.

Мой пользовательский объект:

    <?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 '';
        }

    }

Мой пользовательский репозиторий:

    <?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';
        }
    }

И мой 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 }

Большое спасибо!

Ответы [ 2 ]

4 голосов
/ 11 марта 2012

Похоже, ваша проблема здесь:

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(), вероятно, возвращает курсор / набор результатов, а не одну строку, как вы планировали (даже если набор результатов содержит только одну строку).

Попробуйте просто использовать $this->findOneBy().

Исходя из вашего кода, похоже, что вы следуете учебному пособию по поваренной книге на Как загрузить пользователей Security из базы данных (поставщик сущностей) - но если нет, это полезный ресурс в этом случае.

0 голосов
/ 09 марта 2012

Предостережение: я далеко не эксперт по системе безопасности S2.Я просто публикую то, что работает для меня.

В вашем конфигурационном файле нет ничего, что указывало бы системе использовать ImUserRepository в качестве провайдера пользователя.Таким образом, система в основном пытается использовать поставщика по умолчанию.Кроме того, использование репозитория в лучшем случае проблематично.Репозитории Doctrine могут поступать только от менеджеров сущностей Doctrine, поэтому вы просите систему сказать, эй, мой пользовательский класс является сущностью доктрины, поэтому я должен использовать репозиторий, и я предполагаю, что я буду использовать этот менеджер сущностей.Не произойдет.

Сделайте своего провайдера услуг сервисом, а затем внедрите в него менеджер сущностей.

security:
    providers:
        my_provider:
            id: zayso_core.user.provider


    <service id="zayso_core.user.provider" class="Zayso\CoreBundle\Component\User\UserProvider" public="true">
        <argument type="service" id="doctrine.orm.accounts_entity_manager" />
        <argument type="string">%zayso_core.user.class%</argument>
    </service>

Возможно, вы также захотите закодировать ваши пароли в конечном итоге так:

security:
    encoders:
        Zayso\AreaBundle\Component\User\User:
            id: zayso_core.user.encoder


    <service id="zayso_core.user.encoder" class="Zayso\CoreBundle\Component\User\Encoder" public="true">
    </service>

И это должно помочь вам.

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