使用PHP从LDAP身份验证用户

36
我的项目是为我们的大学制作一个模块选课系统。因此,我联系了我的大学IT人员,以获取有关如何将学生身份验证到系统中的详细信息。我们正在使用现有的大学登录开发该系统。他们提供了一些LDAP信息,但我不知道如何使用它。我在一个Apacha服务器上使用PHP、MySQL。如何使用LDAP信息对用户进行身份验证,给定他的用户ID和密码。
以下是LDAP信息(我已更改域名等):
blueroom.ac.uk 域的LDAP信息
LDAP Host : ad.blueroom.ac.uk

LDAP port no: 389

BASE DN : ou=bluebird, dc=bluebird, dc=ac, dc=my

LDAP account to bind : cn = kikdap, ou=servacc, dc=bluebird,dc=ac,dc=uk

LDAP account password : ********

Attribute : sAMAccountName 

如果您的服务器是Linux系统,没有适当的服务器证书,您将无法与AD进行通信。如果您需要从大学获得帮助,这可能会成为一个问题。 - user423756
4个回答

52
一般的流程如下(相关的ext/ldap php命令在括号中):
  • 使用"LDAP主机"和"LDAP端口号"(ldap_connect())连接到LDAP服务器,并设置正确的连接选项(ldap_set_option()),特别是LDAP_OPT_PROTOCOL_VERSIONLDAP_OPT_REFERRALS

  • 使用"绑定LDAP帐户"和"LDAP帐户密码"(ldap_bind())绑定到LDAP服务器 - 如果您要对Active Directory服务器进行身份验证,可以直接使用登录页面上的用户名和密码,跳过以下所有步骤。

  • 通过指定"BASE DN"和适当的LDAP过滤器在树中搜索匹配的用户条目/对象 - 最有可能是类似于(&(objectClass=user)(sAMAccountName=%s))的内容,其中%s应该被要进行身份验证的用户名替换(ldap_search()

  • 检查返回的条目数是否为1(如果不等于1,则出现了问题,例如找不到用户或找到多个用户)

  • 检索此单个条目的区别名称(DN)(ldap_get_dn()

  • 使用上一步中找到的DN尝试使用身份验证页面上提供的密码绑定到LDAP服务器(ldap_bind()

  • 如果绑定成功,则一切正常;如果不成功,则密码很可能是错误的

  • 这其实并不像听起来的那么难。一般来说,我建议使用一些标准库来对LDAP服务器进行身份验证,比如Net_LDAP2 PEAR包或者Zend_Ldap来自Zend Framework。我对使用Net_LDAP2没有实际经验(虽然我对代码非常熟悉),但Zend_Ldap在与Active Directory服务器或ADAMS服务器(显然这是你正在使用的)的通信方面表现得非常好。
    以下是使用Zend_Ldap的解决方案:
    $options = array(
        'host'                 => 'ad.blueroom.ac.uk',
        'useStartTls'          => true,
        'accountDomainName'    => 'blueroom.ac.uk',
        'accountCanonicalForm' => 4,
        'baseDn'               => 'ou=bluebird,dc=bluebird,dc=ac,dc=my',
    );
    $ldap = new Zend_Ldap($options);
    try {
        $ldap->bind('user', 'password');
    } catch (Zend_Ldap_Exception $e) {
        // something failed - inspect $e
    }
    // bind successful
    $acctname = $ldap->getCanonicalAccountName('user', Zend_Ldap::ACCTNAME_FORM_DN);
    

    刚刚按照你的步骤操作了一下,现在这个功能完美运行了...我选择了原生的PHP LDAP模块。 - on_
    对于使用此方法的人,只是提醒一句:如果您的LDAP服务器允许匿名登录,请确保在尝试进行身份验证之前将空密码过滤为无效。 - Tyzoid
    我正在对Active Directory服务器进行身份验证,但仍需要完成所有7个步骤。 - Jibby

    4

    @Stephen提供了很好的建议。这是我的纯PHP代码,用于使用AD进行身份验证:

    1. first you need to know this parameters: server host, user domain (you need also base dn if you want query AD).
    2. use the following code:

      $ldap = ldap_connect($host); // e.g. 165.5.54.6 or an URL
      ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); // Recommended for AD
      ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
      $bind = ldap_bind($ldap, $username.'@'.$userDomain, $passwrod);
      
      if($bind){
      // successful authentication. 
      }
      

    1
    注意:某些LDAP实现在密码为空时,在ldap_bind上返回true。你应该检查密码不为空 - Johann150

    4

    2

    您可以使用http://pear.php.net/package/Net_LDAP2/docs来进行连接。这是一个很好用的工具。

    以下是文档中给出的连接示例:

    // Inclusion of the Net_LDAP2 package:
    require_once 'Net/LDAP.php';
    
    // The configuration array:
    $config = array (
        'binddn'    => 'cn=admin,ou=users,dc=example,dc=org',
        'bindpw'    => 'password',
        'basedn'    => 'dc=example,dc=org',
        'host'      => 'ldap.example.org'
    );
    
    // Connecting using the configuration:
    $ldap = Net_LDAP2::connect($config);
    
    // Testing for connection error
    if (PEAR::isError($ldap)) {
        die('Could not connect to LDAP-server: '.$ldap->getMessage());
    }
    

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