Symfony中admin的access_control配置不生效问题排查
先还原下你的问题场景:
你配置了Symfony的Security规则如下:
security: access_control: - { path: '^/(%app.locales%)/profile/messages', roles: [ROLE_ADMIN]} role_hierarchy: ROLE_ADMIN: [ROLE_USER]
但拥有ROLE_ADMIN角色的用户访问该路径时被拒绝,把roles改成[ROLE_USER]后就能正常访问,想知道问题出在哪。
结合Symfony Security的工作机制,我梳理几个最可能的原因,你可以逐一排查:
1. 用户实际并未持有ROLE_ADMIN角色
这是最常见的情况——你以为用户有ROLE_ADMIN,但实际认证后用户的角色列表里只有ROLE_USER。
你可以在控制器里临时添加调试代码,打印用户的实际角色:
dump($this->getUser()->getRoles()); die;
如果输出里只有ROLE_USER,那说明用户的角色配置有误:比如数据库里该用户的角色字段存的是ROLE_USER,或者用户实体的getRoles()方法没有正确返回ROLE_ADMIN。
2. role_hierarchy配置未生效(缩进错误)
YAML配置对缩进极其敏感,如果你的role_hierarchy没有正确缩进在security节点下(比如和security平级),Symfony会忽略这个配置。不过这种情况通常会导致ROLE_ADMIN不继承ROLE_USER,和你的场景不完全匹配,但还是建议检查配置文件的缩进是否规范。
3. 路径正则匹配异常
虽然改成ROLE_USER能访问说明路径大概率是匹配的,但还是可以验证下%app.locales%变量是否正确解析。比如你的app.locales参数如果是en|fr,那生成的正则是^/(en|fr)/profile/messages,你可以直接用这个正则测试用户访问的实际路径是否匹配。
4. 权限规则顺序冲突
如果你的access_control里还有其他规则在这条之前,而且那条规则已经匹配了该路径并允许ROLE_USER访问,那后面的ROLE_ADMIN规则会被忽略。不过这种情况应该是两种配置都能访问,所以可能性较低,但你可以检查下规则顺序。
总结来说,优先排查用户实际的角色列表,这是最容易踩坑的点。
内容的提问来源于stack exchange,提问作者Billizzard

