LDAP目錄服務折騰之後的總結

前言

公司管理員工信息以及組織架構的後臺系統要和Active Directory目錄服務系統打通,後臺系統使用PHP開發,

折騰了二十多天,終於上線了,期間碰到過各種疑難問題,不過總算在GOOGLE大叔的幫忙下還有運維部AD管理員的幫助下解決了。

LDAP協議定義

LDAP(Lightweight Directory Access Protocol)輕量目錄訪問協議,定義了目錄服務實現以及訪問規範。

目錄定義

A directory is a specialized database specifically designed for searching and browsing, 
in additional to supporting basic lookup and update functions.

LDAP協議實現

0.基於TCP/IP的應用層協議 默認端口389 加密端口636
1.客戶端發送命令,服務器端響應
2.目錄主要操作
    2.0 用戶驗證(bind操作)
     2.1 添加節點
     2.2 更新節點
     2.3 移動節點
     2.4 刪除節點
     2.5 節點搜索
3.節點類型
    3.0 節點屬性規範(SCHEMA)
4.節點
    4.0 目錄裏的對象
     4.1 屬性即是節點的數據
     4.2 目錄中通過DN(Distinguished Name)唯一標識(可以認爲是路徑)
     4.2.0 節點DN = RDN(Relative Distinguished Name) + 父節點的DN
     4.3 目錄是TREE結構,節點可以有子節點,也可以有父節點
5.屬性
    5.0 同一個屬性可以有多個值
     5.1 包含屬性名稱,屬性類型
6.節點唯一標識DN說明
    6.0 示例: dn:CN=John Doe,OU=Texas,DC=example,DC=com
     6.1 從右到左 根節點 -> 子節點
     6.2 DC:所在控制域 OU:組織單元 CN:通用名稱
7.目錄規範(SCHEMA)
    7.0 目錄節點相關規則
     7.1 Attribute Syntaxes
     7.2 Matching Rules
     7.3 Matching Rule Uses
     7.4 Attribute Types
     7.5 Object Classes
     7.6 Name Forms
     7.7 Content Rules
     7.8 Structure Rule

LDAP服務器端的實現

openLDAP,Active Directory(Microsoft)等等,除了實現協議之外的功能,還對它進行了擴展

LDAP應用場景

0.單點登錄(用戶管理)
1.局域網資源統一管理

封裝的簡單PHP類

適合AD服務器 其他的LDAP服務器需要做相應的修改

zend框架有個開源的LDAP庫實現 完全面向對象

 View Code

輔助PHP類---漢字轉拼音

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php
/**
 * @desc 漢字轉拼音 參考 http://www.php100.com/html/webkaifa/PHP/PHP/2012/0820/10914.html
 */
class o_lib_helper_pinyin{
    private $_DataKey = "a|ai|an|ang|ao|ba|bai|ban|bang|bao|bei|ben|beng|bi|bian|biao|bie|bin|bing|bo|bu|ca|cai|can|cang|cao|ce|ceng|cha
        |chai|chan|chang|chao|che|chen|cheng|chi|chong|chou|chu|chuai|chuan|chuang|chui|chun|chuo|ci|cong|cou|cu|
        cuan|cui|cun|cuo|da|dai|dan|dang|dao|de|deng|di|dian|diao|die|ding|diu|dong|dou|du|duan|dui|dun|duo|e|en|er
        |fa|fan|fang|fei|fen|feng|fo|fou|fu|ga|gai|gan|gang|gao|ge|gei|gen|geng|gong|gou|gu|gua|guai|guan|guang|gui
        |gun|guo|ha|hai|han|hang|hao|he|hei|hen|heng|hong|hou|hu|hua|huai|huan|huang|hui|hun|huo|ji|jia|jian|jiang
        |jiao|jie|jin|jing|jiong|jiu|ju|juan|jue|jun|ka|kai|kan|kang|kao|ke|ken|keng|kong|kou|ku|kua|kuai|kuan|kuang
        |kui|kun|kuo|la|lai|lan|lang|lao|le|lei|leng|li|lia|lian|liang|liao|lie|lin|ling|liu|long|lou|lu|lv|luan|lue
        |lun|luo|ma|mai|man|mang|mao|me|mei|men|meng|mi|mian|miao|mie|min|ming|miu|mo|mou|mu|na|nai|nan|nang|nao|ne
        |nei|nen|neng|ni|nian|niang|niao|nie|nin|ning|niu|nong|nu|nv|nuan|nue|nuo|o|ou|pa|pai|pan|pang|pao|pei|pen
        |peng|pi|pian|piao|pie|pin|ping|po|pu|qi|qia|qian|qiang|qiao|qie|qin|qing|qiong|qiu|qu|quan|que|qun|ran|rang
        |rao|re|ren|reng|ri|rong|rou|ru|ruan|rui|run|ruo|sa|sai|san|sang|sao|se|sen|seng|sha|shai|shan|shang|shao|
        she|shen|sheng|shi|shou|shu|shua|shuai|shuan|shuang|shui|shun|shuo|si|song|sou|su|suan|sui|sun|suo|ta|tai|
        tan|tang|tao|te|teng|ti|tian|tiao|tie|ting|tong|tou|tu|tuan|tui|tun|tuo|wa|wai|wan|wang|wei|wen|weng|wo|wu
        |xi|xia|xian|xiang|xiao|xie|xin|xing|xiong|xiu|xu|xuan|xue|xun|ya|yan|yang|yao|ye|yi|yin|ying|yo|yong|you
        |yu|yuan|yue|yun|za|zai|zan|zang|zao|ze|zei|zen|zeng|zha|zhai|zhan|zhang|zhao|zhe|zhen|zheng|zhi|zhong|
        zhou|zhu|zhua|zhuai|zhuan|zhuang|zhui|zhun|zhuo|zi|zong|zou|zu|zuan|zui|zun|zuo";
    private $_DataValue = "-20319|-20317|-20304|-20295|-20292|-20283|-20265|-20257|-20242|-20230|-20051|-20036|-20032|-20026|-20002|-19990
        |-19986|-19982|-19976|-19805|-19784|-19775|-19774|-19763|-19756|-19751|-19746|-19741|-19739|-19728|-19725
        |-19715|-19540|-19531|-19525|-19515|-19500|-19484|-19479|-19467|-19289|-19288|-19281|-19275|-19270|-19263
        |-19261|-19249|-19243|-19242|-19238|-19235|-19227|-19224|-19218|-19212|-19038|-19023|-19018|-19006|-19003
        |-18996|-18977|-18961|-18952|-18783|-18774|-18773|-18763|-18756|-18741|-18735|-18731|-18722|-18710|-18697
        |-18696|-18526|-18518|-18501|-18490|-18478|-18463|-18448|-18447|-18446|-18239|-18237|-18231|-18220|-18211
        |-18201|-18184|-18183|-18181|-18012|-17997|-17988|-17970|-17964|-17961|-17950|-17947|-17931|-17928|-17922
        |-17759|-17752|-17733|-17730|-17721|-17703|-17701|-17697|-17692|-17683|-17676|-17496|-17487|-17482|-17468
        |-17454|-17433|-17427|-17417|-17202|-17185|-16983|-16970|-16942|-16915|-16733|-16708|-16706|-16689|-16664
        |-16657|-16647|-16474|-16470|-16465|-16459|-16452|-16448|-16433|-16429|-16427|-16423|-16419|-16412|-16407
        |-16403|-16401|-16393|-16220|-16216|-16212|-16205|-16202|-16187|-16180|-16171|-16169|-16158|-16155|-15959
        |-15958|-15944|-15933|-15920|-15915|-15903|-15889|-15878|-15707|-15701|-15681|-15667|-15661|-15659|-15652
        |-15640|-15631|-15625|-15454|-15448|-15436|-15435|-15419|-15416|-15408|-15394|-15385|-15377|-15375|-15369
        |-15363|-15362|-15183|-15180|-15165|-15158|-15153|-15150|-15149|-15144|-15143|-15141|-15140|-15139|-15128
        |-15121|-15119|-15117|-15110|-15109|-14941|-14937|-14933|-14930|-14929|-14928|-14926|-14922|-14921|-14914
        |-14908|-14902|-14894|-14889|-14882|-14873|-14871|-14857|-14678|-14674|-14670|-14668|-14663|-14654|-14645
        |-14630|-14594|-14429|-14407|-14399|-14384|-14379|-14368|-14355|-14353|-14345|-14170|-14159|-14151|-14149
        |-14145|-14140|-14137|-14135|-14125|-14123|-14122|-14112|-14109|-14099|-14097|-14094|-14092|-14090|-14087
        |-14083|-13917|-13914|-13910|-13907|-13906|-13905|-13896|-13894|-13878|-13870|-13859|-13847|-13831|-13658
        |-13611|-13601|-13406|-13404|-13400|-13398|-13395|-13391|-13387|-13383|-13367|-13359|-13356|-13343|-13340
        |-13329|-13326|-13318|-13147|-13138|-13120|-13107|-13096|-13095|-13091|-13076|-13068|-13063|-13060|-12888
        |-12875|-12871|-12860|-12858|-12852|-12849|-12838|-12831|-12829|-12812|-12802|-12607|-12597|-12594|-12585
        |-12556|-12359|-12346|-12320|-12300|-12120|-12099|-12089|-12074|-12067|-12058|-12039|-11867|-11861|-11847
        |-11831|-11798|-11781|-11604|-11589|-11536|-11358|-11340|-11339|-11324|-11303|-11097|-11077|-11067|-11055
        |-11052|-11045|-11041|-11038|-11024|-11020|-11019|-11018|-11014|-10838|-10832|-10815|-10800|-10790|-10780
        |-10764|-10587|-10544|-10533|-10519|-10331|-10329|-10328|-10322|-10315|-10309|-10307|-10296|-10281|-10274
        |-10270|-10262|-10260|-10256|-10254";
    private $_Data array();
     
    public function __construct(){
        $_TDataKey explode('|'str_replace(array("\t","\n","\r\n",' '),array('','','',''),$this->_DataKey));
        $_TDataValue explode('|'str_replace(array("\t","\n","\r\n",' '),array('','','',''),$this->_DataValue));
        $_Data = (PHP_VERSION>='5.0') ? array_combine($_TDataKey$_TDataValue) : $this->_Array_Combine($_TDataKey$_TDataValue);
        arsort($_Data);
        $this->_Data = $_Data;
    }
     
    public function Pinyin($_String$_Code='gb2312'){
        reset($this->_Data);
        if($_Code != 'gb2312'$_String $this->_U2_Utf8_Gb($_String);
        $_Res '';$_aRes array();$_en '';
        for($i=0; $i<strlen($_String); $i++)
        {
            $_P = ord(substr($_String$i, 1));
            if($_P < 160){
                $_en .= chr($_P);
                continue;
            }
            if($_en){
                $_aRes[] = $_en;
                $_en '';
            }
            if($_P>160) { $_Q = ord(substr($_String, ++$i, 1)); $_P $_P*256 + $_Q - 65536; }
            //$_Res .= _Pinyin($_P, $_Data);
            $_aRes[] = $this->_Pinyin($_P$this->_Data);
        }
        foreach($_aRes as $k => $v){
            $v = preg_replace("/[^a-zA-Z0-9]*/"''$v);
            $v = ucfirst($v);
            $_aRes[$k] = $v;
        }
        return implode(' ',$_aRes);
        //return preg_replace("/[^a-zA-Z0-9]*/", '', $_Res);
    }
     
    private function _Pinyin($_Num$_Data){
        if ($_Num>0 && $_Num<160 ) return chr($_Num);
        elseif($_Num<-20319 || $_Num>-10247) return '';
        else {
        foreach($_Data as $k=>$v){ if($v<=$_Numbreak; }
        return $k;
        }
    }
     
    private function _U2_Utf8_Gb($_C){
        $_String '';
        if($_C < 0x80) $_String .= $_C;
        elseif($_C < 0x800)
        {
            $_String .= chr(0xC0 | $_C>>6);
            $_String .= chr(0x80 | $_C & 0x3F);
        }elseif($_C < 0x10000){
            $_String .= chr(0xE0 | $_C>>12);
            $_String .= chr(0x80 | $_C>>6 & 0x3F);
            $_String .= chr(0x80 | $_C & 0x3F);
        elseif($_C < 0x200000) {
            $_String .= chr(0xF0 | $_C>>18);
            $_String .= chr(0x80 | $_C>>12 & 0x3F);
            $_String .= chr(0x80 | $_C>>6 & 0x3F);
            $_String .= chr(0x80 | $_C & 0x3F);
        }
        return iconv('UTF-8''GB2312'$_String);
    }
     
    private function _Array_Combine($_Arr1$_Arr2){
        for($i=0; $i<count($_Arr1); $i++) $_Res[$_Arr1[$i]] = $_Arr2[$i];
        return $_Res;
    }
}

輔助PHP類---簡單TREE處理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
/**
 * @description 簡單tree類
 *
 * @author WadeYu
 * @date 2015-04-30
 * @version 0.0.1
 */
class o_simpletree{
    private $_aNodeList array(); // [id => []]
    private $_aChildNodeList array(); // [parentId => [childId,childId,]]
    private $_aTopNodeList array(); //[id => []]
    private $_pk '';
    private $_parentPk '';
    private $_aTreeKV array(); //tree key的顯示的內容
    private $_aJoinKey array();
     
    public function __construct(array $aData array()/*[[id:0,fid:1],[]]*/array $aOption array()){
        $this->_pk = $aOption['pk'];
        $this->_parentPk = $aOption['parentPk'];
        $this->_aTreeKV = (array)$aOption['aTreeKV'];
        $this->_mkNodeList($aData);
        $this->_mkChildNodeList();
    }
     
    public function getTree($parentPk){
        $aRet array();
        $aChild array();
        if (!isset($this->_aChildNodeList[$parentPk])){
            return $aRet;
        }
        $aChild $this->_aChildNodeList[$parentPk];
        foreach((array)$aChild as $k => $v){
            $currNode $this->_aNodeList[$v];
            $tmpK '';
            $i = 0;
            foreach($this->_aTreeKV as $k2 => $v2){
                $tmpV $currNode[$v2];
                if($i == 0){
                    $tmpK .= $tmpV;
                else if ($i == 1){
                    $tmpK .= "({$tmpV})";
                else if ($i == 2){
                    $tmpK .= "[{$tmpV}]";
                }
                $i++;
            }
            if (isset($this->_aChildNodeList[$v])){
                $aRet[$tmpK] = $this->getTree($v);
            else {
                $aRet[$tmpK] = 1;
            }
        }
        return $aRet;
    }
     
    public function joinKey($aTree,$prefix ''){
        $prefix = trim($prefix);
        if(!is_array($aTree)){
            return $prefix;
        }
        foreach((array)$aTree as $k => $v){
            if (is_array($v)){
                $this->joinKey($v,"{$prefix}{$k}/");
            else {
                $this->_aJoinKey["{$prefix}{$k}"] = 1;
            }
        }
        return true;
    }
     
    public function getJoinKey(){
        return $this->_aJoinKey;
    }
     
    private function _mkNodeList(array $aData array()){
        foreach($aData as $k => $v){
            $this->_aNodeList[$v[$this->_pk]] = $v;
        }
    }
     
    private function _mkChildNodeList(){
        foreach($this->_aNodeList as $k => $v){
            if ($v['fid']){
                $this->_aChildNodeList[$v[$this->_parentPk]][] = $v[$this->_pk];
            else {
                $this->_aTopNodeList[$v[$this->_pk]] = $v;
            }
        }
    }
}

  

 

 

LDAP開源實現:openLDAP

0.相關環境說明
    a.操作系統

複製代碼

1 [root@vm ldap]# lsb_release -a2 LSB Version:    :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:graphics-3.1-ia32:graphics-3.1-noarch3 Distributor ID:    CentOS4 Description:    CentOS release 5.4 (Final)5 Release:    5.46 Codename:    Final

複製代碼

 1.安裝

    a.yum -y install openldap-servers openldap-clients

2.配置
    a.配置HOST
        [root@vm ldap]# vi /etc/hosts
       127.0.0.1 test.com
     b.創建證書

+ View Code

   c.生成管理員密碼

            root@vm ~]# slappasswd 

            New password: 
           Re-enter new password: 
          {SSHA}2eG1IBeHhSjfgS7pjoAci1bHz5p4AVeS

    d.配置slapd.conf
        [root@vm certs]# vi /etc/openldap/slapd.conf

       去掉TLS相關注釋

       設置數據庫配置

    e.BerkeleyDb配置

        [root@vm certs]# cd /etc/openldap/
        [root@vm openldap]# mv ./DB_CONFIG.example /var/lib/ldap/DB_CONFIG

    f.配置ldap.conf

        [root@vm openldap]# vi ldap.conf

    g.開啓加密支持
        [root@vm ~]# vim /etc/sysconfig/ldap
        SLAPD_LDAPS=yes

3.使用slapadd命令添加根節點 未啓動前

複製代碼

1 [root@vm ~]# cd ~2 [root@vm ~]# vim root.ldif3 dn: dc=test,dc=com4 dc: test5 objectClass: dcObject6 objectClass: organizationalUnit7 ou: test.com8 [root@vm ~]# slapadd -v -n 1 -l root.ldif

複製代碼

4.啓動slapd
[root@vm ~]# slapd -h "ldap:// ldaps://"
389非加密端口 636加密端口

5.檢測

+ View Code

  

6.phpldapadmin客戶端訪問
    a.官網下載源碼放入WEB目錄下 下載頁面:http://phpldapadmin.sourceforge.net/wiki/index.php/Download
    b.安裝依賴的擴展gettext ldap這2個擴展
    c.按需配置 源碼目錄下config/config.php

問題

1.ldaps無法訪問
/etc/openldap/ldap.conf TLS_REQCERT never加上這個

源碼安裝PHP擴展步驟

1.下載PHP源碼
2.切換到擴展源碼所在目錄 示例:cd /src path/ext/extname
3.執行phpize命令 (1.PHP源代碼或者PHP安裝目錄包含此命令 2.當前目錄會生成一個檢查編譯擴展的環境腳本configure)
4../configure --with-php-config=/usr/local/php/bin/php-config (1.編譯環境配置檢查 2.生成make命令需要的編譯配置文件makefile)
5.make && make install (編譯安裝)
6.php.ini 加上配置 extension = "xxxxx.so"
7.重啓php service php-fpm restart

安裝PHP LDAP擴展

示例:centos系統安裝LDAP擴展
1.安裝依賴庫openldap openldap-devel
yum install openldap 
yum install openldap-devel
2.參考:源碼安裝PHP擴展步驟

 

補充(最新LDAP操作類LARAVEL框架版)

LDAP基礎類

 View Code

組織架構信息更新類

 View Code

 查看客戶端

ApacheDirectoryStudio-win32-x86_64-2.0.0.v20130628

 

參考資料

[1] LDAPV3協議

http://tools.ietf.org/html/rfc4511

[2] LDAP百度百科

http://baike.baidu.com/view/159263.htm

[3] WIKI LDAP

http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol

[4] LDAP Data Interchange Format

http://en.wikipedia.org/wiki/LDAP_Data_Interchange_Format

[5] OpenLDAP介紹

http://en.wikipedia.org/wiki/OpenLDAP

[6] OpenLDAP管理員文檔

[7] Zend LDAP API

http://framework.zend.com/manual/1.11/en/zend.ldap.api.html

[8] BerkeleyDb以及OPENLDAP安裝指南

http://www.openldap.org/lists/openldap-technical/201001/msg00046.html

[9] LDAP環境搭建 OpenLDAP和phpLDAPadmin -- yum版

http://www.cnblogs.com/yafei236/p/4141897.html

[10] phpldapadmin開源項目

http://phpldapadmin.sourceforge.net/wiki/index.php/Main_Page

作者:WadeYu 
出處:http://www.cnblogs.com/wadeyu/ 
本文版權歸本人和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章