LDAP的作用與實現


LDAP(Lightweight Directory Access Protocol)的意思是"輕量級目錄訪問協議",是一個用於訪問"目錄服務器"(Directory Servers)的協議。這里所謂的"目錄"是指一種按照樹狀結構存儲信息的數據庫。這個概念和硬盤上的目錄結構類似,不過LDAP的"根目錄"必須是"The world",並且其一級子目錄必須是"countries"。二級目錄通常包含有公司(companies)、組織(organisations)、地點(places)等等……相應的三級子目錄通常會包含人員(people)、設備(equipment)、文檔(documents)等等……

當你引用硬盤上的文件時,通常是這樣的:

/usr/local/myapp/docs

正斜杠(/)在這里表示級別分界線,並且從左向右閱讀。

 

而在LDAP中則通過"distinguished name"(簡稱"dn")來表示文件,通常像下面這樣:

cn=John Smith,ou=Accounts,o=My Company,c=US

逗號(,)在這里表示級別分界線,並且從右向左閱讀。上述dn可以理解為:

   country = US
   organization = My Company
   organizationalUnit = Accounts
   commonName = John Smith

術語對比:

dn,entry	目錄/文件
attribute	屬性
value		值

與硬盤目錄一樣,目錄服務器上的目錄結構也沒有任何限制,這就意味着你必須了解一些服務器的結構信息才能寫程序。

 

更多關於LDAP的信息可以在下面兩個URL找到:
Mozilla
OpenLDAP Project

安裝與配置

PHP默認並不啟用LDAP支持,PHP的LDAP模塊依賴於OpenLDAPbind9.net提供的客戶端LDAP庫,你必須在編譯的時候使用 --with-ldap[=DIR] 才行,如果你想要SASL支持,那還必須使用 --with-ldap-sasl[=DIR] 選項,而且你的系統中必須有 sasl.h 頭文件才行。

LDAP模塊的行為受下面的配置指令的影響

指令 數據類型 作用域 默認值 解釋
ldap.max_links 整數 PHP_INI_SYSTEM -1 每進程允許的最大LDAP連接數。"-1"表示無限制。

編程步驟

在進行LDAP編程之前,你必須知道目錄服務器的下列信息:

  • 服務器的IP地址(主機名)以及端口號
  • 服務器的"base dn"(也就是"the world"目錄下的子目錄,比如:"o=My Company,c=US")
  • 訪問服務器的用戶名(RDN)和密碼(許多服務器允許"匿名綁定"來讀取信息,但是其他操作必須有密碼才行)

一般的LDAP編程步驟如下:

  1. ldap_connect() // 連接到LDAP服務器
  2. ldap_bind() // 匿名登陸或者認證登陸
  3. 做一些操作,比如讀取、添加、刪除等...
  4. ldap_unbind() // 關閉連接

LDAP常用函數簡介

resource ldap_connect ([ string $hostname = NULL [, int $port = 389 ]] )

使用指定的主機名($hostname)和端口($port)連接到LDAP服務器。

$hostname
主機名,如果服務器端是 OpenLDAP 2.x.x 或更高版本,那么還可以使用 ldap://hostname/ 格式(URL格式)。
要使用SSL連接,那么必須確保OpenLDAP和PHP都帶有SSL支持,並使用 ldaps://hostname/ 的格式。
如果使用空格分隔的主機名列表(比如"192.168.0.100:389 192.168.0.101"),那么此函數將依次嘗試直到連接成功為止。
$port
連接的端口(默認為389)。在使用URL格式的時候不需要使用此參數,直接在URL里面指明即可(ldap://hostname:port/)。

連接成功則返回一個LDAP連接標識符,連接失敗則返回 FALSE 。
如果服務器端是 OpenLDAP 2.x.x 或更高版本,那么此函數將始終返回一個LDAP連接標識符,而永遠不會失敗。實際的連接動作將在接下來調用 ldap_* 函數[通常是ldap_bind()]時執行。
如果不帶任何參數調用此函數,則返回上一次連接已經打開的連接標識符。

bool ldap_bind ( resource $link_identifier [, string $bind_rdn = NULL [, string $bind_password = NULL ]] )

使用指定的RDN($bind_rdn)和密碼($bind_password)綁定到LDAP目錄。

$link_identifier
ldap_connect()函數返回的LDAP連接標識符
$bind_rdn
$bind_password
綁定時使用的RDN(Relative Distinguished Name)和密碼。如果未指定則使用匿名認證。

綁定成功返回 TRUE 否則返回 FALSE 。

string ldap_error ( resource $link_identifier )

檢索LDAP操作的錯誤信息。

$link_identifier
ldap_connect()函數返回的LDAP連接標識符

返回指定的連接標識符上最近一次LDAP操作的錯誤信息。

bool ldap_get_option ( resource $link_identifier , int $option , mixed &$retval )
bool ldap_set_option ( resource $link_identifier , int $option , mixed $newval )

獲取/設置LDAP選項的值。

$link_identifier
ldap_connect()函數返回的LDAP連接標識符
$option
LDAP選項名稱,主要的選項及其數據類型如下:
LDAP_OPT_DEREF(int)
搜索的時候如何處理別名,取值范圍如下:LDAP_DEREF_NEVER(0,默認值), LDAP_DEREF_SEARCHING(1), LDAP_DEREF_FINDING(2), LDAP_DEREF_ALWAYS(3)
LDAP_OPT_NETWORK_TIMEOUT(int)
網絡超時秒數,LDAP_NO_LIMIT(0,默認值)表示永不超時。
LDAP_OPT_PROTOCOL_VERSION(int)
指定使用的LDAP協議版本,取值范圍如下:LDAP_VERSION2(2,默認值), LDAP_VERSION3 (3)。
LDAP_OPT_REFERRALS(bool)
LDAP庫是否自動追隨LDAP服務器返回的引用,取值范圍如下:TRUE(1,默認值), FALSE(0)。
&$retval
接受選項值的變量
$newval
選項的新值

獲取/設置成功返回 TRUE 否則返回 FALSE 。

bool ldap_add ( resource $link_identifier , string $dn , array $entry )
bool ldap_delete ( resource $link_identifier , string $dn )

在LDAP目錄中添加/刪除一個項。

$link_identifier
ldap_connect()函數返回的LDAP連接標識符
$dn
將要添加/刪除的項目名稱(distinguished name)。
$entry
指定新項內容的關聯數組(attribute=>value)。如果value也是一個數組,那么必須是從0開始的索引數組。例如:
$entry["bool"]='TRUE';
$entry["int"]='-3';
$entry["mail"]='jonj@example.com';
$entree["tel"][0] = "2222222";
$entree["tel"][1] = "4444444";

添加/刪除成功返回 TRUE 否則返回 FALSE 。

mixed ldap_compare ( resource $link_identifier , string $dn , string $attribute , string $value )

檢查LDAP目錄項$dn的$attribute屬性值與給定的$value是否相同。注意:不能用來比較二進制數據!

$link_identifier
ldap_connect()函數返回的LDAP連接標識符
$dn
LDAP項的名稱(distinguished name)
$attribute
屬性名
$value
給定的值

相同返回 TRUE ,不同返回 FALSE ,遇見錯誤返回 -1

resource ldap_read ( resource $link_identifier , string $base_dn , string $filter [, array $attributes [, int $attrsonly [, int $sizelimit [, int $timelimit [, int $deref ]]]]] )
resource ldap_list ( resource $link_identifier , string $base_dn , string $filter [, array $attributes [, int $attrsonly [, int $sizelimit [, int $timelimit [, int $deref ]]]]] )
resource ldap_search ( resource $link_identifier , string $base_dn , string $filter [, array $attributes [, int $attrsonly [, int $sizelimit [, int $timelimit [, int $deref ]]]]] )

使用指定的過濾器搜索LDAP目錄。三個函數的不同之處在於搜索范圍不同:
read僅搜索$base_dn本身(LDAP_SCOPE_BASE),相當於從目錄中讀取一個條目(entry)。
list僅搜索$base_dn的下一級對象(LDAP_SCOPE_ONELEVEL),不包含本身,相當於"ls"命令。
search搜索$base_dn本身及其所有子對象(LDAP_SCOPE_SUBTREE),相當於搜索整個目錄樹。

$link_identifier
ldap_connect()函數返回的LDAP連接標識符
$base_dn
將要被搜索的目錄的DN
$filter
搜索過濾器。比如"(objectClass=*)"表示搜索所有條目(對於read函數則表示所有屬性)。
其語法規則在 RFC2254中描述,例如:"(|(sn=$person*)(givenname=$person*))"
$attributes
需要檢索的屬性名稱數組,比如:array("mail", "sn", "cn")。
注意:不管有沒有指定,"dn"屬性的值總會被返回。
如果不指定此參數,那么將返回所有的屬性值。
$attrsonly
默認值"0"表示同時獲取屬性的類型(attribute type)和屬性的值(attribute value)。
非默認值"1"表示僅獲取屬性的類型(attribute type)。
$sizelimit
限定最多返回多少條記錄。默認值"0"表示沒有限制。注意:這個參數不能超越服務器的限制。
$timelimit
限定搜索操作最大允許進行多少秒。默認值"0"表示沒有限制。注意:這個參數不能超越服務器的限制。
$deref
指定搜索的時候如何處理別名。取值范圍如下:
LDAP_DEREF_NEVER(默認)
在搜索中或者查找那基礎對象時做不復引用別名
LDAP_DEREF_SEARCHING
在基礎對象的附屬的搜索中而不是查找那基礎對象時做復引用別名
LDAP_DEREF_FINDING
在基礎對象而不是其附屬的搜索中做復引用別名
LDAP_DEREF_ALWAYS
在搜索中或者查找那基礎對象時做都復引用別名

成功返回一個結果集的資源描述符,通常被其他函數以$result_identifier引用,失敗返回FALSE

array ldap_get_entries ( resource $link_identifier , resource $result_identifier )

返回前一次搜索操作的結果集,包括每一項的屬性和屬性值。

$link_identifier
ldap_connect()函數返回的LDAP連接標識符
$result_identifier
ldap_read/ldap_list/ldap_search函數返回的結果集的資源描述符。

成功返回一個包含結果集的多維數組,失敗返回FALSE。
注意:結果集數組的屬性索引將被轉換成小寫字母(對於LDAP來說屬性是大小寫無關的)。
結果集數組的結構如下所示:

return_value["count"] = 結果集中的條目總數(包含第零項)
return_value[0] : 對結果集中第零項(一般不同於后面的常規項)的詳細信息的引用

return_value[i]["dn"] =  結果集中第 i 個條目的 DN
return_value[i]["count"] = 結果集中第 i 個條目的屬性數量
return_value[i][j] = 結果集中第 i 個條目的第 j 個屬性

return_value[i]["attribute"]["count"] = 結果集中第 i 個條目的"attribute"屬性的值的數量
return_value[i]["attribute"][j] = 結果集中第 i 個條目的"attribute"屬性的第 j 個值

 

bool ldap_unbind ( resource $link_identifier )

解除綁定,也就是關閉LDAP連接。

$link_identifier
ldap_connect()函數返回的LDAP連接標識符

成功返回 TRUE 否則返回 FALSE 。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM