Reputation: 325
I'm following this tutorial (How to Authenticate Users with API Keys) to implement api keys in my application.
I'm using my user repository class which was created based on this tutorial (How to load Security Users from the Database) as the user provider that is needed in the pre authentication process, because that class already has the methods described as need from the user provider in the tutorial I'm following, namely loadUserByUsername()
, refreshUser()
and supportsClass()
.
Symfony calls my apikey_authenticator
service which requires a user provider as argument. Because of that I've configured another service called userprovider
that is my user repository class, like this:
services:
apikey_authenticator:
class: MyBundle\Security\ApiKeyAuthenticator
arguments: ["@userprovider"]
userprovider:
class: MyBundle\Entity\UserRepository
But my user repository class is dependent on an entity manager, which I don't know how to inject. My doctrine's configuration is the default that comes with symfony:
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
How can I solve this? And is it a good idea using the user repository class as the user provider in this case?
Upvotes: 0
Views: 956
Reputation: 329
Just wanted to add my 2c as I have followed those guides you mentioned too.
I have defined an Authenticator and provider class. The authenticator only does the necessary security checks and the provider handles the database connections (returning a user by token for instance).
In the __construct of my provider I have this:
protected $em;
protected $repositoryClass = 'myrepoclass';
protected $repository;
public function __construct(EntityManager $em) {
$this->em = $em;
$this->repository = $this->em->getRepository($this->repositoryClass);
}
Now I can just call queries like $this->repository->findOneById($id); I explicitly defined the repository class, because it allows easier switching to other entity if needed I think (could be wrong thinking ofcourse).
In my services file I have this:
api_user_provider:
class: "%api_user_provider.class%"
arguments: ["@doctrine.orm.entity_manager"]
api_user_authenticator:
class: "%api_user_authenticator.class%"
arguments: ["@api_user_provider"]
The provider class is not the same (at least for me) as the entity class. I separated them, because I think that works cleaner.
Well, that's how I have set things up. Hope this helps :)
edit: As I have created a separate bundle (ApiBundle and UserBundle), I have separated the provider from the entity class. I also followed the 'load security users from database' tutorial and this is the final thing I came up with to implement API token authentication. Although you do have the same methods already in your repository, I still think that it's better to separate it from your repository class as I did (that of course depends on your needs) as I think that works cleaner. Of course, the decision is up to you what to do :)
Upvotes: 1
Reputation: 48865
Doctrine entity repositories are created using a factory. Here is an example:
cerad_game__game_repository__doctrine:
class: Cerad\Bundle\GameBundle\Doctrine\EntityRepository\GameRepository
factory_service: 'doctrine.orm.default_entity_manager'
factory_method: 'getRepository'
arguments:
- 'Cerad\Bundle\GameBundle\Doctrine\Entity\Game'
Is it a good idea? Might be cleaner to inject the repository into a UserProvider class instead of cluttering up the repository with the UserProvider methods. But either way will work.
Upvotes: 2