对Symfony登录进行额外的安全检查

时间:2015-12-12 00:30:00

标签: php validation symfony authentication login

我正在使用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和其余登录程序之前,我可以对数据库中的所提供电子邮件地址进行额外检查?基本上我只是在提交登录后尝试进行额外的检查,以确保选择正确的帐户而不是数据库中的第一个匹配。

2 个答案:

答案 0 :(得分:0)

您需要实现自定义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 article了解更多信息。

答案 1 :(得分:0)

UserProvider应该通过用户名返回用户,没有别的,它不应该做一些重的逻辑。我认为你可以尝试通过实现SimpleFormAuthenticatorInterface接口来解释here来创建自己的身份验证器。