Symfony2 ACL access to multiple objects for multiple users
For this case I used a custom security service that verifies ManyToMany relations between entities. It`s not the ideal decision but keep in mind.
First we need to make listener that will be triggered at every controller action.
class SecurityListener{ protected $appSecurity; function __construct(AppSecurity $appSecurity) { $this->appSecurity = $appSecurity; } public function onKernelController(FilterControllerEvent $event) { $c = $event->getController(); /* * $controller passed can be either a class or a Closure. This is not usual in Symfony2 but it may happen. * If it is a class, it comes in array format */ if (!is_array($c)) { return; } $hasAccess = $this->appSecurity->hasAccessToContoller($c[0], $c[1], $event->getRequest()); if(!$hasAccess) { throw new AccessDeniedHttpException('Access denied.'); } }}
In service we have access to request, controller instance and called action. So we can make a decision have user access or not.
class AppSecurity{ protected $em; protected $security; /** @var $user User */ protected $user; public function __construct(EntityManager $em, SecurityContext $security) { $this->em = $em; $this->security = $security; if($security->getToken() !== null && !$security->getToken() instanceof AnonymousToken) { $this->user = $security->getToken()->getUser(); } } /** * @param $controller * @param string $action */ public function hasAccessToContoller($controller, $action, Request $request) { $attrs = $request->attributes->all(); $client = $attrs['client']; /* db query to check link between logged user and request client */ }}
If you are using very nasty annotations like ParamConverter
you can easily extract ready to use entites from request.