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"
;
4
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
or
die
(
"Can't connect to LDAP server"
);
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"
;
4
$ldap_user
=
""
;
5
$ldap_pwd
=
""
;
6
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
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,其语法格式如下所示。
其中,ldap_conn 是前面连接 LDAP 服务器时创建的连接对象。以下代码在绑定了对位于 192.168.3.1地址的 LDAP 服务器后与其断开连接。
01
<?php
02
$ldap_host
=
"ldap://192.168.3.1"
;//LDAP 服务器地址
03
$ldap_port
=
"389"
;
04
$ldap_user
=
""
;
05
$ldap_pwd
=
""
;
06
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
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"
;
04
$ldap_user
=
""
;
05
$ldap_pwd
=
""
;
06
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
or
die
(
"Can't connect to LDAP server"
);
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"
;
04
$ldap_user
=
""
;
05
$ldap_pwd
=
""
;
06
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
or
die
(
"Can't connect to LDAP server"
);
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"
;
04
$ldap_user
=
""
;
05
$ldap_pwd
=
""
;
06
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
or
die
(
"Can't connect to LDAP server"
);
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"
;
04
$ldap_user
=
""
;
05
$ldap_pwd
=
""
;
06
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
or
die
(
"Can't connect to LDAP server"
);
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
,
$entry
)
or
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"
;
04
$ldap_user
=
""
;
05
$ldap_pwd
=
""
;
06
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
or
die
(
"Can't connect to LDAP server"
);
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"
;
04
$ldap_user
=
""
;
05
$ldap_pwd
=
""
;
06
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
)
or
die
(
"Can't connect to LDAP server"
);
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"
;
03
$ldap_user
=
""
;
04
$ldap_pwd
=
""
;
05
$ldap_conn
= ldap_connect(
$ldap_host
,
$ldap_port
);
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