LDAP開發學習

因爲項目須要實現SSO單點登陸的功能,因此,這裏借用LDAP實現,LDAP的優勢是不使用數據庫就可在服務器創建一種權限關係。php

1、LDAP簡介

LDAP 的全稱是「輕量級目錄訪問協議 (Lightweight Directory Access Protocol)」,是一種簡單的目錄協議。所謂目錄,是一種專門的數據庫,能夠用來服務於任何應用程序。公司的域賬號登陸採用的是Ldap登陸驗證,全部的系統均使用來自同一個 LDAP 目錄的用戶信息進行身驗證。這樣,就不須要在每一個系統中保存不一樣的密碼,只須要在 LDAP 目錄中保存一個密碼便可。本文主要介紹一下PHP環境下如何經過後臺登陸公司Ldap服務器驗證用戶名密碼。html

2、LDAP目錄樹的結構

 LDAP目錄以樹狀的層次結構來存儲數據。若是你對自頂向下的DNS樹或UNIX文件的目錄樹比較熟悉,也就很容易掌握LDAP目錄樹這個概念了。就象DNS的主機名那樣,LDAP目錄記錄的標識名(Distinguished Name,簡稱DN)是用來讀取單個記錄,以及回溯到樹的頂部。web

1. 基準DN

DN:標識名,簡稱DN (Distinguished Name,簡稱DN)
是用來讀取單個記錄,以及回溯到樹的頂部。數據庫

這種格式很直觀,用公司的域名做爲基準DN。這也是如今最經常使用的格式。
dc=foobar, dc=com
(用DNS域名的不一樣部分組成的基準DN)vim

DC=Domain Component 爲用戶名或服務器名,最長能夠到80個字符,能夠爲中文;
CN=Common Name 爲用戶名或服務器名,最長能夠到80個字符,能夠爲中文;
OU=Organizational Unit爲組織單元,最多能夠有四級,每級最長32個字符,能夠爲中文;
O=Organization 爲組織名segmentfault

CN, OU, DC 都是 LDAP 鏈接服務器的端字符串中的區別名稱(DN, distinguished name)
LDAP鏈接服務器的鏈接字串格式爲:ldap://servername/DN
其中DN有三個屬性,分別是CN,OU,DC
LDAP是一種通信協議,如同HTTP是一種協議同樣的!
在 LDAP 目錄中,
· DC (Domain Component)
· CN (Common Name)
· OU (Organizational Unit)服務器

LDAP 目錄相似於文件系統目錄。
下列目錄:dom

DC=redmond,DC=wa,DC=microsoft,DC=com

若是咱們類比文件系統的話,可被看做以下文件路徑:ui

Com\Microsoft\Wa\Redmond

例如:spa

CN=test,OU=developer,DC=domainname,DC=com

在上面的代碼中 cn=test 可能表明一個用戶名,ou=developer 表明一個 active directory 中的組織單位。這句話的含義可能就是說明 test 這個對象處在domainname.com 域的 developer 組織單元中。

3、安裝LDAP

安裝OpenLdap

tar zvxf openldap2.4.31.tgz  
cd /openldap2.4.31  
./configure --prefix=/usr/local/openldap  
make depend  
make  
make test  
make install

注意: 在執行./configure的時候可能會報以下錯誤
configure: error: MozNSS not found – please specify the location to the NSPR and NSS header files in CPPFLAGS and the location to the NSPR and NSS libraries in LDFLAGS (if not in the system location)

緣由是openldap須要依賴openssl的一些庫文件,安裝openldap,而後配置SSL的環境變量

root@homestead:/home/other/openldap-2.4.31# export CPPFLAGS="-I/usr/local/BerkeleyDB.5.1/include -I/usr/local/ssl/include "
root@homestead:/home/other/openldap-2.4.31# export LDFLAGS="-L/usr/local/BerkeleyDB.5.1/lib -L/usr/local/ssl/lib "

使用 find -name xxx 命令查找文件

[root@openldap openldap]# find -name slapd.conf
./slapd.conf

進入etc 配置修改

cd /etc/openldap/

殺掉ldap:

killall slapd

查看進程:

netstat -anlt

啓動slapd服務

/usr/local/openldap-2.4.31/libexec/slapd

4、使用

<?php

define('LDAP_SERVER_IP', '127.0.0.1');
define('LDAP_SERVER_PORT', 389);

// 創建到ldap服務器的鏈接LDAP_SERVER_IP是ldap服務器ip,LDAP_SERVER_PORT是ldap服務器端口(默認389) 
$ldapConnect = ldap_connect(LDAP_SERVER_IP, LDAP_SERVER_PORT) or die("Could not connect to " . LDAP_SERVER_IP); 

if ($ldapConnect)
{ 
   $username = "xiaowang"; 
   $upasswd  = "123456"; 
   $binddn   = "uid=$username,ou=people,dc=192.168.17.181,dc=com"; 
   $ldapbind = ldap_bind($ldapConnect);    // 匿名的 bind,爲只讀屬性


  if($ldapbind)
  { 
        echo "login" ; 

          $sr=ldap_search($ldapConnect,"dc=".LDAP_SERVER_IP, "sn=l*");  
          print_r($sr);
  } 
  else 
  {
   echo " not login"; 
  } 

}


// 關閉鏈接
 ldap_close($ldapConnect);

5、遇到的坑

clipboard.png
擦,出現這樣的問題:

Warning: ldap_bind(): Unable to bind to server: Invalid credentials in D:\xampps\htdocs\xampps\web\ldap\index.php on line 40

使用命令在服務器端添加條目:

[root@openldap openldap]# ldapadd -x -D "cn=Chow,dc=baidu,dc=com" -W -f user.ldif
Enter LDAP Password: 
ldap_bind: Invalid credentials (49)

OpenLDAP 服務出現這樣的問題,什麼緣由呢?

折騰了很久,原來是本身的ldap的服務器域名沒有設置:

先獲取ldap服務器的IP地址:

# ifconfig
192.168.17.83
# vim hostname

baidu.com

而後再配置文件中進行相應的修改。

6、phpldapadmin

clipboard.png

7、ldap的相關增刪改查

<?php

define('LDAP_SERVER_IP', '192.168.1.1');
define('LDAP_SERVER_PORT', 389);

// 創建到ldap服務器的鏈接LDAP_SERVER_IP是ldap服務器ip,LDAP_SERVER_PORT是ldap服務器端口(默認389) 
$ldapConnect = ldap_connect(LDAP_SERVER_IP, LDAP_SERVER_PORT) or die("Could not connect to " . LDAP_SERVER_IP); 

ldap_set_option($ldapConnect, LDAP_OPT_PROTOCOL_VERSION,3) or die("Could not set ldap protocol version");


// ================= 添加people 組=====================
/*
$new_dn = "ou=People,dc=baidu,dc=com";
$ldaprecord['ou'] = "People";
$ldaprecord['objectclass'][0] = "top";
$ldaprecord['objectclass'][1] = "organizationalUnit";
*/
// ================= 添加people 組=====================
// 

if ($ldapConnect)
{ 
  
   $upasswd    = "123456"; 
   $base       = "dc=baidu,dc=com";
   $new_binddn = "cn=root,dc=baidu,dc=com";


  $ldapbind = ldap_bind($ldapConnect, $new_binddn, $upasswd) or die("bind fail");    // 匿名的 bind,爲只讀屬性


$admin_users = array(
 array("user_name" => "張雪玉", "pinyin" => "zhangxueyu", "pwd" => "b3be5dc2e108236561fd120f6e4c654c"),
 array("user_name" => "張學友", "pinyin" => "zhangxueyou", "pwd" => "eadd934e2cc978f23654fdsadffdfdaf"),

);


  // 公共屬性
  $new_dn = "ou=people,dc=baidu,dc=com";
  $ldaprecord['objectclass'][0] = "top";
  $ldaprecord['objectclass'][1] = "posixAccount";
  $ldaprecord['objectclass'][2] = "inetOrgPerson";
  $ldaprecord['gidNumber'] = "200";
  $ldaprecord['uidNumber'] = "3";
    

foreach($admin_users as $k => $v)
{
  $name   = $v['user_name'];
  $uid    = base64_encode($name);
  $pinyin = $v['pinyin'];
  $pwd    = $v['pwd'];

  // 添加屬性
  $ldaprecord['cn'] = $pinyin;
  $ldaprecord['sn'] = $pinyin;
  $ldaprecord['displayName'] = $name; 
  $ldaprecord['uid'] = $uid;
  $ldaprecord['userpassword'] = $pwd;
  $ldaprecord['homeDirectory'] = "/home/users/{$pinyin}";

  $good_new_dn = "uid={$uid},{$new_dn}";

  ldap_add($ldapConnect, $good_new_dn, $ldaprecord) or die( "Can’t add new dn!" );

}

 

   // 添加

     if($ldapbind)
    { 
      echo "login" ; 

     //  $sr=ldap_search($ldapConnect, $base, 'cn=wang*');  
     //  $ret = ldap_get_entries($ldapConnect, $sr);
      $sr=ldap_search($ldapConnect, $base, "(ObjectClass=*)");  
      $ret = ldap_get_entries($ldapConnect, $sr);
      $pwd = $ret[0]['userpassword'][0];
      print_r($ret);
    } 
    else 
    {
     echo " not login"; 
    } 

}

// 刪除
 $del_dn = "uid=xiaoming,ou=People,dc=baidu,dc=com";
// $res = ldap_delete($ldapConnect, $del_dn) or die( "Can’t delete dn!" );

if($res)
{
  echo 'delete success!';

}


// 更新
$update_dn = "uid=corwien,ou=People,dc=baidu,dc=com";
$update_entry = array( "userpassword"=>"10086");
// $res = ldap_mod_replace($ldapConnect, $update_dn, $update_entry) or die( "Can’t update  dn!" );
if($res)
{
  echo 'update success!';

}

// 關閉鏈接
 ldap_close($ldapConnect);

php LDAP簡介
LDAP服務器的概念和原理簡單介紹
LDAP環境搭建 OpenLDAP和phpLDAPadmin -- yum版
LDAP目錄服務折騰以後的總結
LDAP 中 CN, OU, DC 的含義
OpenLDAP(2.4.3x)服務器搭建及配置說明
LDAP經常使用命令解析
OpenLDAP編譯安裝及配置
LDAP的相關概念與objectClass介紹
LDAP基礎概念

相關文章
相關標籤/搜索