我正在使用symfony 2.5,遇到了一个障碍。
我根据symfony文档使用SecurityContext
来验证用户。具体来说,我目前有:
$securityContext = $this->container->get('security.context');
# If authenticated through Symfony
if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY'))
{
return $this->redirect($this->generateUrl('accounts_dashboard'), 301);
}
.....
这很好用,但这个应用程序从多个位置注册用户,当时我们没有控制重复注册。这意味着同一个电子邮件地址有多个条目。
正因为如此,当有人试图登录,而同一电子邮件地址下有多个帐户时,登录过程会失败,因为它选择了错误的帐户。
我在数据库中还有其他字段可以用来匹配正确的帐户,比如活动状态、上次登录IP甚至上次登录日期。我遇到的问题是,我不确定如何在登录期间创建额外的检查来正确验证该信息。
在不必重新处理整个登录物流的情况下,正确的方法是什么?这样我就可以在调用SecurityContext
和登录过程的其余部分之前,对数据库中提供的电子邮件地址进行额外检查?本质上,我只是在提交的登录后尝试进行额外的检查,以确保选择了正确的帐户,而不是数据库中的第一个匹配帐户。
UserProvider应该按用户名返回user,不需要其他任何操作,它不应该做一些繁重的逻辑。我认为您可以尝试通过实现SimpleFormAuthenticatorInterface
接口来创建自己的验证器,如本文所述。
您需要实现一个自定义的UserProvider。示例:
<?php
namespace Acme'Security'Authorization;
use Symfony'Bridge'Doctrine'Security'User'EntityUserProvider;
use Symfony'Component'Security'Core'Exception'UsernameNotFoundException;
class MyCustomEmailUserProvider extends EntityUserProvider
{
/**
* {@inheritdoc}
*/
public function loadUserByUsername($username)
{
//your code to get user by email goes here
// if you found User, you need to return it from this method, otherwise throw an exception
throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
}
}
您不必扩展EntityUserProvider
,您可以考虑自己的UserProviderInterface
实现。
将其注册为服务(假定为security.my_custom_email_user_provider
服务名称),添加所需的依赖项,然后将其添加到security.yml
:
providers:
main:
id: security.my_custom_email_user_provider
然后在您的登录表单上使用此提供商:
firewalls:
firewall_name:
form_login:
provider: main
查看Cookbook文章了解更多信息。