Commit e2c48152 authored by Haralan Dobrev's avatar Haralan Dobrev Committed by Fabien Potencier

Use ServiceIterator in Security provider for voters

parent eb559d4c
......@@ -681,6 +681,32 @@ Symfony `cookbook`_.
providers. :doc:`How to Create a Custom Authentication System with Guard
</cookbook/guard_authentication>`
Using Voters to check user permissions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See the `Security component documentation on voters <http://symfony.com/doc/current/security/voters.html>`_.
By default Silex includes the role hierarchy and authenticated voters.
If you want to add a custom voter, you need to register it as a service and extend ``security.voter_services``.
.. code-block:: php
$app['custom_voter'] = function () {
return MyCustomVoter();
};
$app->extend('security.voter_services', function (array $voters) {
$voters[] = 'custom_voter';
return $voters;
});
.. note::
Using the above approach with the service names circular references are avoided
and you can use the ``AccessDecisionManager`` in your custom voter
to `check for roles inside a voter
<http://symfony.com/doc/current/security/voters.html#checking-for-roles-inside-a-voter>`_.
Stateless Authentication
~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -12,6 +12,7 @@
namespace Silex\Provider;
use Pimple\Container;
use Pimple\ServiceIterator;
use Pimple\ServiceProviderInterface;
use Silex\Application;
use Silex\Api\BootableProviderInterface;
......@@ -140,14 +141,29 @@ class SecurityServiceProvider implements ServiceProviderInterface, EventListener
};
$app['security.access_manager'] = function ($app) {
return new AccessDecisionManager($app['security.voters']);
$votersIterator = new ServiceIterator($app, $app['security.voter_services']);
return new AccessDecisionManager($votersIterator);
};
$app['security.voter_services'] = function () {
return [RoleHierarchyVoter::class, AuthenticatedVoter::class];
};
$app[RoleHierarchyVoter::class] = function ($app) {
return new RoleHierarchyVoter(new RoleHierarchy($app['security.role_hierarchy']));
};
$app[AuthenticatedVoter::class] = function ($app) {
return new AuthenticatedVoter($app['security.trust_resolver']);
};
// Unused, kept for backwards-compatibility
// Extend security.voter_services instead to prevent circular references
$app['security.voters'] = function ($app) {
return [
new RoleHierarchyVoter(new RoleHierarchy($app['security.role_hierarchy'])),
new AuthenticatedVoter($app['security.trust_resolver']),
];
return array_map(function ($voterServiceId) use ($app) {
return $app[$voterServiceId];
});
};
$app['security.firewall'] = function ($app) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment