Skip to content
Advertisement

Symfony 5.2.11: Problem with creating Custom Access Decision Manager

I am trying to create a Custom Access Decision Manager by implementing AccessDecisionManagerInterface on Symfony 5.2.

Symfony recognizes the decision manager and instantiate it, but it doesn’t pass Voters array to decision manager. So it can’t collect votes, however the default decision manager works fine. I have followed the information provided on Symfony website. I have also copied the decision manager file to my AppSecurity and just changed the class+file name but it didn’t work. Adding the custom decision manager to service.yml didn’t help too.

Has anyone encountered the same problem? Any chance to fix it?

UPDATE #1

With reference to the issue https://github.com/symfony/symfony/issues/41123

I encountered this issue with different symptoms!

Although I knew the service is automatically registered but I did this in service.yml:

JavaScript

then I added decision manager to security.yml:

JavaScript

As you can see below, arguments haven’t been passed to the decision manager:

JavaScript

When I use default AccessDecisionManager voters are passed. I need to implement special authorization so I need to create my own decision manager. By the way, my decision manager implements AccessDecisionManagerInterface

I also checked SecurityBundleDependencyInjectionCompilerAddSecurityVotersPass->process() , it is not being called when my decision manager is set.

UPDATE #2 For testing, I temporarily renamed default AccessDecisionManager.php and placed my decision manager, it surprisingly worked. But it is not the solution. Still looking for the correct solution.

Advertisement

Answer

Thank you guys for your replies and helps, I figured it out.

Workaround

When Symfony compiles the code, it (somehow) has its own service definitions, so it doesn’t get confused. I traced the code into the compiled cache and I found that it can’t determine the service definitions of my ADM. So I changed my service.yml and defined arguments as follows:

JavaScript

Inside vendor/symfony/security-bundle/DependencyInjection/Compiler/AddSecurityVotersPass.php I found that there is argument replacement which enumerates service arguments by number, that is why I added unnamed service arguments.

JavaScript

The traces showed that Symfony collects all voters correctly up to this point, so it is not needed to manage dependencies manually.

By using this service.yml, I didn’t need to define the access_decision_manager in security.yml.

After finding the problem, I tried to use access_decision_manager but it caused the same error, means it didn’t receive list of voters. Then I decided to stop working on the problem as it is working for me now.

Conclusion

I know AccessDecisionManager is somehow a deep Symfony concept which is rarely used for common projects, but:

  1. Documentation doesn’t adequately cover this part
  2. When a developer implements an interface and injects it to Symfony, it is supposed either to be treated exactly same as the native code or provide enough descriptive logs or details to show noncompliance
  3. The method I used to fix the problem is not standard and might need modification in the future
  4. Symfony misbehaves when it is processing access_decision_manager from security.yml

Probably this part of Symfony needs to be reviewed.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement