一、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. HDU 1498 50 years, 50 colors

    题目大意:给你一个 n*n 的矩阵,每个格子上对应着相应颜色的气球,每次你可以选择一行或一列的同种颜色的气球进行踩破,问你在K次这样的操作后,哪些颜色的气球是不可能被踩破完的. 题解:对于每一种颜色建 ...

  2. JAVA GUI学习 - JList列表、JScrollPane滚动条组件学习

    /** * 本例结合JList和JScrollPane共同使用 * @author Wfei * */ public class JListKnow extends JFrame { JList jL ...

  3. Node.cluster

    nodejs是一个单进程单线程的引擎,只能利用到单个cpu进行计算,面对当今服务器性能的提高,cpu的利用率显然对node应有的性能大打折扣,面对这个问题,cluster应运而生. cluster介绍 ...

  4. 2014-CVTE网测部分软件技术测试题及答案

    1.叉树的先序遍历序列和后序遍历序列正好相反,则该二叉树满足的条件是(D) A.空或只有一个结点 B.高度等于其结点数 C.该二叉树是完全二叉树 D.所有结点无右孩子 应该是二叉树的每个结点都只有一个 ...

  5. sass基本语法

    sass是一种基于ruby语言开发的CSS预处理器.它可以使用变量,嵌套,混入,继承,运算,函数等编程语言具有的特性进行CSS的开发,使得CSS的开发变得简单粗暴清晰可维护. sass有两种后缀文件格 ...

  6. [置顶] 浅谈大型web系统架构

    转载原文:http://blog.csdn.net/dinglang_2009/article/details/6863697 分类: 大规模Web 2.0架构 2011-10-11 18:27 12 ...

  7. 在 Windows系统中编译node.js 源代码

    Node.js 在 Windows 下只能通过 Microsoft Visual Studio 编译,因此你需要首先安装 Visual Studio 或者免费的 Visual Studio Expre ...

  8. C#中泛型、程序集一些基本运用(Fifteenth Day)

    今天主要在学习了泛型和程序集以及一些细碎的知识的运用.下面我就把今天所学的总结一下. 理论: 泛型: * 英文名字是Generic,可以让多个类型共享一组代码,泛型允许我们声明类型参数化,可以用不同的 ...

  9. 数据完整性(Data Integrity)笔记

    因数据库存储数据要持之以恒,数据库中的表需要一些方法验证各种数据类型.不仅仅局限于数据类型,还有唯一值,值的范围,或者某列的值和另外一个表中的列匹配. 当你在定义表的时候其用这些数据验证方法.这叫做声 ...

  10. BZOJ 1617: [Usaco2008 Mar]River Crossing渡河问题( dp )

    dp[ i ] = max( dp[ j ] + sum( M_1 ~ M_( i - j ) ) + M , sum( M_1 ~ M_i ) ) ( 1 <= j < i )  表示运 ...