PHP 访问 LDAP

LDAP 的全称是“轻量级目录访问协议(Lightweight Directory Access Protocol)”,是一种简单的目录协议。所谓目录,是一种专门的数据库,可以用来服务于任何应用程序。在企业应用中使用 LDAP可以让企业范围内的所有应用程序LDAP 目录中获取信息,应用程序可以从网络上直接从 LDAP 目录获取信息,而不局限于操作系统与服务器的类型。这里主要介绍如何使用 PHP 来访问 LDAP。

连接 LDAP 服务器

PHP 中用于连接 LDAP 服务器的函数是 ldap_connect,其语法格式如下所示。

1 ldap_connect([string hostname [, int port]])

其中,hostname 是 LDAP 服务器所在的主机地址,port 是 LDAP 服务器的端口号。以下代码实现了对位于 192.168.3.1 地址的 LDAP 服务器的连接。

1 <?php
2 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
3 $ldap_port = "389";//LDAP 服务器端口号
4 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//建立与 LDAP 服务器的连接
5 ?>

与前面介绍过的方法类似,上面的代码使用了“or die”来美化错误信息。

绑定 LDAP 服务器

绑定 LDAP 服务器的含义是使用特定的用户名或密码来登陆 LDAP 服务器。PHP 中用于绑定 LDAP服务器的函数是 ldap_bind,其语法格式如下所示。

1 ldap_bind(ldap_conn [, string username [, string password]])

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,username 是登陆 LDAP 服务器时使用的用户名,password 是登陆时所用的密码。以下代码实现了对位于 192.168.3.1 地址的 LDAP 服务器的绑定。

1 <?php
2 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
3 $ldap_port = "389";//LDAP 服务器端口号
4 $ldap_user = ""; //设定服务器用户名
5 $ldap_pwd = ""; //设定服务器密码
6 $ldap_conn = ldap_connect($ldap_host, $ldap_port) //建立与 LDAP 服务器的连接
7 or die("Can't connect to LDAP server");
8 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//与服务器绑定
9 ?>

断开 LDAP 服务器

与 LDAP 服务器断开的过程与绑定 LDAP 服务器相反,PHP 中用于绑定 LDAP 服务器的函数是ldap_unbind,其语法格式如下所示。

1 ldap_unbind(ldap_conn)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象。以下代码在绑定了对位于 192.168.3.1地址的 LDAP 服务器后与其断开连接。

01 <?php
02 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
03 $ldap_port = "389";//LDAP 服务器端口号
04 $ldap_user = "";//设定服务器用户名
05 $ldap_pwd = "";//设定服务器密码
06 $ldap_conn = ldap_connect($ldap_host, $ldap_port) //建立与 LDAP 服务器的连接
07 or die("Can't connect to LDAP server");
08 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) //与服务器绑定
09 or die("Can't bind to LDAP server.");
10 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");  //与服务器断开连接
11 ?>

查询 LDAP 目录内容

查询 LDAP 目录使用 ldap_search 函数来实现,其语法格式如下所示。

1 ldap_search(ldap_conn, base_dn, conditions)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象。base_dn 是 LDAP 服务器的查询主键。conditions 是用于 LDAP 目录查询所用的条件。该函数返回一个结果对象,该结果对象保存查询到的所有记录。对于这个结果对象,可以使用 ldap_get_entries 函数进行简单的读取,其语法格式如下所示。

1 ldap_get_entries(ldap_conn, result)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,result 是前面查询 LDAP 目录时返回的对象。该函数返回一个数组,包含所有的结果记录。以下代码实现了对服务器上的内容进行查询。

01 <?php
02 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
03 $ldap_port = "389";//LDAP 服务器端口号
04 $ldap_user = "";//设定服务器用户名
05 $ldap_pwd = "";//设定服务器密码
06 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//建立与 LDAP 服务器的连接
07 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//与服务器绑定
08 $base_dn = "ou=company,o=depart";//定义要进行查询的目录主键
09 $filter_col = "mail";//定义用于查询的列
10 $filter_val = "phptester@163.com";//定义用于匹配的值
11 $result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//执行查询
12 $entry= ldap_get_entries($ldap_conn, $result);//获得查询结果
13 print_r($entry);//输出查询结果
14 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //与服务器断开连接
15 ?>

运行结果如下所示。

01 Array
02 (
03 [count] => 1
04 [0] => Array
05 (
06 [objectclass] => Array
07 (
08 [count] => 5
09 [0] => person
10 [1] => organizationalPerson
11 [2] => companyPerson
12 [3] => departPerson
13 [4] => top
14 )
15 [0] => objectclass
16 [ou] => Array
17 (
18 [count] => 1
19 [0] => company
20 )
21 [1] => ou
22 [o] => Array
23 (
24 [count] => 1
25 [0] => depart
26 )
27 [2] => o
28 [employeeserialnumber] => Array
29 (
30 [count] => 1
31 [0] => 100001
32 )
33 [3] => employeeserialnumber
34  
35 [givenname] => Array
36 (
37 [count] => 2
38 [0] => Peng Cheng
39 [1] => Peng
40 )
41 [4] => givenname
42 [mail] => Array
43 (
44 [count] => 1
45 [0] => phptester@163.com
46 )
47 [5] => mail
48 [count] => 6
49 [dn] => uid=672100001,c=cn,ou=company,o=depart
50 )
51 )

可以看出,访问 LDAP 服务器与查询数据库中的记录很相似。事实上,在实际应用中,LDAP 服务器也与数据库服务器有着相似的作用。除了上面的用法之外,ldap_search 函数还支持通配符的使用。例如,将前面的用于 LDAP 服务器查询的代码修改如下。

1 <?php
2 $filter_val = "*@163.com";//定义用于匹配的值
3 $result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//执行查询
4 ?>

这里,就会将所有包含以“@163.com”结尾的邮件地址的记录返回。

获得查询结果中的值

上面的例子完整的获得了 LDAP 服务器查询结果的信息,这样,根据数组中的值就可以进行其他操作了。除此之外,PHP 还提供了专门的用于获得查询结果值的方法。首先介绍一种与 ldap_get_entries 相似的函数——ldap_first_entry,函数仅获得结果对象中的第一条记录,其语法格式如下所示。

1 ldap_first_entry(ldap_conn, result)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,result 是前面查询 LDAP 目录时返回的对象。获取结果中的值的函数为 ldap_get_values,该函数的语法格式如下所示。

1 ldap_get_values(ldap_conn, entry, column)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,entry 是前面查询查询结果时返回的对象,column 是要返回的值所在的列的名称。该函数返回一个仅包含该列信息的数组。以下代码返回了前面数组的 givenname 列。

01 <?php
02 $ldap_host = "ldap://192.168.3.1"; //LDAP 服务器地址
03 $ldap_port = "389"; //LDAP 服务器端口号
04 $ldap_user = ""; //设定服务器用户名
05 $ldap_pwd = ""; //设定服务器密码
06 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//建立与 LDAP 服务器的连接
07 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//与服务器绑定
08 $base_dn = "ou=company,o=depart";//定义要进行查询的目录
09 $filter_col = "mail";//定义用于查询的列
10 $filter_val = "phptester@163.com";//定义用于匹配的值
11 $result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//执行查询
12 $entry = ldap_first_entry($ldap_conn, $result);//获得第一个查询结果
13 $firstname = ldap_get_values($ldap_conn, $entry, "givenname");//获得查询结果中的值
14 print_r($firstname);//输出
15 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");//与服务器断开连接
16 ?>

运行结果如下所示。

1 Array
2 (
3 [0] => Peng Cheng
4 [1] => Peng
5 [count] => 2
6 )

计算查询结果中的记录数

计算查询结果中的记录数 ldap_count_entries 函数来实现,该函数的语法格式如下所示。

1 ldap_count_entries(ldap_conn, result)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,result 是前面查询 LDAP 目录时返回的对象。以下代码计算出了查询结果中的记录数。

01 <?php
02 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
03 $ldap_port = "389";//LDAP 服务器端口号
04 $ldap_user = "";//设定服务器用户名
05 $ldap_pwd = "";//设定服务器密码
06 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//建立与 LDAP 服务器的连接
07 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//与服务器绑定
08 $base_dn = "ou=company,o=depart";//定义要进行查询的目录
09 $filter_col = "mail";//定义用于查询的列
10 $filter_val = "*@163.com";//定义用于匹配的值
11 $result = ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//执行查询
12 $count = ldap_count_entries($ldap_conn, $result);//计算查询结果中的记录数
13 echo "Total records count: ".$count;//输出查询结果中的记录数
14 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");//与服务器断开连接
15 ?>

需要注意的是这里使用了通配符进行 LDAP 数据库的查询,因此,可能会有多条记录被返回。

向 LDAP 添加一条新记录

向 LDAP 添加一条新记录使用 ldap_add 函数来完成。

1 ldap_add(ldap_conn, base_dn, entry)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,base_dn 是 LDAP 服务器的查询主键,entry 是储存新记录的数组。以下代码实现了向 LDAP 服务器添加一条新记录的功能。

01 <?php
02 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
03 $ldap_port = "389";//LDAP 服务器端口号
04 $ldap_user = "";//设定服务器用户名
05 $ldap_pwd = "";//设定服务器密码
06 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//建立与 LDAP 服务器的连接
07 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server."); //与服务器绑定
08  
09 $base_dn = "ou=company,o=depart"//定义要进行查询的目录
10 $entry["givenname"] = "Simon"//定义新记录数组
11 $entry["company"] = "PHP workshop";
12 $entry["mail"] = "pch1982cn@cn.yahoo.com";
13 $entry["serial_no"] = "100001";
14 ldap_add($ldap_conn, $base_dn, $entryor die("Can't add new entry!");
15 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //与服务器断开连接
16 ?>

更新 LDAP 中的一条记录

更新 LDAP 中的一条记录使用 ldap_modify 函数来完成。

1 ldap_modify(ldap_conn, base_dn, entry)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,base_dn 是 LDAP 服务器的查询主键,entry 是储存更新后的记录的数组。以下代码实现了更新 LDAP 记录的功能。

01 <?php
02 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
03 $ldap_port = "389";//LDAP 服务器端口号
04 $ldap_user = "";//设定服务器用户名
05 $ldap_pwd = "";//设定服务器密码
06 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); //建立与 LDAP 服务器的连接
07 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server."); //与服务器绑定
08 $base_dn = "ou=company,o=depart"; //定义要进行查询的目录
09 $entry = array("company" => "PHP Workshop", "mail" => "pengcheng.sun@yahoo.com");//设定要修改的记录属性
10 ldap_modify($ldap_conn, $base_dn, $entry) or die("Can't modify entry."); //修改记录
11 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //与服务器断开连接
12 ?>

从 LDAP 中删除一条新记录

删除 LDAP 中的一条记录使用 ldap_delete 函数来完成。

1 ldap_modify(ldap_conn, base_dn)

其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象,base_dn 是 LDAP 服务器的查询主键。以下代码实现了删除 LDAP 记录的功能。

01 <?php
02 $ldap_host = "ldap://192.168.3.1";//LDAP 服务器地址
03 $ldap_port = "389";//LDAP 服务器端口号
04 $ldap_user = "";//设定服务器用户名
05 $ldap_pwd = "";//设定服务器密码
06 $ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); //建立与 LDAP 服务器的连接
07 ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//与服务器绑定
08 $base_dn = "ou=company,o=depart"; //定义要进行查询的目录
09 ldap_delete($ldap_conn, $base_dn) or die("Can't delete entry."); //修改记录
10 ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //与服务器断开连接
11 ?>

错误处理

PHP 还提供了对 LDAP 操作的错误处理的方法。主要包括 3 个函数——ldap_errno、ldap_error 和ldap_err2str。ldap_errno 的语法格式如下所示。int ldap_errno(resource)其中 resource 是在 LDAP 操作中产生的对象,该函数将返回一个错误代码。ldap_error 的语法格式如下所示。

1 string ldap_error(resource)

其中 resource 是在 LDAP 操作中产生的对象,该函数将返回一个错误信息。ldap_err2str 的语法格式如下所示。

1 string ldap_error(int errno)

其中 errno 是前面返回的错误代码,该函数将返回一个错误信息。该函数主要用于将错误代码转换成错误信息输出。以下代码试图连接一个不存在的服务器,输出错误的代码和错误信息。

01 <!--?php <br ?--> $ldap_host = "ldap://192.168.3.44";//LDAP 服务器地址
02 $ldap_port = "389";//LDAP 服务器端口号
03 $ldap_user = "";//设定服务器用户名
04 $ldap_pwd = "";//设定服务器密码
05 $ldap_conn = ldap_connect($ldap_host, $ldap_port);//建立与 LDAP 服务器的连接
06 @ldap_bind($ldap_conn, $ldap_user, $ldap_pwd);//与服务器绑定
07 echo "Error number: ".ldap_errno($ldap_conn)."
08 ";//输出错误代码
09 echo "Error message: ".ldap_error($ldap_conn)."
10 ";//输出错误信息
11 echo ldap_err2str(ldap_errno($ldap_conn));//输出错误信息
12 ?>

运行代码如下所示。
Error number: 81
Error message: Can’t contact LDAP server
Can’t contact LDAP server
上面的代码首先输出错误代码,然后输出错误信息,最后使用 ldap_err2str 函数将错误代码转换成错误信息。可以看到,两种方法输出的错误信息完全相同。

使用 LDAP 验证用户身份

本节将以一个实例来介绍如何使用 LDAP 验证用户身份。在实际应用中,可能会需要多个应用使用一个共同的用户名和密码来登陆。例如,一个企业使用多个系统来处理员工的日常操作,所有的系统均使用来自同一个 LDAP 目录的用户信息进行身验证。这样,就不需要在每个系统中保存不同的密码,只需要在 LDAP 目录中保存一个密码即可。使用 LDAP 验证用户身份的原理与上一节中介绍的绑定 LDAP 服务器的方法相同,不同的是验证时的用户名和密码来自用户的输入。完整的代码如下所示。

01 <?php
02 if (!isset($_SERVER['PHP_AUTH_USER']))
03 {
04 Header("WWW-Authenticate: Basic realm=\"login\"");
05 Header("HTTP/1.0 401 Unauthorized");
06 }
07 else
08 {
09 $ldap_host = "ldap://192.168.3.1";
10 $ldap_port = "389";
11 $ldap_user = $_SERVER['PHP_AUTH_USER'];
12 $ldap_pwd = $_SERVER['PHP_AUTH_PW'];
13 $ldap_conn = ldap_connect($ldap_host, $ldap_port)
14 or die("Can't connect to LDAP server");
15 @ldap_bind($ldap_conn, $ldap_user, $ldap_pwd);if(ldap_errno($ldap_conn)!=0)
16 {
17 echo "Can't log in! ".ldap_error($ldap_conn)."<br>";
18 }
19 else
20 {
21 echo "Welcome $ldap_user";
22 }
23 }
24 ?>

需要注意的是这里使用了$_SERVER[‘PHP_AUTH_USER’]和$_SERVER[‘PHP_AUTH_PW’]来获取用户名和密码.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值