Symfony 3中带有Guard身份验证系统的LDAP

时间:2017-11-07 10:38:15

标签: mysql security authentication ldap symfony-3.3

我假装要做的是在ddbb配置的Guard身份验证系统中包含内部用户的LDAP。 我已经构建了我的Guard身份验证系统,并且由于https://knpuniversity.com/screencast/symfony-security而非常好。

但我还需要尝试先通过LDAP模式登录。更确切地说,功能必须如下:

用户尝试登录使用MySQL配置数据库的Guard System Authentication,并执行以下操作:

1-检查用户是否存在于MySQL用户表中。如果存在,我们转到步骤2.如果不存在,则返回false以使用错误消息进行身份验证。

2 - 检查用户是否存在于LDAP模式。如果存在,请转到步骤3.如果不存在,请转到步骤4.

3 - 尝试使用用户名和密码通过LDAP登录。如果验证正常,则登录。如果无法通过LDAP匹配密码,则返回false以进行验证并显示错误消息。

4 - 检查LDAP选项后,我们将尝试通过Guard Authentication System登录。如果验证没问题,则用户已登录。如果无法通过Guard与MySQL用户表匹配密码,则返回false以进行身份​​验证并显示错误消息。

1 个答案:

答案 0 :(得分:0)

在LoginFormAuthenticator文件中,我终于可以管理我想要的这种行为,如下所示。

<?php

namespace AppBundle\Security;

use ...
use Zend\Ldap\Ldap;
use Zend\Ldap\Exception\LdapException;

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;

    private $em;
    private $router;
    private $passwordEncoder;
    private $csrfTokenManager;

    public function __construct(...
    }

    public function getCredentials(Request $request)
    {
    ...
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $username = $credentials['username'];
        $ldapPassword = $credentials['password'];
        $ldaphost = 'ldap.example.com';    // your ldap servers
        $baseDn = 'dc=example,dc=es';

        $options = [
            'host'              => $ldaphost,
            'username'          => $username,
            'password'          => $ldapPassword,
            'bindRequiresDn'    => false,
            'accountDomainName' => 'example.es',
            'baseDn'            => $baseDn,
        ];


        $userInterface = $this->em->getRepository('AppBundle:User')
            ->findOneBy(['email' => $username]);
        $ldap = new Ldap($options);

        try {
            $ldap->bind();
            $userInterface->setIsAuthenticationLDAP(true);
        } catch (LdapException $zle){
            $userInterface->setIsAuthenticationLDAP(false);
        }

        return $userInterface;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        $password = $credentials['password'];

        if($user->isAuthenticationLDAP()){
            $user->setLoginAttempts(0);
            $this->em->persist($user);
            $this->em->flush();
            return true;
        } else {
           if($this->passwordEncoder->isPasswordValid($user, $password)) {
               $user->setLoginAttempts(0);
               $this->em->persist($user);
               $this->em->flush();
               return true;
           } else {
               if($user->getLoginAttempts() == '0') $user->setFirstLoginAttempt(new \DateTime('now'));
               $user->setLoginAttempts($user->getLoginAttempts() + 1);
               if($user->getLoginAttempts() >= 5) {
                   $user->setLockedDateTime(new \DateTime('now'));
                   $user->setLoginAttempts(0);
               }
               $this->em->persist($user);
               $this->em->flush();
           }
       }

       return false;
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
       ....
    }

    protected function getLoginUrl()
    {
        return $this->router->generate('fos_user_security_login');
    }
}

我希望任何人都能享受这个答案。