LDAP研究

一、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.数据同步与复制配置

主服务器配置这项

overlay syncprov

syncprov-nopresent TRUE

syncprov-reloadhint TRUE

从服务器配置 这项

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的作用功能都有。

时间: 2024-10-18 21:59:31

LDAP研究的相关文章

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

前有Mimikatz,今有mimipenguin,近日国外安全研究员huntergregal发布了工具mimipenguin,一款Linux下的密码抓取神器,可以说弥补了Linux下密码抓取的空缺. 详情通过转储过程和提取那些包含明文密码可能性很高的行(hang),充分利用内存中的明文凭证.通过检查/etc/shadow文件hash,内存中的hash和正则匹配去尝试计算出每个单词的概率 要求root权限 已支持(以下环境已通过测试)Kali 4.3.0 (rolling) x64 (gdm3)U

ldap的详细介绍,搭建,配置管理,备份,案例

Ldap  服务应用指南 兼容(5.X&6.X) 1.1  Ldap 目录服务介绍 1.1.1 什么是目录服务(active directory)?? 目录是一类为了浏览和搜索数据为设计的特殊的数据库,目录服务是按照树状存储信息的 目录进行更新的操作,可以说是要么全部,要么都不得原子性操作 目录不支持大多数事物型数据库所支持的高吞吐量和复杂的更新操作,适应于大量的查询和搜索操作,为了保证数据的可靠性和可用性,他也有主从服务器同步数据信息能力. ldap 也可以一主多从. ldap 可以说是活动目

LDAP开发小结

写在前面 由于最近的一个项目的需求是要是需要读取AD域里面的一些数据,然后保存到数据库中,所以对LDAP这个东西进行了一些研究. 感谢以下链接提供的资料 : http://wibiline.iteye.com/blog/1840739 http://aa00aa00.iteye.com/blog/1276936 http://www.cnblogs.com/forbreak/archive/2012/10/30/2746464.html http://cgs1999.iteye.com/blog

OpenLDAP使用疑惑解答及使用Java完成LDAP身份认证

导读 LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务.目录服务是一种特殊的数据库系统,其专门针对读取,浏览和搜索操作进行了特定的优化.目录一般用来包含描述性的,基于属性的信息并支持精细复杂的过滤能力.目录一般不支持通用数据库针对大量更新操作操作需要的复杂的事务管理或回卷策略.而目录服务的更新则一般都非常简单.这种目录可以存储包括个人信息.web链结.jpeg图像等各种信息.为了访问存储在目录中的信息,就

ldap配置记录

记录一下最近研究ldap+nfs的情况 ldap这个东西上次研究nis的时候就有人说那是上个世纪的老东西了,不应该继续使用.虽然意识到如此但时间不够还是使用了nis,这次乘着重做就干脆切换到ldap,可这次相当不顺利,折腾了一个星期左右,现在总算折腾好了,中间被坑了无数次,记录一下以备下次继续参考吧. 关防火墙,关防火墙,关防火墙 没想到这次又被这个大坑害了一把,因为用的是redhat7.0, 所以每次安装之后都是直接service iptables off, 一看提示没有就大意了,没把防火墙作

LDAP与数据库的比较

一 LDAP 概念 LDAP(Lightweight Directory Access Protocol),轻量级目录访问协议.它是目录访问协议一个标准.它是基于X.500 标准的,可以根据需要定制.轻量级目录访问协议以信息目录的形式存在,在该目录中可只定义一次用户和组,而在多台机器和多个应用程序间共享它们.[1] LDAP 定义与目录服务进行通信所使用的操作,如何找到目录中的实体,如何描述实体属性,以及许多安全特性.这些安全特性可用于对目录进行身份验证,控制对目录中的实体的访问. LDAP 标

LDAP认证客户端、自动挂载用户家目录shell脚本配置

这个是LDAP认证客户端与自动挂载家目录shell脚本配置,使用"authconfig-tui"图形化配置简单,但是后面需要手动操作,自动写入配置文件还没有研究透彻.以后完善 #!/bin/bash yum install -y nss-pam-ldapd nfs-utils nfs autofs pam_ldap openldap openldap-clients #showmount -e 172.16.16.22 automaster="/etc/auto.master

Python实现LDAP用户名密码验证

网上借鉴了不少东西,下面是python代码,备份后用. 思路,因为每个用户的组都不一样,这样就导致了dn不一致的情况, 据需要先根据用户名获取该用户的dn,然后再bind用户名和密码进行验证. 反正是实现了,至于方式对不对后续再研究了. 机器上要先安装python-ldap包 1 #coding: utf-8 2 import ldap 3 ''' 4 实现LDAP用户登录验证,首先获取用户的dn,然后再验证用户名和密码 5 ''' 6 7 ldappath = "ldap://xxxx&quo

Windows 下搭建LDAP服务器

五一闲来没事,加上项目正在进行UAT.抽空研究了一下LDAP相关知识.随手做一个记录. 为了方便阅读还是先介绍一下什么是LDAP? 前言.Lightweight Directory Access Protocol: The Lightweight Directory Access Protocol , or LDAP ,is an application protocol for querying and modifying directory services running over TCP