什么是LDAP?

LDAP(轻量目录访问协议),简单的说,LDAP是一个能得到关于人或者资源的集合、静态数据的快速方式。

这种说法似乎有点抽象,结合这几天在做的一个项目具体来谈一下。

AD,LDAP,初来乍到的面对这些在课本上不可能碰到的新术语还真是有些懵了,查了大量的资料之后,终于开始有点感觉了。

大多数企业及单位都会有人员管理系统,而有很多是用window server进行管理的,其中的原因相信大家早已明白:简单,方便。但是很多时候我们会需要利用程序获取服务器上面的人员数据,听起来似乎无从下手,但由于资源大多是保存在AD域下面的,于是LDAP能够帮我们轻易的完成这件事。

最开始找了很多的程序,但都走了弯路,因为这些程序大多没有解释几个关键概念:

OU(组织单元):你可以理解为目录信息

O(组织名):可以理解为公司名,比如说O=foobar.com,但是更多情况下我们会把它拆分为DC=foobar,DC=com(实践发现使用O会出现连接错误,不知道是否这种表示方式已经被DC替代)。

下面是一段实例代码,之后会解释了各个字段的意思及用法:

 

package ldap;

import java.util.Iterator;

import com.novell.ldap.LDAPAttributeSet;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPEntry;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPSearchResults;

public class LdapCon {
	
	public static void main(String[] args) {
		LdapCon lc=new LdapCon();
		try {
			lc.conenction();
		} catch (LDAPException e) {
			e.printStackTrace();
		}
	}

	
	private static void conenction() throws LDAPException{
		String MY_HOST = "192.168.139.132";//访问AD域的IP地址
		int MY_PORT = 389;//端口号,默认为389
		
		LDAPConnection ld = new LDAPConnection();

//		ld.setSocketTimeOut(21000);//设置超时
		ld.connect( MY_HOST, MY_PORT );
//		ld.bind(null, null);
		ld.bind("Administrator@smallbusiness.local", "123456");
		
		String searchBase = "OU=项目部,DC=smallbusiness,DC=local";//域名入口
		int searchScope = LDAPConnection.SCOPE_SUBORDINATESUBTREE;//搜索范围
		
		//过滤器
		String filter="(|(objectclass=person)(objectclass=user)(objectclass=organizationalPerson))";
		
		LDAPSearchResults searchResults =ld.search(searchBase,
		searchScope,
		filter,
		null,
		false);
		
		while ( searchResults.hasMore()) {
			LDAPEntry nextEntry = searchResults.next();
			System.out.println("We found "+nextEntry.getDN());
//			LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
			
//			Iterator ite=attributeSet.iterator();
//			while(ite.hasNext()){
//				System.out.println(ite.next());
//			}
		}

	}
}

具体的解释一下下面这几个概念

Ld.bind(loginDN,loginPW):表示LDAPConnection的绑定,不能省略,你可以输入两个null来进行匿名登录,当然,以匿名方式登录并不代表你具有所有的权限。下面就来说一下这两个参数到底应该怎么填,尝试了很多种方法,DN表示域名,根据这种命名方法来猜测,loginDN应该是登录名加域名的表示方式,而你在windwos server的AD域中进行用户添加的时候就会发现,用户唯一标示名的表示方式是login@DN,密码则是对应用户的密码。

ld.setSocketTimeOut(int),设置连接超时,这个方法并没有产生实际的效果,因为即使不设置,服务器在连接不上的时候依然会超时。

Search Scope:表示搜索的深度,有四个基本参数:

• SCOPE_BASE. 这个只在你已经知道了目录结构的时候使用,你用这种搜索方式输出的时候会发现什么都看不到

• SCOPE_ONE. 只搜索处在该层目录的数据(也就是说如果存在多层结构,处在该层目录一下的目录里面的数据就搜不到)。

• SCOPE_SUB. 按层次遍历,可以搜到该目录下面的所有数据,包含目录.

• SCOPE_SUBORDINATESUBTREE. 搜索的形式跟上面一个一样,但是不包含基础的数据,具体什么含义,试试就知道了。

Filter:过滤器,and = "&" filterlist,or = "|" filterlist,not = "!" filterlist,就像我代码中写到的一样以|开头,表示条件或。还有一种表示方式就是objectClass=*,使用通配符表示所有。

 有了数据你自然明白该做什么了O(∩_∩)O~,不过还有一点依然需要强调,就像很多前辈跟我说过的,学好算法跟数据结构,前两天想单纯依靠循环的逻辑控制解决目录结构的问题,但努力之后才发现,利用多叉树解决要快得多,虽然我一开始就意识到目录本身就是一个树状结构,但是加以实践才是问题的最好答案。算法和数据结构受到如此之重视就是因为用对了的算法和数据结构有可能使你的代码在效率和简洁度上出现意想不到的结果。

路漫漫其修远兮~