前言
公司管理员工信息以及组织架构的后台系统要和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/
本文版权归本人和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。