Skip to content

Commit

Permalink
feature #6024 Performance improvement: SecurityVoter implements suppo…
Browse files Browse the repository at this point in the history
…rtsAttribute from CacheableVoterInterface (rneuter)

This PR was merged into the 4.x branch.

Discussion
----------

Performance improvement: SecurityVoter implements supportsAttribute from CacheableVoterInterface

Hi,

Our application is performing a lot of permission checks, and specially some greedy ones on properties. So I was reading some documentation about Symfony voters performance and finally read these articles:

- [New in Symfony 5.4: Faster Security Voters](https://symfony.com/blog/new-in-symfony-5-4-faster-security-voters)
- [The Voter Interface](https://symfony.com/doc/current/security/voters.html#the-voter-interface)

These two links explain how voter performance can be improved by the usage of the [CacheableVoterInterface](https://github.com/symfony/symfony/blob/6.3/src/Symfony/Component/Security/Core/Authorization/Voter/CacheableVoterInterface.php):

> Checking each voter several times can be time consuming for applications that perform a lot of permission checks. To improve performance in those cases, you can make your voters implement the [CacheableVoterInterface](https://github.com/symfony/symfony/blob/6.3/src/Symfony/Component/Security/Core/Authorization/Voter/CacheableVoterInterface.php). This allows the access decision manager to remember the attribute and type of subject supported by the voter, to only call the needed voters each time.

> During runtime, whenever Symfony finds a isGranted() method call, it iterates over all the voters, and stops when the configured [access decision strategy](https://symfony.com/doc/current/security/voters.html#changing-the-access-decision-strategy) is met. This works well in most applications, but it hurts performance in some scenarios.

> Consider a backend that displays a listing of 20 entities, each of them showing 6 properties and 3 actions (e.g. edit, show, delete). If you want to check permissions for accessing those properties and running those actions, you are calling each voter 20 x (6 + 3) = 180 times. If you have 5 voters, that's 900 calls.

So this branch changes removes the calls to the `EasyCorp\Bundle\EasyAdminBundle\Security\SecurityVoter` when it is not necessary by implementing the function `supportsAttribute` from the `Symfony\Component\Security\Core\Authorization\Voter\CacheableVoterInterface`.

Those screenshots below are made from the Symfony debug bar from a route from our app which not implied calls to the  `EasyCorp\Bundle\EasyAdminBundle\Security\SecurityVoter`.

**Before changes**
![before_changes](https://github.com/EasyCorp/EasyAdminBundle/assets/19284102/7d9d33b8-f6e0-476b-a24f-eb6767437bf7)

**After changes**
![after_changes](https://github.com/EasyCorp/EasyAdminBundle/assets/19284102/57e963b5-4050-4a11-908c-0e2f93d280f0)

This performance improvement will be more visible when the access decision manager strategy is configured to `unanimous` as in this specific case, all voters have to be called to be sure no one is denying the access.

Commits
-------

fb94a20 Performance improvement: SecurityVoter implements supportsAttribute from Symfony\Component\Security\Core\Authorization\Voter\CacheableVoterInterface which allows the access decision manager to cache the supported attributes by the voter
  • Loading branch information
javiereguiluz committed Nov 16, 2023
2 parents d66ff09 + fb94a20 commit 92e5475
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Security/SecurityVoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public function __construct(AuthorizationCheckerInterface $authorizationChecker,
}

protected function supports(string $permissionName, mixed $subject): bool
{
return $this->supportsAttribute($permissionName);
}

public function supportsAttribute(string $permissionName): bool
{
return Permission::exists($permissionName);
}
Expand Down

0 comments on commit 92e5475

Please sign in to comment.