Symfony 安全:即使用户不匹配角色也不需要身份验证

Symfony Security: Auth is not needed even if user doesn't match role

我遇到了一个奇怪的问题。我有以下 security.yml:

security:
    encoders:
        Symfony\Component\Security\Core\User\User: plaintext

    role_hierarchy:
        ROLE_USER:
        ROLE_EDITOR:      [ROLE_USER]
        ROLE_ADMIN:       [ROLE_USER, ROLE_EDITOR]

    providers:
        in_memory:
            memory:
                users:
                    admin: { password: 123456, roles: [ 'ROLE_ADMIN' ] }
                    editor: { password: 123456, roles: [ 'ROLE_EDITOR' ] }

    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        backend:
            pattern: ^/backend
            anonymous: ~
            provider: in_memory
            form_login:
                login_path: backend_login
                check_path: backend_login_check

    access_control:
        - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY, host: example\.com$ }
        - { path: ^/backend_login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/backend, roles: ROLE_ADMIN }
        - { path: ^/user/fetch, roles: ROLE_USER }
        - { path: ^/level, roles: ROLE_USER }
        - { path: ^/gallery, roles: ROLE_USER }

我有一台 window 开发机器,带有 XAMPP 运行,一切正常。我可以登录到后端,如果我没有登录并尝试打开后端路由,我将被重定向到登录页面。

这是我的路由部分:

backend_login:
    pattern:    /backend_login
    defaults:   { _controller: FooBackendBundle:Security:login }

backend_login_check:
    pattern:   /backend/login_check

但是当我将它上传到我的集成 linux 服务器时,我可以打开后端而无需登录。似乎 Symfony 并不关心当前用户拥有的角色。

代码和 symfony 版本完全相同 (Symfony 2.3)。

如果我从后端防火墙中删除 anonymous: ~ 部分,它将重定向到登录页面,但也会创建无限重定向循环。

有人知道如何解决这个问题吗?

来自Symfony documentation

For each incoming request, Symfony checks each access_control entry to find one that matches the current request. As soon as it finds a matching access_control entry, it stops - only the first matching access_control is used to enforce access.

当您在安全配置中设置 access_control 时,您希望将 least-restrictive 匹配项放在最后。在您的情况下,您将始终匹配第一个模式,因为所有路由都在 ^/ 上匹配,因此不需要任何身份验证。将您的 access_control 更改为:

access_control:
    - { path: ^/backend_login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/backend, roles: ROLE_ADMIN }
    - { path: ^/user/fetch, roles: ROLE_USER }
    - { path: ^/level, roles: ROLE_USER }
    - { path: ^/gallery, roles: ROLE_USER }
    - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }

我删除了 host 参数,因为它似乎不相关。