繁体   English   中英

Symfony 4:ROLE_USER 不继承 IS_AUTHENTICATED_FULLY 并且投票者抛出 AccessDeniedException

[英]Symfony 4: ROLE_USER doesn't inherit IS_AUTHENTICATED_FULLY and Voter throws AccessDeniedException

我正在与许多古老的员工一起开展一个遗留项目。 有大量使用非常罕见的动作。 半年前,我们从 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 ,但$attributes中不存在这个。

另一个有趣的事情是,当我将此配置直接添加到 Action 时,它按预期工作并且没有抛出异常:

/**
 * @Route("/admin/update-user-permissions/{id}", name="update_user_permissions")
 * @Method({"POST"})
 * 
 * @IsGranted("ROLE_SUPER_ADMIN")
 * @IsGranted("ROLE_CUSTOMER_ADMIN")
 */

任何人都可以帮助解决这种奇怪的行为吗?

PS有一个类似的问题,但它适用于Symfony 2,对我来说不可靠。

显然发生的是,所有提到的角色都是必需的,即ROLE_SUPER_ADMIN ROLE_CUSTOMER_ADMIN ROLE_SUPER_ADMIN 据我了解您的问题描述,您的用户,但不是两者。

您提供的屏幕截图显示了在底部处理请求的访问管理器: 在此处输入图像描述

这清楚地表明, AuthenticatedVoter不是问题,因为它弃权(因为它只对IS_AUTHENTICATED_*角色(例如IS_AUTHENTICATED_FULLY )投票,这在其代码中也很容易看到。

但是,也很容易看出,两个角色都是单独检查的(。), RoleHierarchyVoter 现在尝试查看是否授予ROLE_CUSTOMER_ADMIN ,并且我假设您的用户具有ROLE_SUPER_ADMIN , RoleHierarchyVoter 将通过使用层次结构进行扩展到ROLE_SUPER_ADMINROLE_ADMIN_CAN_EDIT_PERMISSIONSROLE_ADMINROLE_USER 其中没有一个是ROLE_CUSTOMER_ADMIN

正如我在评论中建议的那样,您可能希望选择添加两个扩展管理员角色都拥有的新角色。 如果ROLE_ADMIN不合适,可能是ROLE_EXTENDED_ADMIN的。

ROLE_CUSTOMER_ADMIN: [ROLE_ADMIN, ROLE_EXTENDED_ADMIN]
ROLE_SUPER_ADMIN: [ROLE_ADMIN_CAN_EDIT_PERMISSIONS, ROLE_EXTENDED_ADMIN]

然后在访问控制中:

 - { path: ^/admin/select-customer-status, roles: ROLE_EXTENDED_ADMIN }

您可以使用

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;

/**
 * @Security("has_role('ROLE_SUPER_ADMIN') or has_role('ROLE_CUSTOMER_ADMIN')")
 */

that's all 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM