歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> 關於Unix >> 在Windows和UNIX下利用PHP和LDAP進行身份驗證

在Windows和UNIX下利用PHP和LDAP進行身份驗證

日期:2017/2/28 11:28:49   编辑:關於Unix


  我現在的老板曾要求我為企業內部互聯網的Web服務提供一種標准的身份驗證方法。我遇到的一個主要問題就是我們公司主要使用了兩種平台:UNIX和Windows。所以,我的第一個想法並不很成功:它要求每個員工都使用UNIX或者Linux而放棄Windows。
  
  我認為解決現在的UNIX/Windows問題的最好方法就是利用PHP的LDAP特性。由於LDAP服務器,要求我使用現有的系統,主要指的是一個巨大的Microsoft Exchange Server系統。我非常高興使用Exchange,它很可靠,而且LDAP特性的使用和配置也極為簡單。不過,請你注意:這套方案就身份驗證角度來看並不是最安全的。如果有較高等級的安全需求,我強烈建議你采用LDAP和SSL。
  
  從哪裡開始學習
  為了讓你入門,我給出了一個PHP LDAP函數的清單並對函數的功能給以簡要說明。然後,我將演示如何建立到LDAP服務器的連接並驗證用戶。為了代碼簡單起見,我將演示PHP連接的功能以及如何綁定到LDAP服務器。
  
  一對絕配:PHP和LADP
  下面是我在例子中將要使用的函數的清單。網上有相關資料。
  
  ldap_connect—用來連接LDAP服務。
  ldap_bind—用來綁定到特定的LDAP目錄。
  ldap_error—從LDAP服務器上獲得錯誤信息。
  ldap_search—用來開始搜索。
  ldap_get_entries—從搜索結果中獲得多個結果。
  ldap_close—關閉LDAP連接。
  
  現在我在例子中演示如何使用第一個函數(代碼清單A)並適當介紹該函數的功能。
  
     // LDAP variables
  $ldap[‘user’] = ‘uname’;
  $ldap[‘pass’] = ‘password’;
  $ldap[‘port’] = 389;
  $ldap[‘dn’] = ‘cn’.$ldap[‘user’].’,ou=Department,o=Company Name’;
  $ldap[‘base’] = ‘’;
  
  // connecting to ldap
  $ldap[‘conn’] = ldap_connect( $ldap[‘host’], $ldap[‘port’] )
  or die( “Could not connect to {$ldap[‘host’]}” );
  ?>
  將會返回一個到LDAP服務器的連接(也稱為資源,即resource)。ldap_connect函數有兩個參數:主機(host)和端口。第一個參數:主機就是LDAP主機名稱,第二個參數是LDAP運行的端口。默認情況下,LDAP使用的端口號為389。如果你需要到LDAP服務器的一個安全連接,你可以把參數host改為一個你可以訪問的LDAP服務器的URL,如下所示:
  
  
  由於你指定了URL而不是服務器名稱,在這種方法下,你就不需要使用端口參數了。需要牢記的一點就是確切名稱需要與加密套接字協議層證書(the SSL certificate)對應。
  
     // LDAP variables
  $ldap[‘user’] = ‘uname’;
  $ldap[‘pass’] = ‘password’;
  $ldap[‘port’] = 389;
  $ldap[‘dn’] = ‘cn’.$ldap[‘user’].’,ou=Department,o=Company Name’;
  $ldap[‘base’] = ‘’;
  
  // connecting to ldap
  $ldap[‘conn’] = ldap_connect( $ldap[‘host’], $ldap[‘port’] )
  or die( “Could not connect to {$ldap[‘host’]}” );
  
  // binding to ldap
  $ldap[‘bind’] = ldap_bind( $ldap[‘conn’], $ldap[‘dn’], $ldap[‘pass’] );
  
  ?>
  演示了如何用用戶名和口令來綁定到服務器。我創建了一個合適的域名(domain name ,DN)並用用戶的口令來合法連接到LDAP。我們通過使用域名和口令就可以讓LDAP服務器通過身份認證並允許綁定連接,這樣我們就成功的綁定上了。ldap_bind的返回值是一個布爾類型。我們可以根據返回值判斷用戶的登錄證書是否有效。當這個過程結束後,你就可以知道用戶身份是否得到了認證。
  
  如果發生了錯誤會怎樣?調用ldap_error函數是判斷發生了什麼錯誤的好方法。ldap_error函數返回了一個字符串,其中包含了LDAP服務器發生的最後錯誤的信息。
  
  在
  
     // LDAP variables
  $ldap[‘user’] = ‘uname’;
  $ldap[‘pass’] = ‘password’;
  $ldap[‘port’] = 389;
  $ldap[‘dn’] = ‘cn’.$ldap[‘user’].’,ou=Department,o=Company Name’;
  $ldap[‘base’] = ‘’;
  
  // connecting to ldap
  $ldap[‘conn’] = ldap_connect( $ldap[‘host’], $ldap[‘port’] )
  or die( “Could not connect to server {$ldap[‘host’]} );
  
  // binding to ldap
  $ldap[‘bind’] = ldap_bind( $ldap[‘conn’], $ldap[‘dn’], $ldap[‘pass’] );
  
  if( !$ldap[‘bind’] )
  {
  echo ldap_error( $ldap[‘conn’] );
  exit;
  }
  
  ?>
  
  中,我向腳本中添加了ldap_error函數,如果綁定到LDAP服務器的用戶身份沒有得到確認,那麼代碼將退出運行。該函數返回一個字符串,該字符串包含了發送到LDAP服務器的最後一條指令產生的錯誤信息。如果你按給定用戶名和口令的綁定沒有成功登錄,那麼錯誤信息將包含這對無效的用戶名和口令。
  
  在我們的最後一個例子中
  
QUOTE:   // LDAP variables
  $ldap[‘user’] = ‘uname’;
  $ldap[‘pass’] = ‘password’;
  $ldap[‘port’] = 389;
  $ldap[‘dn’] = ‘cn’.$ldap[‘user’].’,ou=Department,o=Company Name’;
  $ldap[‘base’] = ‘’;
  
  // connecting to ldap
  $ldap[‘conn’] = ldap_connect( $ldap[‘host’], $ldap[‘port’] )
  or die( “Could not connect to server {$ldap[‘host’]} );
  
  // binding to ldap
  $ldap[‘bind’] = ldap_bind( $ldap[‘conn’], $ldap[‘dn’], $ldap[‘pass’] );
  
  if( !$ldap[‘bind’] )
  {
  echo ldap_error( $ldap[‘conn’] );
  exit;
  }
  
  // search for the user on the ldap server and return all
  // the user information
  $ldap[‘result’] = ldap_search( $ldap[‘conn’], $ldap[‘base’], ‘uid=’.$ldap[‘user’] );
  
  if( $ldap[‘result’] )
  {
  // retrieve all the entries from the search result
  $ldap[‘info’] = ldap_get_entries( $ldap[‘conn’], $ldap[‘result’] );
  }
  else
  {
  echo ldap_error( $ldap[‘conn’] );
  exit;
  
  }
  
  if( $ldap[‘info’] )
  {
  // Add the user’s department name and email address
  // to the session
  $_SESSION[‘userdept’] = $ldap[‘info’][0][‘department’][0];
  $_SESSION[‘usermail’] = $ldap[‘info’][0][‘mail’][0];
  }
  else
  {
  echo ldap_error( $ldap[‘conn’] );
  exit;
  }
  
  // close connection to ldap server
  $ldap_close( $ldap[‘conn’] );
  
  ?>

  
  我同時使用了上述函數清單中的最後列出的三個函數:: ldap_search、ldap_get_entries以及ldap_close.
  
  當代碼清單D中調用過ldap_bind函數後,我通過調用ldap_search函數來搜索服務器以獲得我需要的信息。ldap_search函數有多個參數,不過,我們這裡只使用了前三個參數。我向搜索函數傳遞了ldap connection、search base和filter參數,這樣該函數就會正確用戶名下以及支持的搜索范圍和過濾條件下對服務器進行搜索。簡而言之,就是我指定uid來指示用戶名說明搜索的用戶。這樣LDAP服務器就會過濾搜索結果,僅僅返回該用戶自己的LDAP信息。
  
  學習過程
  當我第一次開始用PHP的LDAP擴展時候,我對ldap_search函數只返回資源而不是一個數組或者字符串而迷惑不解。當我學會用ldap_get_entries函數來獲取搜索的實際結果時,我才明白過來。ldap_get_entries函數的一個優點就是它把搜索結果作為一個多維數組來返回。就是說,我把搜索結果存到一個名為$ldap[‘info’]的數組中,這看起來挺讓人迷惑的。
  
  由於在多維數組中有我搜索的結果,我可以任意處理這些數據。我把用戶的部門和電子郵件地址保存到session變量中,以便在本次session的稍後時候用上。
  
  當這些事情都做完之後,我用ldap_close函數關閉連接。關閉函數可以釋放連接資源。該函數還有一個別名ldap_unbind,它們實際上是同一個函數。
  
  一個很好的出發點
  盡管我對LDAP擴展中的其它函數有很多接觸,我列出的函數對你初學LDAP身份認證來說已經夠用了。PHP和LDAP的聯合為基於Web的應用程序提供了一種通用的驗證用戶身份的方法。LDAP服務器允許管理員對用戶授權訪問許可,它也可以允許或者拒絕應用程序對數據的訪問。
Copyright © Linux教程網 All Rights Reserved