我试图通过在Symfony5.2上实现AccessDecisionManagerInterface来创建一个自定义访问决策管理器。
Symfony识别决策管理器并将其实例化,但它不会将投票者数组传递给决策经理。因此它不能收集选票,但是默认的决策管理器可以正常工作。我已经跟踪了Symfony网站上提供的信息。我还将决策管理器文件复制到我的App\Security中,并更改了class+file名称,但它没有工作。将自定义决策管理器添加到service.yml也没有帮助。
有没有人遇到过同样的问题?有机会修好吗?
更新#1
关于https://github.com/symfony/symfony/issues/41123问题
我遇到这个问题有不同的症状!
虽然我知道服务是自动注册的,但我是在service.yml中这样做的。
App\Security\SpecialAccessDecisionManager:
class: App\Security\SpecialAccessDecisionManager
autowire: false
autoconfigure: false
public: false然后我将决策管理器添加到security.yml中。
security:
access_decision_manager:
service: App\Security\SpecialAccessDecisionManager如下所示,参数尚未传递给决策管理器:
[root@dev7 rouzonline.test]# bin/console debug:container debug.security.access.decision_manager.inner --show-arguments
// This service is a private alias for the service
// App\Security\SpecialAccessDecisionManager
Information for Service "App\Security\SpecialAccessDecisionManager"
===================================================================
Description of SpecialAccessDecisionManager
---------------- -------------------------------------------
Option Value
---------------- -------------------------------------------
Service ID App\Security\SpecialAccessDecisionManager
Class App\Security\SpecialAccessDecisionManager
Tags -
Public no
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
---------------- -------------------------------------------
! [NOTE] The "debug.security.access.decision_manager.inner" service or alias has been removed or inlined when the
! container was compiled.
[root@dev7 rouzonline.test]#当我使用默认AccessDecisionManager时,投票者将被传递。我需要实现特殊的授权,所以我需要创建自己的决策管理器。顺便说一下,我的决策管理器实现了AccessDecisionManagerInterface
我还检查了\SecurityBundle\DependencyInjection\Compiler\AddSecurityVotersPass->process(),在设置决策管理器时不会调用它。
为了进行测试,我临时重命名了默认AccessDecisionManager.php并放置了决策管理器,这令人惊讶地起了作用。但这不是解决办法。还在寻找正确的解决方案。
发布于 2021-07-16 21:41:45
谢谢你们的回复和帮助,我想明白了。
解决办法
当Symfony编译代码时,它(不知怎么地)有自己的服务定义,所以不会混淆。我将代码跟踪到编译的缓存中,发现它无法确定我的ADM的服务定义。因此,我更改了我的service.yml并定义了如下参数:
security.access.decision_manager:
class: App\Security\SpecialAccessDecisionManager
arguments:
- []
- 'affirmative'
- false
- true在vendor/symfony/security-bundle/DependencyInjection/Compiler/AddSecurityVotersPass.php内部,我发现有参数替换,它按数字枚举服务参数,这就是为什么我添加了未命名的服务参数。
$container->getDefinition('security.access.decision_manager')
->replaceArgument(0, new IteratorArgument($voterServices));
}跟踪显示,直到目前为止,Symfony正确地收集了所有选民,因此不需要手动管理依赖项。
通过使用这个service.yml,我不需要在security.yml中定义access_decision_manager。
在发现问题后,我尝试使用access_decision_manager,但它导致了同样的错误,这意味着它没有收到选民名单。然后我决定停止处理这个问题,因为它现在正为我工作。
结论
我知道AccessDecisionManager在某种程度上是一个深层次的Symfony概念,很少用于普通项目,但是:
当开发人员实现一个接口并将其注入到Symfony时,noncompliance
security.yml
处理access_decision_manager时可能需要修改
这一部分可能需要复习一下。
https://stackoverflow.com/questions/68369936
复制相似问题