我正在任何Symfony2项目中实现一个简单的身份验证区域。
没有什么难的,即使我可以使用FOSUserBundle,我也不使用,但这不是问题所在,我的问题实际上是针对安全方案和防火墙。
基本流程:
- 定义一个防火墙,该防火墙需要具有足够角色的经过身份验证的用户配置文件
- 创建允许用户进行身份验证的登录表单页面
- 管理错误,并重定向防火墙内经过身份验证的用户
我可以用SF2很容易地做到这一点。
但是,我需要一些不同于这个项目的东西:
防火墙不需要任何经过身份验证的配置文件。
只有找到经过身份验证的配置文件时,它才会显示附加信息,但应该可以匿名访问。
所以我会把一个给定的页面作为登录表单页面和一个经典的防火墙页面
更多信息请点击此处:
- 我有一个主页,显示公共信息
- 登录表单是这个主页的一部分,顺便说一句,用于图形需求(下拉列表)
- 如果任何用户使用该表单登录,我不想将其重定向到定义的防火墙页面,而是允许经过身份验证的用户留在该主页上并显示其他信息
实际上,登录表单页面===防火墙主页===公共主页;
问题是,在该页面上,用户从未被视为已通过身份验证,即使在使用表单登录后也是如此,但用户可以访问所有私有^/成员页面。
# 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 %}
最后:
- 主页(/)可以匿名使用:确定
- 成员区域(^/members)需要任何经过身份验证的配置文件:确定
- 主页始终显示登录表单,即使用户已经登录(trick测试{%if app.user%}仅在主页上总是返回false)
我终于修复了它,我只是混淆了防火墙和访问控制列表。
如问题所示,我在主页上创建了两个防火墙,在symfony2中,你不能登录两个不同的防火墙-我不知道-
在这种情况下,如果您希望在任何防火墙页面中都有登录表单,则不使用防火墙进行管理,而是使用访问控制列表进行管理。
# 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