通过 Active Directory 使用 LDAP 在 PHP 中进行身份验证

Posted

技术标签:

【中文标题】通过 Active Directory 使用 LDAP 在 PHP 中进行身份验证【英文标题】:Authenticating in PHP using LDAP through Active Directory 【发布时间】:2010-09-15 08:25:55 【问题描述】:

我正在寻找一种通过 LDAP 和 php 对用户进行身份验证的方法(Active Directory 是提供者)。理想情况下,它应该能够在 IIS 7 上运行(adLDAP 在 Apache 上运行)。有没有人做过类似的事情,并且成功了?

编辑:我更喜欢一个库/类,其代码可以随时使用......当有人已经这样做时,发明***是愚蠢的。

【问题讨论】:

我认为drupal有一个模块 【参考方案1】:

PHP 有库:http://ca.php.net/ldap

PEAR 还有很多包:http://pear.php.net/search.php?q=ldap&in=packages&x=0&y=0

我也没有使用过,但我曾经打算使用它们,它们似乎应该可以工作。

【讨论】:

【参考方案2】:

我喜欢Zend_Ldap 类,你可以在你的项目中只使用这个类,而不需要 Zend 框架。

【讨论】:

我在执行上述操作时遇到了麻烦,发现那是为了管理不身份验证。我打算切换到zend.auth.adapter.ldap【参考方案3】:

我只需将用户凭据传递给 ldap_bind() 即可。

http://php.net/manual/en/function.ldap-bind.php

如果账号可以绑定LDAP,则有效;如果不能,那就不是。如果您所做的只是身份验证(而不是帐户管理),我认为不需要图书馆。

【讨论】:

【参考方案4】:

当您只需要两行代码时,导入整个库似乎效率低下...

$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) 
  // log them in!
 else 
  // error message

【讨论】:

如果提供的密码为空,部分安装的AD会绑定成功。当心这个!在尝试进行身份验证之前,您可能需要确保密码不为空。 @diolemo 有没有办法在不检查密码是否为空的情况下防止这种情况发生? @Neal 您可以使用ldap_set_option 使其以不同的方式运行。也许设置协议版本?您将不得不进行实验。为了安全起见,我个人建议您检查空密码。 @diolemo I made a new question related to this. 致匿名编辑:不,据我所知,这里不需要输入清理,因为 ldap_bind 会处理它,特殊字符不是问题。【参考方案5】:

对于那些寻找完整示例的人,请查看http://www.exchangecore.com/blog/how-use-ldap-active-directory-authentication-php/。

我已经测试了从 Windows Server 2003 Web Server (IIS6) 和运行 IIS 8 的 Windows Server 2012 Enterprise 到 Windows Server 2003 和 Windows Server 2008 R2 域控制器的连接。

【讨论】:

【参考方案6】:

您会认为在 Active Directory 中简单地对用户进行身份验证将是一个非常简单的过程,在 PHP 中使用 LDAP 而不需要库。但是有很多事情会很快使其复杂化:

您必须验证输入。否则,空的用户名/密码将通过。 您应确保在绑定时正确编码用户名/密码。 您应该使用 TLS 加密连接。 使用单独的 LDAP 服务器实现冗余,以防其中一台服务器出现故障。 如果身份验证失败,则会收到一条信息性错误消息。

在大多数情况下,使用支持上述内容的 LDAP 库实际上更容易。我最终推出了自己的库来处理上述所有问题:LdapTools(嗯,不仅用于身份验证,它还可以做更多事情)。它可以像下面这样使用:

use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;

$domain = (new DomainConfiguration('example.com'))
    ->setUsername('username') # A separate AD service account used by your app
    ->setPassword('password')
    ->setServers(['dc1', 'dc2', 'dc3'])
    ->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);

if (!$ldap->authenticate($username, $password, $message)) 
    echo "Error: $message";
 else 
    // Do something...

上面的验证调用将:

验证用户名或密码都不为空。 确保用户名/密码正确编码(默认为 UTF-8) 尝试备用 LDAP 服务器以防万一出现故障。 使用 TLS 加密身份验证请求。 如果失败(即锁定/禁用帐户等),请提供其他信息

还有其他库也可以做到这一点(例如 Adldap2)。但是,我觉得有必要提供一些额外的信息,因为投票最多的答案实际上是一个安全风险,在没有完成输入验证并且不使用 TLS 的情况下依赖。

【讨论】:

对于 LDAP 连接,TLS 已被弃用,取而代之的是 StartTLS:openldap.org/faq/data/cache/605.html @zenlord 不推荐使用ldaps:// 格式的连接。在我的示例中,当您指定setUseTls(true) 时,它使用ldap:// 格式,然后使用ldap_start_tls($connection) 发出StartTLS。所以 TLS 本身并没有被弃用,只是使用ldaps:// 连接(实际上是通过一个完全不同的端口连接到 LDAP)。

以上是关于通过 Active Directory 使用 LDAP 在 PHP 中进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

通过 Active Directory 使用 LDAP 在 PHP 中进行身份验证

使用 SQL Server 2005 通过 LDAP 访问 Active Directory 角色成员资格

通过 Active Directory LDAP 使用 Spring-Security 进行身份验证

如何使用 OAuth 2.0 通过 Azure Active Directory 对用户进行身份验证?

如何使用 Active Directory 集成身份验证通过 python SQL alchemy 连接到 Azure sql 数据库

通过 C# 删除 Active Directory 中的用户