PHP訪問LDAP

LDAP 的全稱是「輕量級目錄訪問協議(Lightweight Directory Access Protocol)」,是一種簡單的目錄協議。所謂目錄,是一種專門的數據庫,能夠用來服務於任何應用程序。在企業應用中使用 LDAP可讓企業範圍內的全部應用程序LDAP 目錄中獲取信息,應用程序能夠從網絡上直接從 LDAP 目錄獲取信息,而不侷限於操做系統與服務器的類型。這裏主要介紹如何使用 PHP 來訪問 LDAP。 php

 LDAP目錄中的信息是是按照樹型結構組織,具體信息存儲在條目(entry)的數據結構中。條目至關於關係數據庫中表的記錄;條目是具備區別名DN (Distinguished Name)的屬性(Attribute),DN是用來引用條目的,DN至關於關係數據庫表中的關鍵字(Primary Key)。
數據庫

LDAP簡稱對應 數組

1.o-organization 服務器

2.ou-organization unit 網絡

3.c- countryName 數據結構

4.dc-domainComponent dom

5.sn-suer name 函數

6.cn-common name ui

鏈接LDAP服務器

PHP中用於鏈接LDAP服務器的函數時ldap_connect,其語法格式以下所示。 spa

ldap_connect([string hostname [, int port]])
其中,hostname是LDAP服務器所在的主機地址,port是LDAP服務器的端口號。如下代碼實現了對位於192.168.3.1地址的服務器鏈接。

<?PHP
$ldap_host = "ldap:192.168.3.1";//LDAP服務器地址
$ldap_port = "389";
$ldap_conn = ldap_connect($ldap_host,$ldap_port) or die ("Can't connect to LDAP server");//創建與LDAP服務器鏈接
?>

綁定LDAP服務器

綁定 LDAP 服務器的含義是使用特定的用戶名或密碼來登錄 LDAP 服務器。PHP 中用於綁定 LDAP服務器的函數是 ldap_bind,其語法格式以下所示。

ldap_bind(ldap_conn[,string username [, string password]])
其中ldap_conn是前面鏈接LDAP服務器時建立的鏈接對象,username是登錄LDAP服務器時使用的用戶名,password是登錄時所用的密碼。如下代碼實現了對位於198.168.3.1地址的LDAP服務器的綁定。

<?php
$ldap_host = "ldap:192.168.3.1";//LDAP服務器
$ldap_port = "386";//LDAP服務器端口號
$ldap_user = "";//設定服務器用戶名
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ladp_connect($ldap_host,$ladp_port) or die("Can't connect to the LDA server.");
$ldap_bind($ldap_conn,$ldap_user,$ldap_pwd) or die("Can't bind to LDAP server.");
?>
斷開LDAP服務器

與LDAP服務器斷開的過程與綁定LDAP服務器相反,PHP中用於綁定LDAP服務器的函數時ldap_unbind,其語法格式以下

ldap_unbind(ldap_conn)

其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象。如下代碼在綁定了對位於 192.168.3.1地址的 LDAP 服務器後與其斷開鏈接。

<?PHP
$ldap_host = "ldap://192.168.3.1";
$ldap_user = "";
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");
ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");
ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");
?>

查詢LDAP目錄內容

查詢LDAP目錄使用ldap_search函數來實現,其語法格式以下所示。

ldap_search(ldap_conn,base_dn,conditions)
其中,ldap_conn是前面鏈接LDAP服務器時建立的鏈接對象。base_dn是LDAP服務器的查詢主鍵。conditions是用於LDAP目錄查詢所用的條件。該函數返回一個結果對象,該結果對象保存查詢到的全部記錄。對於這個結果對象,可使用ldap_get_entries函數進行簡單的讀取,其語法格式以下所示。

ldap_get_entries(ldap_conn,result)
其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,result 是前面查詢 LDAP 目錄時返回的對象。該函數返回一個數組,包含全部的結果記錄。如下代碼實現了對服務器上的內容進行查詢。


<?php
$ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址
$ldap_port = "389";//LDAP 服務器端口號
$ldap_user = "";//設定服務器用戶名
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接
ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定
$base_dn = "ou=company,o=depart";//定義要進行查詢的目錄主鍵
$filter_col = "mail";//定義用於查詢的列
$filter_val = "phptester@163.com";//定義用於匹配的值
$result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");
$entry= ldap_get_entries($ldap_conn, $result);//得到查詢結果
print_r($entry);
ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接
?>

運行結果以下所示。

Array
(
[count] => 1
[0] => Array
(
[objectclass] => Array
(
[count] => 5
[0] => person
[1] => organizationalPerson
[2] => companyPerson
[3] => departPerson
[4] => top
)
[0] => objectclass
[ou] => Array
(
[count] => 1
[0] => company
)
[1] => ou
[o] => Array
(
[count] => 1
[0] => depart
)
[2] => o
[employeeserialnumber] => Array
(
[count] => 1
[0] => 100001
)
[3] => employeeserialnumber

[givenname] => Array
(
[count] => 2
[0] => Peng Cheng
[1] => Peng
)
[4] => givenname
[mail] => Array
(
[count] => 1
[0] => phptester@163.com
)
[5] => mail
[count] => 6
[dn] => uid=672100001,c=cn,ou=company,o=depart
)
)
能夠看出,訪問LDAP服務器與查詢數據庫中的記錄很類似。事實上,在實際應用中,LDAP服務器也與數據庫服務器有着類似的做用。除了上面的用法外,ldap_search函數還支持通配符使用。例如,將前面的用於LDAP服務器查詢的代碼修改以下。

<?php
$filter_val = "*@163.com";//定義用於匹配的值
$result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//執行查詢
?>
這裏就會將全部包含以「@163.com」結尾的郵件地址的記錄返回。

得到查詢結果中的值

上面的例子完整的得到了LDAP服務器查詢結果的信息,這樣,根據數組中的值就能夠進行其餘操做了。除此以外,PHP還提供了專門用於得到查詢結果值的方法。首先介紹一種與ldap_get_entries類似的函數--ldap_first_entry,函數僅得到結果對象中的第一條記錄,其語法格式以下。

ldap_first_entry(ldap_conn, result)
其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,result 是前面查詢 LDAP 目錄時返回的對象。獲取結果中的值的函數爲 ldap_get_values,該函數的語法格式以下所示。

ldap_get_values(ldap_conn, entry, column)
其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,entry 是前面查詢查詢結果時返回的對象,column 是要返回的值所在的列的名稱。該函數返回一個僅包含該列信息的數組。如下代碼返回了前面數組的 givenname 列。

<?php
$ldap_host = "ldap://192.168.3.1"; //LDAP 服務器地址
$ldap_port = "389"; //LDAP 服務器端口號
$ldap_user = ""; //設定服務器用戶名
$ldap_pwd = ""; //設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接
ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定
$base_dn = "ou=company,o=depart";//定義要進行查詢的目錄
$filter_col = "mail";//定義用於查詢的列
$filter_val = "phptester@163.com";//定義用於匹配的值
$result= ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//執行查詢
$entry = ldap_first_entry($ldap_conn, $result);//得到第一個查詢結果
$firstname = ldap_get_values($ldap_conn, $entry, "givenname");//得到查詢結果中的值
print_r($firstname);//輸出
ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");//與服務器斷開鏈接
?>
運行結果以下所示。

Array
(
[0] => Peng Cheng
[1] => Peng
[count] => 2
)

計算查詢結果中的記錄數

計算查詢結果中的記錄數ldap_count_entries函數來實現,該函數的語法格式以下所示、

ldap_count_entries(ldap_conn, result)
其中,ldap_conn是前面鏈接LDAP服務器時建立的鏈接對象 ,result 是前面查詢 LDAP 目錄時返回的對象。如下代碼計算出了查詢結果中的記錄數。

<?php
$ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址
$ldap_port = "389";//LDAP 服務器端口號
$ldap_user = "";//設定服務器用戶名
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接
ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定
$base_dn = "ou=company,o=depart";//定義要進行查詢的目錄
$filter_col = "mail";//定義用於查詢的列
$filter_val = "*@163.com";//定義用於匹配的值
$result = ldap_search($ldap_conn, $base_dn, "($filter_col=$filter_val)");//執行查詢
$count = ldap_count_entries($ldap_conn, $result);//計算查詢結果中的記錄數
echo "Total records count: ".$count;//輸出查詢結果中的記錄數
ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server.");//與服務器斷開鏈接
?>
須要注意的是這裏使用了通配符進行 LDAP 數據庫的查詢,所以,可能會有多條記錄被返回

向 LDAP 添加一條新記錄

向 LDAP 添加一條新記錄使用 ldap_add 函數來完成。

ldap_add(ldap_conn, base_dn, entry)

其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,base_dn 是 LDAP 服務器的查詢主鍵,entry 是儲存新記錄的數組。如下代碼實現了向 LDAP 服務器添加一條新記錄的功能。

<?php
$ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址
$ldap_port = "389";//LDAP 服務器端口號
$ldap_user = "";//設定服務器用戶名
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server");//創建與 LDAP 服務器的鏈接
ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server."); //與服務器綁定

$base_dn = "ou=company,o=depart";  //定義要進行查詢的目錄
$entry["givenname"] = "Simon";  //定義新記錄數組
$entry["company"] = "PHP workshop";
$entry["mail"] = "pch1982cn@cn.yahoo.com";
$entry["serial_no"] = "100001";
ldap_add($ldap_conn, $base_dn, $entry)  or die("Can't add new entry!");
ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接
?>



更新LDAP中的一條記錄

更新LDAP中的一條記錄使用ldap_modify函數來完成

ldap_modify(ldap_conn, base_dn, entry)



其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,base_dn 是 LDAP 服務器的查詢主鍵,entry 是儲存更新後的記錄的數組。如下代碼實現了更新 LDAP 記錄的功能。
<?php
$ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址
$ldap_port = "389";//LDAP 服務器端口號
$ldap_user = "";//設定服務器用戶名
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); //創建與 LDAP 服務器的鏈接
ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server."); //與服務器綁定
$base_dn = "ou=company,o=depart"; //定義要進行查詢的目錄
$entry = array("company" => "PHP Workshop", "mail" => "pengcheng.sun@yahoo.com");//設定要修改的記錄屬性
ldap_modify($ldap_conn, $base_dn, $entry) or die("Can't modify entry."); //修改記錄
ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接
?>



從 LDAP 中刪除一條新記錄

刪除 LDAP 中的一條記錄使用 ldap_delete 函數來完成。

ldap_modify(ldap_conn, base_dn)



其中,ldap_conn 是前面鏈接 LDAP 服務器時建立的鏈接對象,base_dn 是 LDAP 服務器的查詢主鍵。如下代碼實現了刪除 LDAP 記錄的功能。
<?php
$ldap_host = "ldap://192.168.3.1";//LDAP 服務器地址
$ldap_port = "389";//LDAP 服務器端口號
$ldap_user = "";//設定服務器用戶名
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port) or die("Can't connect to LDAP server"); //創建與 LDAP 服務器的鏈接
ldap_bind($ldap_conn, $ldap_user, $ldap_pwd) or die("Can't bind to LDAP server.");//與服務器綁定
$base_dn = "ou=company,o=depart"; //定義要進行查詢的目錄
ldap_delete($ldap_conn, $base_dn) or die("Can't delete entry."); //修改記錄
ldap_unbind($ldap_conn) or die("Can't unbind from LDAP server."); //與服務器斷開鏈接
?>



錯誤處理

PHP 還提供了對 LDAP 操做的錯誤處理的方法。主要包括 3 個函數——ldap_errno、ldap_error 和ldap_err2str。ldap_errno 的語法格式以下所示。int ldap_errno(resource)其中 resource 是在 LDAP 操做中產生的對象,該函數將返回一個錯誤代碼。ldap_error 的語法格式以下所示。

string ldap_error(resource)



其中 resource 是在 LDAP 操做中產生的對象,該函數將返回一個錯誤信息。ldap_err2str 的語法格式以下所示。
string ldap_error(int errno)



其中 errno 是前面返回的錯誤代碼,該函數將返回一個錯誤信息。該函數主要用於將錯誤代碼轉換成錯誤信息輸出。如下代碼試圖鏈接一個不存在的服務器,輸出錯誤的代碼和錯誤信息。
<!--?php <br ?--> $ldap_host = "ldap://192.168.3.44";//LDAP 服務器地址
$ldap_port = "389";//LDAP 服務器端口號
$ldap_user = "";//設定服務器用戶名
$ldap_pwd = "";//設定服務器密碼
$ldap_conn = ldap_connect($ldap_host, $ldap_port);//創建與 LDAP 服務器的鏈接
@ldap_bind($ldap_conn, $ldap_user, $ldap_pwd);//與服務器綁定
echo "Error number: ".ldap_errno($ldap_conn)."
";//輸出錯誤代碼
echo "Error message: ".ldap_error($ldap_conn)."
";//輸出錯誤信息
echo ldap_err2str(ldap_errno($ldap_conn));//輸出錯誤信息
?>



運行代碼以下所示。
Error number: 81
Error message: Can’t contact LDAP server
Can’t contact LDAP server
上面的代碼首先輸出錯誤代碼,而後輸出錯誤信息,最後使用 ldap_err2str 函數將錯誤代碼轉換成錯誤信息。能夠看到,兩種方法輸出的錯誤信息徹底相同。

使用 LDAP 驗證用戶身份

在實際應用中,可能會須要多個應用使用一個共同的用戶名和密碼來登錄。例如,一個企業使用多個系統來處理員工的平常操做,全部的系統均使用來自同一個LDAP目錄的用戶信息進行身份驗證。這樣,就不須要在每一個系統中保存不一樣的密碼,只須要在LDAP目錄中保存一個密碼便可。使用LDAP驗證用戶身份的原理與上一節中介紹的綁定LDAP服務器的方法相同。不一樣的驗證時的用戶名和密碼來自用戶的輸入。完整代碼以下

<?php
if (!isset($_SERVER['PHP_AUTH_USER']))
{
Header("WWW-Authenticate: Basic realm=\"login\"");
Header("HTTP/1.0 401 Unauthorized");
}
else
{
$ldap_host = "ldap://192.168.3.1";
$ldap_port = "389";
$ldap_user = $_SERVER['PHP_AUTH_USER'];
$ldap_pwd = $_SERVER['PHP_AUTH_PW'];
$ldap_conn = ldap_connect($ldap_host, $ldap_port)
or die("Can't connect to LDAP server");
@ldap_bind($ldap_conn, $ldap_user, $ldap_pwd);if(ldap_errno($ldap_conn)!=0)
{
echo "Can't log in! ".ldap_error($ldap_conn)."<br>";
}
else
{
echo "Welcome $ldap_user";
}
}
?>



須要注意的是這裏使用了$_SERVER['PHP_AUTH_USER']和$_SERVER['PHP_AUTH_PW']來獲取用戶名和密碼.
相關文章
相關標籤/搜索