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