0

我想我在 Symfony 安全组件上达到了一些限制。这是我的问题:我有两个防火墙来管理两个用户类型(具有两个不同的实体)身份验证和对网站两个不同部分的访问。我有第三方来管理文件、上传……必须是私有的,并且两种用户类型都需要访问它。

所以我在security.yml中做了多个provider:

providers:
    # used to reload user from session & other features (e.g. switch_user)
    core_user_provider:
        entity:
            class: Akyos\CoreBundle\Entity\User
            property: email

    platform_user_provider:
        entity:
            class: App\Entity\Platform\UserPlatform
            property: email

    file_manager_provider:
        chain:
            providers: [core_user_provider, platform_user_provider]

和多个防火墙

防火墙:开发:模式:^/(_(profiler|wdt)|css|images|js)/ 安全性:false

    core:
        pattern: ^/(app|admin)/
        context: shared
        provider: core_user_provider
        anonymous: lazy
        guard:
            authenticators:
                - Akyos\CoreBundle\Security\CoreBundleAuthenticator
        logout:
            path: app_logout
            target: 'home'
        remember_me:
            secret:   '%kernel.secret%'
            lifetime: 604800 # 1 week in seconds
            path:     /

    file_manager:
        pattern: ^/(file-manager)
        context: shared
        provider: file_manager_provider
        anonymous: lazy
        guard:
            authenticators:
                - App\Security\FileManagerAuthenticator
        logout:
            path: file_manager_logout
            target: 'home'
        remember_me:
            secret:   '%kernel.secret%'
            lifetime: 604800 # 1 week in seconds
            path:     /

    platform:
        pattern: ^/(platorm_login|plateforme)
        context: shared
        provider: platform_user_provider
        anonymous: lazy
        guard:
            authenticators:
                - App\Security\PlatformAuthenticator
        logout:
            path: platform_logout
            target: 'home'
        remember_me:
            secret:   '%kernel.secret%'
            lifetime: 604800 # 1 week in seconds
            path:     /

    main:
        anonymous: lazy

因此,Platform 用户无法访问 Core,Core 用户也无法访问 Platform。但是两个用户都需要访问文件管理器,而无需重新登录。我不能将 /file-manager url 放在核心或平台防火墙下,因为另一个不会授予访问权限。所以我需要第三个防火墙来管理文件管理器访问。它使用对核心用户和平台用户进行分组的链提供商。它也不起作用,因为如果核心用户通过核心防火墙进行身份验证,则它没有通过文件管理器的身份验证,因此它重定向到文件管理器登录页面。如果用户登录文件管理器部分,它可以访问它,但是当它返回核心部分时,它必须再次重新连接。

我尝试了几件事,但最接近的解决方案是在防火墙上使用上下文选项,因此当用户通过核心部分登录时,它可以访问文件管理器部分而无需重新登录,因为两个防火墙共享相同的上下文。这就是我想要的。但我也需要它用于平台防火墙!因此,我还为其添加了相同的上下文选项,并且它有效,两种用户类型都可以访问文件管理器而无需再次登录 :D 但是由于三个防火墙共享相同的上下文,核心用户可以访问平台,反之亦然,并且这打破了所有的分离逻辑.. :'(

我需要一种方法来告诉安全组件“文件管理器防火墙与核心防火墙具有相同的上下文,文件管理器防火墙与平台防火墙具有相同的上下文,但核心和平台防火墙不共享相同的上下文”。像这样的东西:

firewalls:

    core:
        context: core

    file_manager:
        context: [core,platform]

    platform:
        context: platform

    main:
        anonymous: lazy

我一无所获。也许它无法完成,也许我必须创建自定义提供程序或身份验证器来破解它。也许我可以在没有 Symfony 的情况下做到这一点,毕竟它只是 php,所以我可以让每个人都可以访问文件管理器部分(所以在主防火墙下)并添加一个侦听器来检查请求是否针对文件管理器,如果有以前登录的用户,则在会话中查找,检查用户是核心用户还是平台用户,如果不是则重定向...?在没有 Symfony 功能的情况下,如何在“主防火墙”页面(= 作为匿名身份验证)上找到会话中以前的 Core 或 Platform 用户?我还不够好,不知道如何实现这一目标。帮助 ?

谢谢

4

1 回答 1

1

我终于让 3 个提供商和防火墙在它之间共享了上下文。为了防止 Core 用户访问 Platform,反之亦然,我添加了 access_control:

- { path: ^/file-manager, roles: [ROLE_PLATFORM, ROLE_CORE] }
- { path: ^/core, roles: ROLE_CORE }
- { path: ^/plateforme, roles: ROLE_PLATFORM }

所以它以 403 access denied 错误结束。这不是我想要的行为,所以我还在核心和平台防火墙上添加了“access_denied_url”选项,以在良好的登录页面上重定向用户。由于上下文是共享的,用户已经登录,所以在登录模板上我检查了用户对象的实例,建议他在尝试访问这部分之前先断开连接。

{% if instanceOf(app.user, 'App\\Entity\\PlatformUser') %}
    You're already logged in Platform space, please <a href="{{ path('platform_logout') }}">log out</a> before access Core space.
{% else %}
    You're already logged in as {{ app.user.username }}, <a href="{{ path('core_logout') }}">log out</a> or <a href="{{ path('core_index') }}">access core panel</a>.
{% endif %}

在除了访问文件管理器之外不应该共享任何内容的部分之间共享上下文有点令人困惑,但是没有用户可以访问其他部分,所以..这行得通。

于 2020-06-12T08:27:04.080 回答