【发布时间】:2021-04-26 01:51:46
【问题描述】:
我正在与许多古老的员工一起开展一个遗留项目。有大量使用非常罕见的动作。半年前我们从 Symfony 2.8 升级到 Symfony 4.4。在经理尝试使用现在返回 AccessDeniedException: Access Denied. 的旧操作之一之前,一切都运行良好
我检查了 Symfony 文档,对我来说一切似乎都很简单。
检查用户是否已登录 (IS_AUTHENTICATED_FULLY)
如果您只想检查用户是否登录(您不关心角色),您有两种选择。首先,如果您为每个用户分配了 ROLE_USER,则可以检查该角色。
有app/config/security.yml有下一个配置:
security:
access_decision_manager:
strategy: unanimous
allow_if_all_abstain: true
encoders:
FOS\UserBundle\Model\UserInterface:
algorithm: sha512
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_CUSTOMER_ADMIN: ROLE_USER
ROLE_ADMIN: ROLE_USER
ROLE_ADMIN_CAN_EDIT_PERMISSIONS: ROLE_ADMIN
ROLE_SUPER_ADMIN: ROLE_ADMIN_CAN_EDIT_PERMISSIONS
providers:
fos_user:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_user
default_target_path: /user-post-login
always_use_default_target_path: true
login_path: user_security_login
check_path: fos_user_security_check
logout:
path: /logout
target: /login
handlers: [mp.logout_handler]
invalidate_session: false
anonymous: ~
remember_me:
secret: "%secret%"
lifetime: 31536000 # 365 days in seconds
path: /
domain: ~ # Defaults to the current domain from $_SERVER
access_control:
- { path: ^/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
...
- { path: ^/api, role: IS_AUTHENTICATED_ANONYMOUSLY }
...
- { path: ^/admin/select-customer-status, role: [ROLE_CUSTOMER_ADMIN, ROLE_SUPER_ADMIN] }
...
- { path: ^/admin, role: ROLE_USER }
我当前的用户有角色ROLE_SUPER_ADMIN,根据role_hierarchy这个角色在祖先中有ROLE_USER,但是当我尝试打开http://localhost:8080/admin/select-customer-status/1我得到了这个Access Denied 异常。
我尝试调试并发现这个异常出现在Symfony\Component\Security\Http\Firewall\AccessListener
但真正的问题是Voter 正在检查IS_AUTHENTICATED_FULLY under the hood,但$attributes 中不存在这个。
另一个有趣的事情是,当我将此配置直接添加到 Action 时,它按预期工作并且没有抛出异常:
/**
* @Route("/admin/update-user-permissions/{id}", name="update_user_permissions")
* @Method({"POST"})
*
* @IsGranted("ROLE_SUPER_ADMIN")
* @IsGranted("ROLE_CUSTOMER_ADMIN")
*/
有人可以帮忙解决这种奇怪的行为吗?
附:有a similar question,但它适用于 Symfony 2,对我来说并不可靠。
【问题讨论】:
-
只有当属性是
IS_AUTHENTICATED_*类型之一时,您链接的选民才会投票(否则继续并最终返回弃权,因为没有设置其他结果),所以它可能不是罪魁祸首。事实上,在开发模式下,分析器中有一个安全选项卡,显示所有投票者的结果。请检查哪个实际上拒绝访问。 -
很可能不是,但是您是否尝试在您的
access_control中设置roles而不是role?我在文档中看到的所有示例似乎都使用了roles,并且存在多个的事实可能会产生一些影响;o) 但是您的注释版本应该要求用户具有 both 角色。 -
@Jakumi,这里是安全标签的a screenshot。我不明白出了什么问题。
-
我尝试将
role更改为roles但这没有任何影响。 -
您发布的屏幕截图似乎暗示,用户必须拥有 both 角色,而仅拥有这两个角色之一的用户并非如此。您要么以某种方式引入 or (如下面的答案),要么为这两个组声明一个共同角色,这两个组在其层次结构中都提供了该共同角色,并改为使用该共同角色。
标签: php symfony symfony4 fosuserbundle