Symfony:多个防火墙上下文 - 用户被转发到错误的上下文

时间:2014-09-28 14:15:07

标签: php security symfony authentication

我有一个前端登录(可选),另一个登录管理面板,这是强制性的。

当用户转到fe_login时,他们可以登录frontend上下文。这没关系!

当他们转到admin_login时,他们应该能够登录admin上下文。这好的

问题在于,当我转到/admin时,当我被重定向到fe_login 时,我会被重定向到admin_login

这是我的security.yml

security:
    encoders:
        App\FrontendBundle\Controller\UserController:
            algorithm: bcrypt
        App\AdminBundle\Controller\UserController:
            algorithm: bcrypt
        App\Entity\User:
            algorithm: bcrypt
    providers:
        administrators:
            entity: { class: AppEntity:User, property: username }

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        admin:
            pattern: ^/admin
            form_login:
                login_path: admin_login
                check_path: admin_auth
                csrf_provider: form.csrf_provider
            logout:
                path: admin_logout
                target: admin_login
        frontend:
            anonymous: ~
            form_login:
                login_path: fe_login
                check_path: fe_auth
                csrf_provider: form.csrf_provider
                always_use_default_target_path: true
                default_target_path: fe_landing
            logout:
                path: fe_logout
                target: fe_landing
        login:
            pattern: ^/admin/login
            anonymous: ~

        default:
            anonymous: ~
    access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin, roles: [ROLE_ADMIN,ROLE_MANAGER,ROLE_DRIVER,ROLE_PARTNER] }

知道我做错了吗?

3 个答案:

答案 0 :(得分:3)

这是我的security.yml,但正如我所说的那样,对于Symfony2.0,你可能会找到一个提示。

security:
    encoders:

### ...

role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

providers:
    fos_userbundle:
        id: fos_user.user_manager
    admin_adminbundle:
        id: custom_admin_manager_id

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

    admin:
        pattern: ^/admin/

        form_login:
            check_path:         /admin/check-login
            login_path:         /admin/login
            provider:           admin_adminbundle
            csrf_provider:      form.csrf_provider
            post_only:          true
            success_handler:    login_success_handler
            failure_handler:    admin_login_failure_handler
            username_parameter: login_username
            password_parameter: login_password
            remember_me:        false
        logout:
            path:               /admin/logout
            target:             /admin/login
        anonymous: true

    frontend:
        pattern: ^/

        form_login:
            check_path:         /frontend/check-login
            login_path:         /frontend/login
            provider:           fos_userbundle
            csrf_provider:      form.csrf_provider
            post_only:          true
            success_handler:    login_success_handler
            failure_handler:    login_failure_handler
            username_parameter: login_username
            password_parameter: login_password
        logout:
            path:               /frontend/logout
            success_handler:    logout_success_handler
        anonymous: true

access_control:
    - { path: ^/frontend/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }

答案 1 :(得分:2)

我不太确定原因,但您现在必须security.yml必须是一个非常清晰的文件,以避免错过配置(这会导致安全问题)

所以,关于你的档案:

  • 它错过了前端部分的模式键:我会添加pattern: ^/
  • 可以像对后端一样
  • 指定前端登录路径
  • 你的规则的顺序让我认为某些事情是不正确的

这是你应该测试的版本:

security:
    encoders:
        App\FrontendBundle\Controller\UserController:
            algorithm: bcrypt
        App\AdminBundle\Controller\UserController:
            algorithm: bcrypt
        App\Entity\User:
            algorithm: bcrypt

    providers:
        administrators:
            entity: { class: AppEntity:User, property: username }

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        login_admin:
            pattern: ^/admin/login
            anonymous: ~
        admin:
            pattern: ^/admin
            form_login:
                login_path: admin_login
                check_path: admin_auth
                csrf_provider: form.csrf_provider
            logout:
                path: admin_logout
                target: admin_login
        login_frontend:
            pattern: ^/login # you should adapt this to your app
            anonymous: ~
        frontend:
            pattern: ^/
            anonymous: ~
            form_login:
                login_path: fe_login
                check_path: fe_auth
                csrf_provider: form.csrf_provider
                always_use_default_target_path: true
                default_target_path: fe_landing
            logout:
                path: fe_logout
                target: fe_landing

    access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin, roles: [ROLE_ADMIN,ROLE_MANAGER,ROLE_DRIVER,ROLE_PARTNER] }

答案 2 :(得分:1)

你有一些似乎没必要的防火墙。让我们简化您的防火墙配置:

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    admin:
        pattern: ^/admin
        form_login:
            login_path: admin_login
            check_path: admin_auth
            csrf_provider: form.csrf_provider
        logout:
            path: admin_logout
            target: admin_login
        anonymous: ~
    frontend:
        pattern: ^/
        anonymous: ~
        form_login:
            login_path: fe_login
            check_path: fe_auth
            csrf_provider: form.csrf_provider
            always_use_default_target_path: true
            default_target_path: fe_landing
        logout:
            path: fe_logout
            target: fe_landing

access_control:
    # allow unauthenticated to access admin login
    - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    # restrict admin access
    - { path: ^/admin, roles: [ROLE_ADMIN,ROLE_MANAGER,ROLE_DRIVER,ROLE_PARTNER] }
    # allow unauthenticated to access front end login
    - { path: ^/fe/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    # restrict front end access
    - { path: ^/fe, roles: ROLE_USER } # or whatever the role is of your frontend user
    # allow all other pages to be viewed by unauthenticated users
    - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }

此配置使/fe下的所有页面都需要前端授权,/admin下的所有页面都需要管理员授权。并且所有其他页面都不受保护。你可以根据需要调整它。

access_control的顺序很重要。一旦匹配规则,它就不会尝试匹配任何其他条目。此配置应该有效,以便显示正确的登录信息。但是,您似乎没有为每个防火墙使用不同的用户提供程序。因此,当您登录时,应用程序将使用相同的提供程序进行两次登录。这可能是也可能不是你想要的,但我想我会指出它。如果您确实需要为每次登录设置不同的用户提供程序,只需将provider: ProviderName添加到每个防火墙。