0

我正在任何 Symfony2 项目中实现一个简单的认证区域。

没什么难的,即使我可以使用 FOSUserBundle,我也不使用,但这不是问题,我的问题实际上是针对安全方案和防火墙。

基本流程:

  • 定义需要具有足够角色的经过身份验证的用户配置文件的防火墙
  • 创建允许用户进行身份验证的登录表单页面
  • 管理错误,并在防火墙内重定向经过身份验证的用户

我可以很容易地用 SF2 做到这一点。

但是,我需要这个项目有点不同的东西:

防火墙不需要任何经过身份验证的配置文件。

它仅在找到经过身份验证的配置文件时才显示附加信息,但应该可以匿名访问。

所以我会把一个给定的页面作为登录表单页面和一个经典的防火墙页面

更多信息在这里:

  • 我有一个主页,显示公共信息
  • 登录表单是此主页的一部分,顺便说一下图形需求(下拉菜单)
  • 如果任何用户使用表单登录,我不想将其重定向到定义的防火墙页面,但允许经过身份验证的用户留在此主页上并显示其他信息

其实登录表单页面===防火墙主页===公共主页;

问题是在这个页面上,用户永远不会被认为是经过身份验证的,即使在使用表单登录后,但可以访问所有私人 ^/members 页面。

# Security.yml
    firewalls:
        home:
            pattern: ^/$
            anonymous: ~

        members_area:
            pattern: ^/
            provider: <any_working_entity-based_provider>
            form_login:
                login_path: /
                check_path: /login_check
                post_only: true
                default_target_path: /
                use_referer: false
            logout:
                path: /logout
                target: /
                invalidate_session: false

    access_control:
        - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Public page, login page AND firewall page
        - { path: ^/members, roles: ROLE_USER } # Other firewall pages

# My/Super/Bundle/Resources/views/home.html.twig
    # [...]
    {% if app.user %}
        // This part is never displayed, even when the user is successfully authenticated
        <h3>Welcome home {{ app.user.username }}</h3>
    {% else %}
        // This part is always shown...
        <form action='{{ path('MySuperBundle_members_login_check') }}' method='post'>
            <div>
                <label for='_username'>Username</label>
                <input type='text' id='_username' name='_username' value='{{ last_username }}' />
            </div>
            <div>
                <label for='_password'>Password</label>
                <input type='text' id='_password' name='_password' value='{{ last_username }}' />
            </div>
            [... CSRF ...]
            <div>
                <input type='submit' name='submit' value='Submit' />
            </div>
        </form>
    {% endif %}

所以最后:

  • 主页 (/) 可匿名访问:OK
  • 会员区 (^/members) 需要任何经过身份验证的个人资料:OK
  • 主页始终显示登录表单,即使用户已经登录(twig test {% if app.user %} 始终仅在主页上返回 false)
4

1 回答 1

0

我终于修好了,我只是混淆了防火墙和访问控制列表。

如问题所示,我在主页上创建了2个防火墙,而在symfony2中,您无法登录2个不同的防火墙-我不知道-

在这种情况下,如果您想在任何防火墙页面中拥有登录表单,您不需要使用防火墙来管理它,而是使用访问控制列表。

# Security.yml
firewalls:
    members_area:
        pattern: ^/
        provider: <any_working_entity-based_provider>
        anonymous: ~ # To allow unauthenticated users to access the firewall --> The login form
        form_login:
            login_path: /
            check_path: /login_check
            post_only: true
            default_target_path: /
            use_referer: false
        logout:
            path: /logout
            target: /
            invalidate_session: false

access_control:
    - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Public page, login page AND firewall page
    - { path: ^/members/suscribe, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Suscribe is a public activity
    - { path: ^/members/retrieve_password, roles: IS_AUTHENTICATED_ANONYMOUSLY } # As well as forgotten password
    - { path: ^/members/reset_password, roles: IS_AUTHENTICATED_ANONYMOUSLY } # Or reset password features with the token protected page...
    - { path: ^/members, roles: ROLE_USER } # BUT, you set up the access control to require any role of the authenticated users, for the different firewall pages
于 2013-08-24T21:05:19.923 回答