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

112

我正在寻找一种使用PHP通过LDAP对用户进行身份验证的方法(使用Active Directory作为提供者)。理想情况下,它应该能够在IIS 7上运行(adLDAP在Apache上可以做到这一点)。有人做过类似的事情并且获得成功了吗?

  • 编辑:我希望使用一个包含可直接使用的代码的库/类...如果有人已经发明了轮子,再重复造轮子就显得愚蠢了。

我认为Drupal有一个相应的模块。 - redben
6个回答

176

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

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

48
如果提供的密码为空,某些AD安装可能会成功绑定。注意这一点!在尝试认证之前,您可能需要确保密码非空。 - diolemo
@diolemo 有没有不检查密码是否为空就能防止这种情况的方法? - Naftali
1
@Neal 你可以尝试使用ldap_set_option来改变它的行为方式。也许设置协议版本?你需要进行实验。我个人建议你无论如何都要检查空密码,以确保安全。 - diolemo
我假设服务器上必须启用 php_ldap.dll 扩展。 - shasi kanth
@windowsuser:我不得不将一些dll文件复制到系统目录才能使其正常工作。尝试这个链接:http://wptidbits.com/webs/enable-php-ldap-module-in-xampp/ - Lucian Depold
显示剩余4条评论

19

你可能认为只是在 PHP 中使用 LDAP 对 Active Directory 进行用户身份验证应该是一个相当简单的过程,不需要库。但实际上有很多东西可以让它变得非常复杂:

  • 必须验证输入。否则,空用户名/密码将通过。
  • 绑定时应确保用户名/密码被正确编码。
  • 应使用 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,所以我觉得有必要提供一些额外的信息。


1
对于LDAP连接,TLS已被弃用,取而代之的是StartTLS:http://www.openldap.org/faq/data/cache/605.html。 - zenlord
2
@zenlord 使用 ldaps:// 格式进行连接已经被弃用。在我的示例中,当您指定 setUseTls(true) 时,它使用 ldap:// 格式,然后使用 ldap_start_tls($connection) 发出 StartTLS。因此,TLS 本身并没有被弃用,只是使用 ldaps:// 进行连接(实际上连接到完全不同的端口的 LDAP)已经被弃用。 - ChadSikorra

13

我只需将用户凭证传递给ldap_bind()即可完成此操作。

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

如果账户可以绑定LDAP,那么它是有效的;如果不能,则无效。如果你只需要进行身份验证(而非账户管理),我认为不需要使用库。


9

我喜欢Zend_Ldap类,你可以在不使用Zend Framework的情况下只使用这个类来完成你的项目。


1
我费了很大的力气去实现上述内容,结果发现那是用于管理而不是认证。我打算转而使用zend.auth.adapter.ldap - vdidxho

6

5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接