【发布时间】:2014-04-30 14:04:43
【问题描述】:
这是我的问题。
情况:
我正在尝试在用户登录期间添加一些自定义逻辑。我可以找到这样做的方法: 艰难的方式(但有很多控制);按照this guidelines of the cookbook 或this complementing publication of vandenbrand 构建我自己的身份验证提供程序
简单的方法(正是我需要的):使用 simple_form。 simple_form 是一个与 form_login 具有相同选项的密钥,但我可以为其定义一个“身份验证器”。 cookbook tuto I used can be found here
问题
我有一个现有且可操作的 app/security.yml 配置,带有“form_login”键。
secured_area:
pattern: ^/foo/user/secured/
form_login:
check_path: /foo/user/secured/login_check
login_path: /foo/user/login
我按照上述教程的步骤进行操作。因此,我的 security.yml 被修改为:
secured_area:
pattern: ^/foo/user/secured/
#form_login:
simple_form:
authenticator: foo_authenticator
check_path: /foo/user/secured/login_check
login_path: /foo/user/login
当我尝试访问安全区域的页面 /foo/user/secured/target 时,防火墙会完成它的工作:它捕获查询并要求提供凭据(通过中间页面 /foo/user/login)。
但是,一旦输入了正确的凭据(并且显然经过验证),我就会一直停留在同一页面上。它不会重定向到我最初要求的页面 /foo/user/secured/target 。尝试通过新请求访问该页面并没有令人耳目一新:我仍然停留在登录阶段。
编辑 1:以下是我根据日志和调试确定的步骤:
1) 用户尝试访问 /foo/user/secured/target,为此您需要至少使用 ROLE_USER 进行识别才能访问
2) 防火墙拦截此请求,因为它匹配侦听的路由 (app/config/security.yml):
secured_area:
pattern: ^/foo/user/secured/
3) 重定向到登录路径
4) 用户填写用户名和密码,提交帖子
5) 当收到表单时,通过自定义身份验证器的 createToken 方法创建一个令牌。它返回使用参数用户名创建的类 UsernamePasswordToken 对象,明文密码,身份验证器密钥:UsernamePasswordToken($username, $password, $providerKey)
6) 令牌被传递到身份验证器对象的 authenticateToken 方法 de 上。此方法将通过 $token->getCredentials()) 访问的令牌中包含的明文密码哈希与数据库中的哈希密码进行比较。
7) 验证成功:我们被重定向到 /foo/user/secured/target 。令牌和用户在会话中被序列化(问题从这里开始:确实,用户清除密码已被删除,因此它不会在会话中留下痕迹,getCredentials() 现在将返回空字符串)。)。 p>
8) 在加载页面时,文件防火墙被激活。它检测到用户登录,似乎想检查它的令牌。因此,它调用authenticateToken。
9) authenticateToken 尝试将 sha1($token->getCredentials()) 与数据库中的散列密码进行比较。 comme $token->getCredentials() 为空,比较失败。 authenticateToken 引发异常。
10) 引发的异常触发防火墙重定向到登录页面。我们就是:卡在无限循环登陆系统登陆页面。
停止编辑 1。
解决方案
有谁知道为什么 'form_login' 和 'simple_form' 之间的行为会发生这种变化?最重要的是,您知道解决此问题的好方法吗?我想身份验证方法或自定义身份验证器应该稍微改变一下,但我对安全性还没有足够的信心优雅地解决这个问题。
非常感谢。
亲切的问候,
智者
【问题讨论】:
标签: security symfony authentication firewall