windows搭建ldap服务 win10 ldap
什么是LDAP,百度百科一堆专业术语的描述。
我总结为一句话:轻量级目录访问协议,有数据库的数据存储功能,以树状层次型存储方式,就好像你的电话薄那样。
在一次项目中,由于该项目是教育性管理项目,客户要求项目必须部署在内网。那么在内网的话,就代表用户需要去拨VPN才能进行内网的访问。
其实当时我想到的是,单独开个注册映射到外网,让用户自己注册,管理员进行审核,然后用VPN去读数据库中的账号和密码就行了。这样,我们的系统和vpn就
相当于统一账号。但是当我确认需求的时候,那个老师告诉我们,他不会读什么数据库,他能够LDAP或者windows域,当时我直接蒙逼了。没听过这个,最后花时间
看了下,发现也不是那么吊。切入正题
(1) 在官网上下载LDAP并安装,注意两点,1、第二步你输入的密码一定要记着,默认是secret;2、到“backend configuration” 这一步的时候,选择“BDB”
其他的你就一直下一步。安装完成的LDAP 默认是启动。你不用管他
(2)找到你安装的LDAP位置,找到“slapd.conf”这个配置文件。打开它。
里面有两行默认的配置
suffix "dc=maxcrc,dc=com" rootdn "cn=Manager,dc=maxcrc,dc=com"这两行东西其实是可以随便改的。只要能和你接下来要导入的conf文件中的配置匹配就可以。
其实,上面的两行属性可以理解为用户名和匹配项,用户名:cn=manager,匹配项:dc=maxcrc,dc=com
(3)写一个ynjy.conf文件
利用这个文件,你可以导入你的初始ldap的管理员
dn: uid=lrd,ou=People,dc=maxcrc,dc=com uid: lrd objectClass: inetOrgPerson labeledURI: http://www.maxcrc.com sn: Sun cn: lrd Sun上面的uid就类似于你的标示,ou=People,类似于你的电话薄名儿,里面存什么待会儿我们利用java来进行添加。
dc=maxcrc,dc=com 这句必须要和你的“slapd.conf”中的匹配,就是我上面说的匹配项。
注意点来了,LDAP可以自定义属性,通过schema自定义,但初次不要去试,因为容易失败,ldap的资料还是比较少。解决问题有时候摸不着头绪
ldap提供了本身自带的属性,就是我们上的uid,mail,userPassword,labeledURI,sn,cn等,,记住,这几个属性必须不能改它。大小写都认。不然导不进去。
(4)导入ynjy.conf进入ldap
cmd进入命令窗口,定位到你的ldap目录中
输入命令:ldapadd -x -D "cn=Manager,dc=maxcrc,dc=com" -w secret -f ynjy.ldif
你会看见执行条目成功的提示
你可以下载一个ldapBrowser进行查看。
上面的初步ldap平台的准备工作就完了
接下来,我们准备Java的访问
其实和连接JDBC方式是一样的。注意的就是LDAP的cn,dc这些属性要匹配。相当于账号!!!
我就直接将我的LDAPHelper代码贴出来。并且附上一段简单将数据读进LDAP中的代码
package util; import java.util.Hashtable; import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; 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 LDAPHelper { private final String URL = "ldap://192.168.2.19:389/"; private final String BASEDN = "ou=People,dc=maxcrc,dc=com"; // 根据自己情况进行修改 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=maxcrc,dc=com"; //根据自己情况修改 env.put(Context.SECURITY_PRINCIPAL, root); // 管理员 env.put(Context.SECURITY_CREDENTIALS, "daqsoft"); // 管理员密码 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(); } } private void closeContext(){ 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; } closeContext(); return valide; }上面的代码是我从另外一张表获得的用户信息写进了ldap。
ldap的操作就介绍完毕。有问题的大家可以一起讨论。我也是刚用到将这个东西勉强用起来