由于项目需要实现SSO单点登录的功能,所以,这里借用LDAP实现,LDAP的优点是不使用数据库就可在服务器建立一种权限关系。
一、LDAP简介
LDAP
的全称是“轻量级目录访问协议 (Lightweight Directory Access Protocol)”,是一种简单的目录协议。所谓目录,是一种专门的数据库,可以用来服务于任何应用程序。公司的域帐号登录采用的是Ldap登录验证,所有的系统均使用来自同一个 LDAP 目录的用户信息进行身验证。这样,就不需要在每个系统中保存不同的密码,只需要在 LDAP 目录中保存一个密码即可。本文主要介绍一下PHP环境下如何通过后台登录公司Ldap服务器验证用户名密码。
二、LDAP目录树的结构
LDAP目录以树状的层次结构来存储数据。如果你对自顶向下的DNS树或UNIX文件的目录树比较熟悉,也就很容易掌握LDAP目录树这个概念了。就象DNS的主机名那样,LDAP目录记录的标识名
(Distinguished Name,简称DN)是用来读取单个记录,以及回溯到树的顶部。
1. 基准DN
DN:标识名,简称DN (Distinguished Name,简称DN)
是用来读取单个记录,以及回溯到树的顶部。
这种格式很直观,用公司的域名作为基准DN。这也是现在最常用的格式。
dc=foobar, dc=com
(用DNS域名的不同部分组成的基准DN)
DC=Domain Component
为用户名或服务器名,最长可以到80个字符,可以为中文;CN=Common Name
为用户名或服务器名,最长可以到80个字符,可以为中文;OU=Organizational Unit
为组织单元,最多可以有四级,每级最长32个字符,可以为中文;O=Organization
为组织名
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 目录类似于文件系统目录。
下列目录:
DC=redmond,DC=wa,DC=microsoft,DC=com
如果我们类比文件系统的话,可被看作如下文件路径:
Com\Microsoft\Wa\Redmond
例如:
CN=test,OU=developer,DC=domainname,DC=com
在上面的代码中 cn=test 可能代表一个用户名,ou=developer 代表一个 active directory 中的组织单位。这句话的含义可能就是说明 test 这个对象处在domainname.com 域的 developer 组织单元中。
三、安装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
四、使用
<?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);
五、遇到的坑
擦,出现这样的问题:
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
然后再配置文件中进行相应的修改。
六、phpldapadmin
七、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基础概念
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。