0
votes

I developing own User Provider. For retrieving User I have injected my UserRepository:

app_bundle.api_key_user_provider:
    class: AppBundle\Security\User\ApiKeyUserProvider
    factory: ["@doctrine.orm.entity_manager", "getRepository"]
    arguments:
        - AppBundle\Entity\User

I also added EntityManager into __construct() method of my provider:

class ApiKeyUserProvider implements UserProviderInterface
{
    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function loadUserByUsername($email)
    {
        $user = $this->em->findBy(array('email' => $email));

        if (!$user) {
            throw new UsernameNotFoundException('User not found!');
        }

        $this->user = $user;

        return $user;
    }

    public function refreshUser(UserInterface $user)
    {
        return $user;
    }

    public function supportsClass($class)
    {
        return $class === 'AppBundle\Entity\User';
    }
}

But when Provider is called, I got next error:

Catchable Fatal Error: Argument 1 passed to Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider::__construct() must implement interface Symfony\Component\Security\Core\User\UserProviderInterface, instance of AppBundle\Repository\UserRepository given

I have tried to inject Symfony\Component\Security\Core\User\UserProviderInterface, but have no success. I pass as argument to services.yml provider definition next strings:

  1. Symfony\Component\Security\Core\User\UserProviderInterface (got error "class not exists")
  2. Vendor\Symfony\Component\Security\Core\User\UserProviderInterface (got same error)

Also I've searched for needed service in SecurityBundle, but found nothing.

My question: How can I inject Symfony\Component\Security\Core\User\UserProviderInterface to my ApiKeyUserProvider or what else I can do to solve this problem?

Thanks a lot for help!

1
ApiKeyUserProvider implements the UserProviderInterface?Matteo
@Matteo yes, implementsSergio Ivanuzzo
I have added my UserProvider class to my question.Sergio Ivanuzzo
If I correctly understand, The ApiKeyUserProvider IS your UserProvider, try define it in the service.yml as simple IOC without the factory definition. Otherwise i don't understand your situation (what are you looking for? Probably i miss a piece in your application...)Matteo
@Matteo you understand me correctly, ApiKeyUserProvider is my own UserProvider. I want to inject UserRepository into it instead of injecting entire entity manager. I think it's possible. So I try to find the way to do it.Sergio Ivanuzzo

1 Answers

1
votes

Your ApiKeyUserProvider expects EntityManager as a dependency. Your service definition is wrong in that case - just put this into services.yml

app_bundle.api_key_user_provider:
    class: AppBundle\Security\User\ApiKeyUserProvider
    arguments: ["@doctrine.orm.entity_manager"]

This will also need some adjustments in your class, since EntityManager does not have findBy method as you're trying to use it. So you need to change

$user = $this->em->findBy(array('email' => $email));

into

$user = $this->em->getRepository('AppBundle:User')->findBy(array('email' => $email));

EDIT: Basing on your comment I assume that you want to inject UserRepository, not whole EntityManager. To do so, you should define your UserRepository as a service and inject it into your class.

services.yml

app_bundle.user_repository:
    class: Doctrine\ORM\EntityRepository
    factory: ["@doctrine.orm.entity_manager", getRepository]
    arguments:
        - AppBundle\Entity\User

app_bundle.api_key_user_provider:
    class: AppBundle\Security\User\ApiKeyUserProvider
    arguments: ["@app_bundle.user_repository"]

ApiKeyUserProvider

class ApiKeyUserProvider implements UserProviderInterface
{
    public function __construct(UserRepository $repository)
    {
        $this->repository = $repository;
    }

    public function loadUserByUsername($email)
    {
        $user = $this->repository->findBy(array('email' => $email));
    }
}