前言
公司管理員工信息以及組織架構的後臺系統要和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 <= $_Num ) break ; } 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.創建證書
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.檢測
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/
本文版權歸本人和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。