当用户未经过身份验证时,在拒绝访问时会将其重定向到登录页面,这很好。
但是当它经过身份验证时,它应该保留在“拒绝访问”页面并显示错误消息,但它会重定向到登录页面,然后该页面会抛出“拒绝访问”异常(因为只有未经过身份验证的用户才能访问登录页面)这会创建一个无限重定向循环。
providers:
app_user:
entity:
class: AppUserBundle:User
property: username
firewalls:
main:
pattern: ^/
form_login:
#check_path: route_id
login_path: app_user_login
provider: app_user
#logout:
# path: route_id
# target: route_id
anonymous: ~
我评论过# check_path:
,因为我使用自定义注册/登录页面,我的登录表单已提交给login_path:
。这很有效,直到我将我的提供者移到entity
。在此之前,我有一个从Cassandra数据库加载用户的自定义提供程序。
我发现了问题:我的网站正在使用remember_me身份验证,但在Symfony中,有this line在AccessDenied异常上执行。当我将->isFullFledged($token)
更改为->isRememberMe($token)
时,一切正常。你认为这是a Symfony bug吗?
答案 0 :(得分:0)
当用户返回您的站点时,他们会根据记住我cookie中存储的信息自动进行身份验证。这允许用户访问受保护的资源,就好像用户在访问网站时已经实际验证一样。 (source)
因此,在完全验证用户之前,用户不受信任。这就是在发生AccessDenied异常时将其重定向到登录页面的原因。
在登录控制器操作上,我设置了注释
@Security("not is_authenticated()")
这样我尝试只允许匿名用户访问该页面,完全通过身份验证的用户运行良好,但当我将我的网站切换为仅使用remember_me时,会发生以下情况
if @Security(...) is False {
if IS_AUTHENTICATED_FULLY {
displayAccessDeniedPage()
} else {
redirectToLoginPage()
}
}
解决方案是:
@Security(..)
(允许所有人访问)在控制器操作中,以编程方式检查
if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
throw $this->createAccessDeniedException('You are already logged in');
}
当用户以编程方式登录时,请同时设置full和remember_me标记(不仅仅是remember_me)
同样的问题是登记行动
@Security("not is_authenticated()")
以编程方式检查
if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
throw $this->createNotFoundException('Only anonymous users can access this page');
}
注意createNotFoundException()
,我不能使用createAccessDeniedException()
因为remember_me用户在尝试访问注册页面时会被重定向到登录页面(很奇怪)。