7
votes

I'm following http://symfony.com/doc/current/cookbook/security/voters.html and attempting to make a custom voter that denies access for requests that don't contain a valid API key and digest in the header (influenced by http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html - I'm not building an authentication provider because I need to use the FOSUserBundle provider for the same request).

I'd like to store my api keys / secrets in the in-memory user provider to begin with and likely migrate this to a custom mongodb provider at a later date. So I need a way of injecting the user provider into my voter. I've already injected the service container, but can the user providers can be accessed from it?

My service definition:

services:
    security.access.api_client_voter:
        class:     Acme\RestBundle\Security\Authorization\Voter\ApiClientVoter
        arguments: [@service_container, %kernel.cache_dir%/security/nonces]
        public:    false
        tags:
            - { name: monolog.logger, channel: authentication }
            - { name: security.voter }

So my question is, how do I inject the in-memory provider? The WSSE example in the cookbook seems to use an auth provider factory to replace the string 'security.providers.in_memory', but as I'm just using a voter, is this necessary? If it is necessary, what would my factory look like?

3

3 Answers

8
votes

The in-memory user provider is first defined as an abstract service in the SecurityBundle's security.xml. Based on your user provider's configuration in security.yml, the SecurityBundle's SecurityExtension then creates the concrete in-memory user provider service, to which each user gets added as a service. As you can see, the name of this service will be security.user.provider.concrete.[name-of-your-firewall]. So, it should be possible to use this service in or inject this service into your voter. You can always take a look in the dumped service container in your /app/cache directory to find out the names of services and if they are defined at all.

6
votes

The in-memory user provider service's name is security.user.provider.concrete.in_memory but the service is private, so you need to define an alias for it in config.yml:

services:
    in_memory_user_provider:
        alias: security.user.provider.concrete.in_memory

Now, you can access it as in_memory_user_provider.

0
votes

The service is already declared

<service id="security.user.provider.in_memory" class="Symfony\Component\Security\Core\User\InMemoryUserProvider" abstract="true" />