导读LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务。目录服务是一种特殊的数据库系统,其专门针对读取,浏览和搜索操作进行了特定的优化。目录一般用来包含描述性的,基于属性的信息并支持精细复杂的过滤能力。目录一般不支持通用数据库针对大量更新操作操作需要的复杂的事务管理或回卷策略。而目录服务的更新则一般都非常简单。这种目录可以存储包括个人信息、web链结、jpeg图像等各种信息。为了访问存储在目录中的信息,就需要使用运行在TCP/IP 之上的访问协议—LDAP。 LDAP目录中的信息是是按照树型结构组织,具体信息存储在条目(entry)的数据结构中。常见的例子是通讯簿,由以字母顺序排列的名字、地址和电话号码组成。 目录服务与关系数据库之间的主要区别在于:二者都允许对存储数据进行访问,只是目录主要用于读取,其查询的效率很高,而关系数据库则是为读写而设计的。也就是目录服务不适于进行频繁的更新,属于典型的分布式结构。 总结:对于查询操作多于更新操作的(认证)系统来说,使用OpenLDAP是一个比关系数据库如MySq、PostgreSQL等更好的选择。
LDAP的功能在LDAP的功能模型中定义了一系列利用LDAP协议的操作,主要包含以下4部分:
查询操作:允许查询目录和取得数据,其查询性能比关系数据库好。 更新操作:目录的更新操作没关系数据库方便,更新性能较差,但也同样允许进行添加、删除、修改等操作。 复制操作:前面也提到过,LDAP是一种典型的分布式结构,提供复制操作,可将主服务器的数据的更新复制到设置的从服务器中。 认证和管理操作:允许客户端在目录中识别自己,并且能够控制一个会话的性质。
而本文所要将的OpenLDAP就是一个优秀的开源的LDAP实现。
OpenLDAP安装配置及疑惑解答1. 安装和配置OpenLDAP安装软件非常简单,但在配置过程中遇到了不少坎坷,不是服务启动不成功就是验证不成功。 具体的安装和配置方法网上一大把,但都参差不齐,主要是因为新旧版本的OpenLDAP不同,配置方法有很大的改动。 下面给出网上几个还算靠谱的Linux和Windows两个平台下安装该软件的方法: 1)ubuntu安装LDAP:安装方法靠谱,但配置说的不太清楚,配置注意事项看后面。 2)Ubuntu OpenLDAP Server:官方教程,最值得借鉴,是英文的,这里有中文版的,但没英文的清晰,说的比较简单。 3)Linux下安装openldap:二进制包安装方法,适用于非Ubuntu的Linux系统,稍微有点麻烦,在安装OpenlDAP之前还需要安装Berkeley DB,但配置灵活,可以自定义安装路径什么的。后面的配置也没说清楚,主要看安装方法。 4)Linux服务器部署系列之七—OpenLDAP篇:另一篇较详细的二进制安装方法及配置。 4)Windows下OpenLDAP的安装及使用:介绍了LDAP的一些基础知识和Windows下安装方法。 5)图文介绍openLDAP在windows上的安装配置:比较详细,值得一看。
上面给出的这几个链接虽然还不错,但还是欠缺了些什么?对,就是讲解,网上给出的教程都是手把手教你如何安装和配置,而没有说明版本差异、具体配置的含义及为什么这样配置,如果因为版本或环境差异,你按其方法配置不成功,你也不知道哪里出的问题,因此建议还是先熟悉LDAP的基础知识,配置文件含义然后再试着安装。
2. OpenLDAP疑惑解答
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | import java.util.Hashtable; import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.Control; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; public class LDAPAuthentication { private final String BASEDN = "ou=Tester,dc=alexia,dc=cn" ; // 根据自己情况进行修改 private final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory" ; private LdapContext ctx = null ; private final Control[] connCtls = null ; private void LDAP_connect() { Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY); env.put(Context.PROVIDER_URL, URL + BASEDN); env.put(Context.SECURITY_AUTHENTICATION, "simple" ); String root = "cn=manager,dc=alexia,dc=cn" ; // 根,根据自己情况修改 env.put(Context.SECURITY_PRINCIPAL, root); // 管理员 env.put(Context.SECURITY_CREDENTIALS, "123456" ); // 管理员密码 try { ctx = new InitialLdapContext(env, connCtls); System.out.println( "认证成功" ); } catch (javax.naming.AuthenticationException e) { System.out.println( "认证失败:" ); e.printStackTrace(); } catch (Exception e) { System.out.println( "认证出错:" ); e.printStackTrace(); } if (ctx != null ) { try { ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } private String getUserDN(String uid) { String userDN = "" ; LDAP_connect(); try { SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration<SearchResult> en = ctx.search( "" , "uid=" + uid, constraints); if (en == null || !en.hasMoreElements()) { System.out.println( "未找到该用户" ); } // maybe more than one element while (en != null && en.hasMoreElements()) { Object obj = en.nextElement(); if (obj instanceof SearchResult) { SearchResult si = (SearchResult) obj; userDN += si.getName(); userDN += "," + BASEDN; } else { System.out.println(obj); } } } catch (Exception e) { System.out.println( "查找用户时产生异常。" ); e.printStackTrace(); } return userDN; } public boolean authenricate(String UID, String password) { boolean valide = false ; String userDN = getUserDN(UID); try { ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN); ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password); ctx.reconnect(connCtls); System.out.println(userDN + " 验证通过" ); valide = true ; } catch (AuthenticationException e) { System.out.println(userDN + " 验证失败" ); System.out.println(e.toString()); valide = false ; } catch (NamingException e) { System.out.println(userDN + " 验证失败" ); valide = false ; } return valide; } public static void main(String[] args) { LDAPAuthentication ldap = new LDAPAuthentication(); if (ldap.authenricate( "gygtest" , "jmwang" ) == true ){ System.out.println( "该用户认证成功" ); } } } |
既可以作为普通程序的认证,也可以通过输出检查自己的配置是否正确。
LDAP的实现除了OpenLDAP外,还有其它,比如OpenDJ(Open
source Directory services for the Java
platform),它是一个新的LDAPv3相容目录服务,为Java平台开发,提供了一个高性能的,高度可用和安全的企业管理的身份商店。其简单的安
装过程中,结合了Java平台的力量,使OpenDJ简单和最快的目录服务器部署和管理。有兴趣的可以查阅相关资料。
|