一、ldap介绍

ldap是轻量级的文件夹訪问协议。重点是文件夹訪问协议。更为重点的是协议。好吧他是一个协议。也就是一个标准。

那么实现这款协议的软件当中有一款就是openldap.

二、安装windows版本号的openldap

下载好windows版的openldap,一路下一步完毕安装。

重点在安装根文件夹里也就是%OpenLDAP%以下的slapd.conf文件

1. 默认的域名或者组织机构  找到以下的代码配置

suffix "dc=tcl,dc=com"

rootdn "cn=Manager,dc=tcl,dc=com"

rootpw 123456

2. 訪问控制acl  access开头的配置   这是訪问权限配置

3.数据同步与复制配置

主server配置这项

overlay syncprov

 syncprov-nopresent TRUE

 syncprov-reloadhint TRUE

从server配置 这项

syncrepl  rid=0

               provider=ldap://ldapmaster.symas.com:389

               bindmethod=simple

               binddn="cn=replicator,dc=symas,dc=com"

               credentials=secret

               searchbase="dc=symas,dc=com"

               logbase="cn=accesslog"

               logfilter="(&(objectClass=auditWriteObject)(reqResult=0))"

               schemachecking=on

               type=refreshAndPersist

               retry="60 +"

               syncdata=accesslog

4.注意启动方式

我下载的是2.4.39

启动命令在 %OpenLDAP%run 文件夹下的命令行

三、java调用

1.spring配置

	<bean id="ldapSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://Dh-THINK:389" />
<property name="base" value="DC=tcl,DC=com" />
<property name="userDn" value="cn=manager,DC=tcl,DC=com" />
<property name="password" value="123456" />
</bean> <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="ldapSource" />
</bean>

2.pom配置

<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>2.0.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</exclusion>
</exclusions>
</dependency>

由于springmvc 所以包冲突,要排包。

3.增删改查操作

	@Override
public int CreatePerson(String dn, Person person) {
try {
//dn不包含spring中配置的域名
ldapTemplate.bind(dn, null, buildAttributes(person));
return 0;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
	/**
* 构造人员属性
* @param person
* @return
*/
private Attributes buildAttributes(Person person) {
BasicAttribute ba = new BasicAttribute("objectclass");
ba.add("top"); //此处的person相应的是core.schema文件里的objectClass:person
ba.add("person"); //此处的person相应的是core.schema文件里的objectClass:person
Attributes attr = new BasicAttributes();
attr.put(ba); attr.put("cn", person.getCn());
attr.put("sn", person.getSn());
if(person.getTelephoneNumber()!=null&&!"".equals(person.getTelephoneNumber())){
attr.put("telephoneNumber", person.getTelephoneNumber());
}
if(person.getUserPassword()!=null&&!"".equals(person.getUserPassword())){
attr.put("userPassword", person.getUserPassword());
}
if(person.getDescription()!=null&&!"".equals(person.getDescription())){
attr.put("description", person.getDescription());
}
if(person.getSeeAlso()!=null&&!"".equals(person.getSeeAlso())){
// attr.put("seeAlso", person.getSeeAlso());
}
return attr;
}
	@Override
public int UpdatePerson(String dn, Person person) {
try {
ldapTemplate.rebind(dn, null, buildAttributes(person));
return 0;
} catch (Exception e) {
return -1;
}
}
	@Override
public int deletePerson(String dn, Person person) {
try {
ldapTemplate.unbind(dn);
return 0;
} catch (Exception e) {
return -1;
}
}
	@Override
public List<Person> findByOrganization(String oganizationName) {
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "person"));
ContextMapper person = new PersonAttributesMapper();
return ldapTemplate.search( "o="+oganizationName, filter.encode(),person);
}
	@Override
public List findOrganizationAndPerson(String dn) {
// Object object = ldapTemplate.lookup("o=product", new AttributesMapper() { public Object mapFromAttributes(Attributes attrs)throws NamingException{
// return attrs.toString();}});
OrFilter filter = new OrFilter();
filter.or(new LikeFilter("objectclass", "organizationalUnit"));
// filter.or(new LikeFilter("objectclass", "top"));
filter.or(new LikeFilter("objectclass", "organization"));
// filter.or(new LikeFilter("objectclass", "person"));
ContextMapper organizationUnit = new OrganizationUnitAttributesMapper();
return ldapTemplate.search( dn, filter.encode(), new ContextMapper() { @Override
public Object mapFromContext(Object ctx) throws NamingException {
DirContextAdapter context = (DirContextAdapter)ctx;
return context;
} });
}
	@Override
public List<Person> findPersonListByDn(String dn) {
OrFilter filter = new OrFilter();
filter.or(new LikeFilter("objectclass", "person"));
return ldapTemplate.search( dn, filter.encode(), new PersonAttributesMapper());
}
public class PersonAttributesMapper implements ContextMapper<Person> {

	@Override
public Person mapFromContext(Object ctx) throws NamingException {
DirContextAdapter context = (DirContextAdapter)ctx;
Person person = new Person();
person.setCn(context.getStringAttribute("cn"));
person.setSn(context.getStringAttribute("sn"));
person.setUserPassword(context.getStringAttribute("userPassword"));
person.setDescription(context.getStringAttribute("description"));
person.setSeeAlso(context.getStringAttribute("seeAlso"));
person.setTelephoneNumber(context.getStringAttribute("telephoneNumber"));
return person;
} }

接下来介绍一个解析树的递归算法,输入全部的机构人员信息,解析出树状的机构层次

	public JSONArray bulidTree(String dn){
JSONArray jsonArray = new JSONArray();
List<DirContextAdapter> list = ldapUtil.findOrganizationAndPerson(dn);
String[] theDnArray = dn.split("=|,");
for (DirContextAdapter ctx : list) {
JSONObject json = new JSONObject();
String dns = ctx.getDn().toString();
String[] dnArray = dns.split("=|,");
if(dnArray.length==theDnArray.length){
json.put("id", dns);
if("".endsWith(dnArray[0])){
json.put("text", ctx.getStringAttribute("dc"));
}else{
json.put("text", ctx.getStringAttribute(dnArray[0]));
}
json.put("children", findChirld(dns));
jsonArray.add(json);
}else{ }
}
return jsonArray;
}
public JSONArray findChirld(String dn){
JSONArray jsonArray = new JSONArray();
List<DirContextAdapter> list = ldapUtil.findOrganizationAndPerson(dn);
String[] theDnArray = dn.split("=|,");
for (DirContextAdapter ctx : list) {
JSONObject json = new JSONObject();
String dns = ctx.getDn().toString();
String[] dnArray = dns.split("=|,");
if(dnArray.length-theDnArray.length==2||dnArray.length-theDnArray.length==1){
json.put("id", dns);
json.put("text", ctx.getStringAttribute(dnArray[0]));
json.put("children", findChirld(dns));
jsonArray.add(json);
}
}
return jsonArray;
}

接下来前台採用jquery easyUI做的增删改查

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ldap</title>
<link rel="stylesheet" type="text/css" href="<c:url value="/resources/jquery-easyui-1.4/themes/default/easyui.css"/>">
<link rel="stylesheet" type="text/css" href="<c:url value="/resources/jquery-easyui-1.4/themes/icon.css"/>">
<link rel="stylesheet" type="text/css" href="<c:url value="/resources/jquery-easyui-1.4/demo.css"/>">
<title>ldapTest</title>
<style>
body{ margin:0; height:100%}
html{ height:100%} /*兼容firefox的div高度100%*/
#left{ position:absolute; top:0; left:0; width:200px; height:100%; background-color:#98f5ff;border-style: inset groove; border-width: 5px;}
#right{ margin-left:200px; height:100%; background-color:#fffaf0;border-style: outset; border-width: 5px;}
</style>
</head>
<body>
<script type="text/javascript" src="<c:url value="/resources/jquery-easyui-1.4/jquery.min.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/jquery-easyui-1.4/jquery.easyui.min.js"/>"></script>
<div id="left" >
<button id="btnAddOrganization">加入组织</button>
<button id="btnAddOrganizationUnit">加入小组</button>
<ul class="easyui-tree" id="ldapTree" >
</ul></div>
<div id="right">
<button id="btnAddPerson">加入人员</button>
<table class="easyui-datagrid" style="width:600px;" title="ldap-person" id="personTable">
</table>
<div id="win" class="easyui-window" title="加入人员" style="width:600px;height:400px"
data-options="modal:true" >
<form id="personForm" method="post">
<input type="hidden" id="dn" name="dn">
<table cellpadding="4">
<tr>
<td>名字:</td>
<td><input class="easyui-textbox" type="text" name="cn" data-options="required:true"></input></td>
</tr>
<tr>
<td>姓氏:</td>
<td><input class="easyui-textbox" type="text" name="sn" data-options="required:true"></input></td>
</tr>
<tr>
<td>手机号码:</td>
<td><input class="easyui-textbox" type="text" name="telephoneNumber" data-options="validType:'number'"></input></td>
</tr>
<tr>
<td>描写叙述:</td>
<td><input class="easyui-textbox" name="description" data-options="multiline:true" style="height:60px"></input></td>
</tr>
<tr>
<td>其它:</td>
<td><input class="easyui-textbox" name="seeAlso" data-options="multiline:true" style="height:60px"></input></td>
</tr>
<tr>
<td colspan="2"> <span id="warming"></span></td>
</tr>
</table>
</form>
<div style="text-align:center;padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm()">重置</a>
</div>
</div>
<div id="winOrganization" class="easyui-window" title="加入组织" style="width:600px;height:400px"
data-options="modal:true" >
<form id="organizationForm" method="post">
<input type="hidden" id="dnOrganization" name="dn">
<table cellpadding="4">
<tr>
<td>机构名称:</td>
<td><input class="easyui-textbox" type="text" name="o" data-options="required:true"></input></td>
</tr>
<tr>
<td>业务编码:</td>
<td><input class="easyui-textbox" type="text" name="businessCatagory" ></input></td>
</tr>
<tr>
<td>联系电话:</td>
<td><input class="easyui-textbox" type="text" name="telephoneNumber" data-options="validType:'number'"></input></td>
</tr>
<tr>
<td>地址:</td>
<td><input class="easyui-textbox" name="streetAdress" data-options="multiline:true" style="height:60px"></input></td>
</tr>
<tr>
<td>其它:</td>
<td><input class="easyui-textbox" name="seeAlso" data-options="multiline:true" style="height:60px"></input></td>
</tr>
<tr>
<td colspan="2"> <span id="OrganizationWarming"></span></td>
</tr>
</table>
</form>
<div style="text-align:center;padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitOrganizationForm()">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearOrganizationForm()">重置</a>
</div>
</div>
<div id="winOrganizationUnit" class="easyui-window" title="加入小组" style="width:600px;height:400px"
data-options="modal:true" >
<form id="organizationUnitForm" method="post">
<input type="hidden" id="dnOrganizationUnit" name="dn">
<table cellpadding="4">
<tr>
<td>小组名称:</td>
<td><input class="easyui-textbox" type="text" name="o" data-options="required:true"></input></td>
</tr>
<tr>
<td>业务编码:</td>
<td><input class="easyui-textbox" type="text" name="businessCatagory" ></input></td>
</tr>
<tr>
<td>联系电话:</td>
<td><input class="easyui-textbox" type="text" name="telephoneNumber" data-options="validType:'number'"></input></td>
</tr>
<tr>
<td>地址:</td>
<td><input class="easyui-textbox" name="streetAdress" data-options="multiline:true" style="height:60px"></input></td>
</tr>
<tr>
<td>其它:</td>
<td><input class="easyui-textbox" name="seeAlso" data-options="multiline:true" style="height:60px"></input></td>
</tr>
<tr>
<td colspan="2"> <span id="OrganizationUnitWarming"></span></td>
</tr>
</table>
</form>
<div style="text-align:center;padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitOrganizationUnitForm()">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearOrganizationUnitForm()">重置</a>
</div>
</div>
</div>
<script>
function submitForm(){
$('#personForm').form('submit');
}
function clearForm(){
$('#personForm').form('clear');
}
function submitOrganizationForm(){
$('#organizationForm').form('submit');
}
function clearOrganizationForm(){
$('#organizationForm').form('clear');
}
function submitOrganizationUnitForm(){
$('#organizationUnitForm').form('submit');
}
function clearOrganizationUnitForm(){
$('#organizationUnitForm').form('clear');
}
$(document).ready(function() {
$("#ldapFormDiv").hide();
$("#win").window('close');
$("#winOrganization").window('close');
$("#winOrganizationUnit").window('close');
$('#ldapTree').tree({
url:'http://localhost:8080/spring-mvc-showcase/simple',
onClick:function(node){
$('#personTable').datagrid('reload','http://localhost:8080/spring-mvc-showcase/loadPerson/dn='+node.id);
$("#dn").val(node.id);
$("#dnOrganization").val(node.id);
$("#dnOrganizationUnit").val(node.id);
}
});
$('#personTable').datagrid({
url : 'http://localhost:8080/spring-mvc-showcase/loadPerson/dn=o=product',
pagination:true ,
rownumbers:true,
collapsible:true,
singleSelect:true,
columns:[[
{field:'cn',title:'name',width:100},
{field:'sn',title:'sn',width:100},
{field:'telephoneNumber',title:'telephone',width:100}
]]
});
$('#personForm').form({
url:"http://localhost:8080/spring-mvc-showcase/submitPerson",
onSubmit: function(){
if(""==$("#dn").val()){
$("#warming").html("<font color='red'>请选择机构</font>");
return false;
}
$("#warming").html("");
return true;
},
success:function(data){
$("#win").window('close');
$('#personTable').datagrid('reload','http://localhost:8080/spring-mvc-showcase/loadPerson/dn='+data);
}
});
$('#organizationForm').form({
url:"http://localhost:8080/spring-mvc-showcase/submitOrganization",
onSubmit: function(){
return true;
},
success:function(data){
$("#winOrganization").window('close');
$('#ldapTree').tree('reload');
}
});
$('#organizationUnitForm').form({
url:"http://localhost:8080/spring-mvc-showcase/submitOrganizationUnit",
onSubmit: function(){
return true;
},
success:function(data){
$("#winOrganizationUnit").window('close');
$('#ldapTree').tree('reload');
}
});
$("#btnAddPerson").click(function(){
$("#win").window('open');
});
$("#btnAddOrganization").click(function(){
$("#winOrganization").window('open');
});
$("#btnAddOrganizationUnit").click(function(){
$("#winOrganizationUnit").window('open');
});
});
</script>
</body>
</html>

附件是maven项目   下载后想执行须要配置maven库  该项目是在pringmvc-showcase的基础上做的。全部springmvc-showcase的作用功能都有。

LDAP研究的更多相关文章

  1. 转: LDAP有啥子用? 用户认证

    认证的烦恼 小明的公司有很多IT系统, 比如邮箱.SVN.Jenkins , JIRA,VPN, WIFI...... 等等 . 新人入职时需要在每个系统中申请一遍账号,每个系统对用户名和密码的要求还 ...

  2. RFC(请求注解)--各种协议-标准

    转自:http://blog.sina.com.cn/s/blog_65d6476a0101cj8n.html RFC(Request For Comments)-意即“请求注解”,包含了关于Inte ...

  3. ★RFC标准库_目录链接

    RFC(Request For Comments)是一个国际标准化的数据库,记录了从计算机到互联网的海量标准协议.它是一个免费公开的IT标准文件分享平台,其内容也在不断增长,与时俱进.它与ISO等组织 ...

  4. ★RFC标准库_目录链接

    RFC(Request For Comments)是一个国际标准化的数据库,记录了从计算机到互联网的海量标准协议.它是一个免费公开的IT标准文件分享平台,其内容也在不断增长,与时俱进.它与ISO等组织 ...

  5. [转]抓取当前登录用户登录密码的工具:mimipenguin

    Github项目地址 前有Mimikatz,今有mimipenguin,近日国外安全研究员huntergregal发布了工具mimipenguin,一款Linux下的密码抓取神器,可以说弥补了Linu ...

  6. Linux下抓取登陆用户密码神器mimipenguin

    windows下有Mimikatz,现在linux下有了mimipenguin,国外安全研究员huntergregal发布了工具mimipenguin,一款Linux下的密码抓取神器,弥补了Linux ...

  7. INUX下抓取当前登录用户登录密码的工具:mimipenguin

    前有Mimikatz,今有mimipenguin,近日国外安全研究员huntergregal发布了工具mimipenguin,一款Linux下的密码抓取神器,可以说弥补了Linux下密码抓取的空缺. ...

  8. Linux下基于LDAP统一用户认证的研究

    Linux下基于LDAP统一用户认证的研究                   本文出自 "李晨光原创技术博客" 博客,谢绝转载!

  9. LDAP注入与防御解析

    [目录] 0x1 LDAP介绍 0x2 LDAP注入攻击及防御 0x3 参考资料 0x1 LDAP介绍 1 LDAP出现的背景 LDAP(Lightweight Directory Access Pr ...

随机推荐

  1. perl5 附录一 函数集(未定稿)

    附录一 函数集(未定稿) by flamephoenix 一.进程处理函数  1.进程启动函数  2.进程终止函数  3.进程控制函数  4.其它控制函数二.数学函数三.字符串处理函数四.标量转换函数 ...

  2. git 无法添加文件夹下文件

    最近做项目时,发现无法提交某个子文件夹下的文件. google后发现可能是该子文件夹下有.git文件夹导致无法上传. 删除子文件夹下.git后,依然无法提交子文件夹下的文件. 继续google, 尝试 ...

  3. 利用UICollectionView实现瀑布流

    利用UICollectionView实现瀑布流通过自定义布局来实现. - 自定义类继承UICollectionViewLayout: 必须重写的方法有: //决定每个item的位置: - (nulla ...

  4. 「OC」 多态

    一.基本概念 多态在代码中的体现,即为某一类事物的多种形态,OC对象具有多态性.必须要有继承,没有继承就没有多态. 在使用多态时,会进行动态检测,以调用真实的对象方法. 多态在代码中的体现即父类指针指 ...

  5. CentOS环境下R语言的安装和配置

    最近在看数据统计和分析,想到了R语言,于是就着手在自己的CentOS环境下进行安装和配置.步骤如下: 1.前往R官网下载安装包. 2.解压压缩包:tar xvzf R-3.2.2.tar.gz 3.进 ...

  6. 新发现的mbstowcs, mbstowcs_s函数,转换多字节到宽字符

    http://en.cppreference.com/w/c/string/multibyte/mbstowcs https://msdn.microsoft.com/fr-fr/library/ey ...

  7. AnsiString 在 Delphi 中虽然不可用,但是,在 C++ 中可以用

    [C++] C++ Builder 中 Ansi 编码的字符串在Android/iOS程序中显示的问题 呃,这个问题说起来,其实也不麻烦,C++ Builder 本身在 TEncoding 做了处理, ...

  8. Windows Phone 8本地化多语言支持

    原文 Windows Phone 8本地化多语言支持 在WP8平台处理本地化多语言的支持还是比较容易的,大部分工作都有VS IDE处理,开发者只需简单操作,并翻译本地资源即可实现. 无论您目前的应用是 ...

  9. AseoZdpAseo.init(this, AseoZdpAseo.INSERT_TYPE);

    让以后的人知道吧,这就是一个广告包,相当于广告插件.

  10. 解读Google分布式锁服务

    解读Google分布式锁服务  背景介绍 在2010年4月,Google的网页索引更新实现了实时更新,在今年的OSDI大会上,Google首次公布了有关这一技术的论文. 在此之前,Google的索引更 ...