【问题标题】:Symfony2 : Authentication with Active directorySymfony2:使用 Active Directory 进行身份验证
【发布时间】:2013-06-06 16:32:19
【问题描述】:

我正在尝试创建一个用户提供程序,以便我可以通过 Active Directory 服务器进行身份验证。

问题在于,与大多数其他 LDAP 服务器不同,Active Directory 不允许检索某些用户的密码属性,即使是加密的。

这是我的用户类:

class LdapUser implements UserInterface
{
    private $username;
    private $first_name;
    private $last_name;
    private $password;
    private $salt;
    private $roles;

    public function __construct($username, $first_name, $last_name, $password, $salt, array $roles) {
        $this->username = $username;
        $this->first_name = $first_name;
        $this->last_name = $last_name;
        $this->password = $password;
        $this->salt = $salt;
        $this->roles = $roles;
    }

    ...

}

这是我的loadUserByUsername 方法(在我的UserProvider 类中):

public function loadUserByUsername($username)
{

    $server = "my_ldap_server";
    $root_dn = "my_root_dn";
    $root_pw = "my_root_pw";

    $ds = ldap_connect($server);
    if ($ds) {

        ldap_bind($ds, $root_dn, $root_pw);
        $search = ldap_search($ds, "my_branch", "(sAMAccountName=".$username.")", array("sn", "givenName"));
        $info = ldap_get_entries($ds, $sr);

        if($info['count'] > 0) {
            $user = $info[0];
            return new LdapUser($username, $user['givenName'][0], $user['sn'][0], '???PASSWORD???', '???SALT???', array('ROLE_USER'));
        } else {
            throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
        }

        ldap_close($ds);
    } else {
        echo "Connexion au serveur LDAP impossible";
    }
}

如您所见,我无法将密码传递给我的 LdapUser 类,因为它无法通过 Active Directory 访问。

但是,我认为仍然可以验证用户身份,方法是使用用户在登录表单中输入的密码执行ldap_bind($username, $password)。问题是我不知道如何在我的 LdapUserProvider 类中访问此密码。

我尝试了$_POST['password'],但出现未定义索引错误...

欢迎任何帮助:)

【问题讨论】:

    标签: authentication active-directory symfony ldap


    【解决方案1】:

    有一些 LDAP 身份验证包可供使用。

    如下所述,您可以尝试FR3D/LdapBundle,但它需要 FOSUserBundle 才能工作。如果您不想(或不需要)使用 FOSUserBundle,也可以尝试IMAG (BorisMorel/LdapBundle)。 BorisMorel 使用 php-ldap 工作,它不需要额外的 bundle 也不需要任何 zend 组件。

    即使您不想使用它们,我也建议您查看 BorisMorel 的实现以获取更多信息。代码非常简单易懂。

    【讨论】:

      【解决方案2】:

      您的代码通过传输绑定请求来设置连接的身份验证状态。此代码是否尝试搜索条目,从该条目中检索密码,然后绑定为该专有名称?如果是这样,即使您可以检索密码,正确配置的目录服务器也不允许传输预编码的密码。密码应始终通过安全连接(TLS 或 SSL)以明文形式传输,以便服务器可以执行密码质量和历史验证。因此,您的代码必须事先知道明文密码。或者,符合 LDAP 的服务器可能允许对某些条目使用代理身份验证。

      另见

      【讨论】:

        【解决方案3】:

        试试FR3dLdapBundle

        如果您从Zend Framework 2 安装Zend\Ldap 组件,2.0.x 分支支持 Active Directory

        【讨论】: