6
votes

I have five custom voters in my application and use strategy "consensus".

Sometimes my voters not work properly and after debugging I have found the reason.

The standard Symfony RoleHierarchyVoter always returns "1", therefore sum of "granted" results equals to sum of "deny" results. So, I need to disable this Voter, because I don't use RoleHierarchy.

1) How can I disable Voter in config?

2) Does it exist another solution for this issue?

Thanks a lot for any help!

UPDATED.

So, I have created own RoleHierarchyVoter which always return false. This Voter replace standard Voter, but I'm not sure this solution is true way. Maybe any other solutions?

2
You could look into compiler passes symfony.com/doc/current/cookbook/service_container/… to remove the service completely. Does seem like a strange default behavior though.Cerad
@Cerad tell me please, can be the reason of this issue that I have installed FOSUserBundle?Sergio Ivanuzzo
Don't know. I have not implemented the consensus strategy. I just know you can use a pass to modify service definitions. And I stay far far away from FOSUserBundle.Cerad
I have added this as bug report github.com/symfony/symfony/issues/16358Sergio Ivanuzzo
btw, currently impossible to remove definition of RoleHierarchyVoter, because it's registered with priority TYPE_BEFORE_OPTIMIZATION and performed before my compiler.Sergio Ivanuzzo

2 Answers

2
votes

So, currently I have solved the problem by creating own RoleHierarchyVoter, which always return false.

Currently impossible to remove definition of standard RoleHierarchyVoter, because it's registered with priority TYPE_BEFORE_OPTIMIZATION and performed before my own compiler.

Btw, you can find in SecurityBundle/DependencyInjection/SecurityExtension.php next lines:

private function createRoleHierarchy($config, ContainerBuilder $container)
    {
        if (!isset($config['role_hierarchy'])) {
            $container->removeDefinition('security.access.role_hierarchy_voter');

            return;
        }

        $container->setParameter('security.role_hierarchy.roles', $config['role_hierarchy']);
        $container->removeDefinition('security.access.simple_role_voter');
    }

Even when I set role_hierarchy: ~, isset($config['role_hierarchy'] will return true.

This issue has reported as bug https://github.com/symfony/symfony/issues/16358

0
votes

Documentation of the RoleVoter says:

RoleVoter votes if any attribute starts with a given prefix.

The default prefix the RoleVoter will check is ROLE_, passed as default parameter value in the constuctor. These are required, because the voter has to check the current logged in user.

Make sure your own voters implements VoterInterface and also check the voter's implementation of YourVoter::supportsClass. The FQN of the element of which you want to know the user has access to should be checked over there. Then the following config should be enough:

app.security.download_voter:
    class:      AppBundle\Security\Voter\DownloadVoter
    public:     false
    tags:
        - { name: security.voter }

So:

1) You should not disable this voter, because all other voters rely on the RoleHierarchy this voter does create for the current user when passing a vote.

2) For better understanding of the Voter you can let the DIC inject the logger in your voter, and add extra info to the profiler. That way your own voters aren't a black box anymore.