SensioFrameworkExtraBundle
SensioFrameworkExtraBundle copied to clipboard
attribute #[isGranted] behaviour with associated array in subject
Symfony version(s) affected: 5.3.0
Description
when i use isgranted by injecting the security component i can pass an associative array as subject and get the same keys in the voter. When i do the same with the #[IsGranted] attribute keys always have the name of the parameters.
How to reproduce
// In a controller
#[IsGranted('CUSTOM_VOTER', subject: ['foo' => 'structure', 'bar' => 'theme'])]
public function delete(Structure $structure, Theme $theme): Reponse
{
...
}
// In the voter
protected function supports($attribute, $subject): bool
{
dd($subject);
}
subject looks like [structure => ... , theme => ...] instead of [foo => ..., bar => ...].
if i use : $this->security->isGranted('CUSTOM_VOTER', ['foo' => 'structure', 'bar' => 'theme']) i get [foo => ..., bar => ...].
Possible Solution
this is behaviour is cause by Sensio\Bundle\FrameworkExtraBundle\EventListener\IsGrantedListener::onKernelControllerArguments
...
if (\is_array($subjectRef)) {
foreach ($subjectRef as $ref) {
if (!\array_key_exists($ref, $arguments)) {
throw $this->createMissingSubjectException($ref);
}
$subject[$ref] = $arguments[$ref];
}
}
...
it sets the subjectName ref as key instead of the real key.
it shoud do be like this.
...
if (\is_array($subjectRef)) {
foreach ($subjectRef as $key => $ref) {
if (!\array_key_exists($ref, $arguments)) {
throw $this->createMissingSubjectException($ref);
}
$subject[$key] = $arguments[$ref];
}
}
...