Sun Directory Server/LDAP学习笔记(二)——API说明及代码样例

相关文章:[url=http://linliangyi2007.iteye.com/blog/167125]Sun Directory Server/LDAP学习笔记(一)——LDAP协议简述[/url]

[size=large][b]Java6.0 API for LDAP概述[/b][/size]

从JDK5.0开始,对LDAP协议的数据访问操作就被集成在javax的扩展API包中,并随同JDK一并发布,这一章节,我们主要介绍API包中的类信息。
[b]javax.naming.directory 包的结构[/b]
[img]http://linliangyi2007.iteye.com/upload/picture/pic/8744/0369fc37-7571-3409-9013-f036763eebdd.gif[/img]

[size=large][b]常用API解析[/b][/size]

[b]javax.naming.directory.InitialDirContext,初始化目录服务上下文类[/b]
该类是LDAP数据内容的操作工具类,通过该类可以执行绑定LDAP服务器、新增LDAP条目、获取条目实例、修改条目属性、删除条目和根据条件搜索条目等操作。常用方法说明如下:

[b]初始化LDAP 目录服务上下文(相当于使用JDBC打开一个数据库链接)[/b][list]
[*]InitialDirContext(Hashtable<?,?> environment)
[/list]
[b]绑定/创建LDAP条目对象(相当于新增一个LDAP条目数据[/b]bind(Name [list]
[*]name, Object obj, Attributes attrs)
[*]bind(String name, Object obj, Attributes attrs)
[*]createSubcontext(Name name, Attributes attrs)
[*]createSubcontext(String name, Attributes attrs)
[/list]
[b]获取条目实例(属性集)[/b]
[list]
[*]getAttributes(Name name)
[*]getAttributes(Name name, String[] attrIds)
[*]getAttributes(String name)
[*]getAttributes(String name, String[] attrIds)
[/list]
[b]修改条目属性[/b]
[list]
[*]modifyAttributes(Name name, int mod_op, Attributes attrs)
[*]modifyAttributes(Name name, ModificationItem[] mods)
[*]modifyAttributes(String name, int mod_op, Attributes attrs)
[*]modifyAttributes(String name, ModificationItem[] mods)
[/list]
[b]删除条目[/b]
[list]
[*]destroySubcontext(Name name)
[*]destroySubcontext(String name)
[/list]
[b]根据属性集搜索条目[/b]
[list]
[*]search(Name name, Attributes matchingAttributes)
[*]search(Name name, Attributes matchingAttributes, String[] attributesToReturn)
[*]search(String name, Attributes matchingAttributes)
[*]search(String name, Attributes matchingAttributes, String[] attributesToReturn)
[/list]
[b]根据过滤器搜索条目[/b]
[list]
[*]search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons)
[*]search(Name name, String filter, SearchControls cons)
[*]search(String name, String filterExpr, Object[] filterArgs, SearchControls cons)
[*]search(String name, String filter, SearchControls cons)
[/list]

[b]javax.naming.directory.BasicAttribute,LDAP基本属性对象[/b]
该类用来表示LDAP条目中的单个属性对象。在目录服务中,每个属性名称是可以对应多个的属性值的。

[b]构建属性对象[/b]
[list]
[*]BasicAttribute(String id)
[*]BasicAttribute(String id, boolean ordered)
[*]BasicAttribute(String id, Object value)
[*]BasicAttribute(String id, Object value, boolean ordered)
[/list]
[b]添加属性值[/b]
[list]
[*]add(int ix, Object attrVal),添加属性值到多值属性的指定位置
[*]add(Object attrVal) , 追加属性值到多值属性尾部
[/list]
[b]判断属性值是否包含[/b]
[list]
[*]contains(Object attrVal) , 多值属性中有一个值是匹配的,返回true
[/list]
[b]获取属性值[/b]
[list]
[*]get(),取得属性值中的一个
[*]get(int ix),从多值属性中的指定位置取值
[/list]
[b]获取属性ID[/b]
[list]
[*]getID(),属性的ID就是属性名
[/list]
[b]删除属性值[/b]
[list]
[*]remove(int ix),删除指定位置的属性值
[*]remove(Object attrval),删除指定的属性值
[/list]

[b]javax.naming.directory.BasicAttributes,LDAP实体的属性集[/b]
该类表示一个LDAP条目绑定的属性集合,在绝大多数情况下,一个LDAP条目存在多个属性。

[b]构造属性集[/b]
[list]
[*]BasicAttributes()
[*]BasicAttributes(boolean ignoreCase),属性ID是否大小写敏感,建议不要使用敏感
[*]BasicAttributes(String attrID, Object val)
[*]BasicAttributes(String attrID, Object val, boolean ignoreCase)
[/list]
[b]获取属性集中的单个属性对象[/b]
[list]
[*]get(String attrID)
[/list]
[b]获取全部属性的枚举[/b]
[list]
[*]getAll()
[/list]
[b]获取全部属性的ID枚举[/b]
[list]
[*]getIDs()
[/list]
[b]添加新属性[/b]
[list]
[*]put(Attribute attr)
[*]put(String attrID, Object val)
[/list]
[b]移除指定属性[/b]
[list]
[*]remove(String attrID)
[/list]

[b]javax.naming.directory.SearchControls , LDAP目录服务搜索控制对象[/b]
该类负责控制LDAP搜索行为的范围、设定返回结果数上限,搜索耗时上限,指定结果所包括的属性集等。

[b]设定搜索行为的范围[/b]
[list]
[*]setSearchScope(int scope)
[/list]
[b]设定返回结果数上限[/b]
[list]
[*]setCountLimit(long limit)
[/list]
[b]设定搜索耗时上限[/b]
[list]
[*]setTimeLimit(int ms) , 以毫秒为单位
[/list]
[b]指定结果所包括的属性集[/b]
[list]
[*]setReturningAttributes(String[] attrs)
[/list]

[b]javax.naming.directory.SearchResult , 表示.search() 方法的返回结果集中的一项。[/b]
SearchResult类是对LDAP条目属性集的封装。在search()操作中可能返回完整的条目属性,也可能是条目属性的一部分。

[b]获取SearchResult封装的条目属性[/b]
[list]
[*]getAttributes()
[/list]

以上只列举了LDAP操作API的常用部分,更多更详细的描述,请参考 [url=http://java.sun.com/javase/6/docs/api/javax/naming/directory/package-summary.html]Sun Java6.0 API DOC。[/url]

[size=large][b]LDAP操作代码样例[/b][/size]
在这个章节中,我们将结合LDAP操作的代码实例了解API使用。

[b]初始化LDAP 目录服务上下文[/b]
该例子中,我们使用uid=linly,ou=People,dc=jsoso,dc=net这个账号,链接位于本机8389端口的LDAP服务器(ldap://localhost:8389),认证方式采用simple类型,即用户名/密码方式。

private static void initialContext() throws NamingException{
if(singleton == null){
singleton = new LDAPConnection();
/*
* 在实际编码中,这些环境变量应尽可能通过配置文件读取
*/
//LDAP服务地址
singleton.sLDAP_URL = "ldap://localhost:8389";
//管理员账号
singleton.sMANAGER_DN = "uid=linly,ou=People,dc=jsoso,dc=net";
//管理员密码
singleton.sMANAGER_PASSWORD = "coffee";
//认证类型
singleton.sAUTH_TYPE = "simple";
//JNDI Context工厂类
singleton.sCONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";

singleton.envProps.setProperty(Context.INITIAL_CONTEXT_FACTORY, singleton.sCONTEXT_FACTORY);
singleton.envProps.setProperty(Context.PROVIDER_URL, singleton.sLDAP_URL);
singleton.envProps.setProperty(Context.SECURITY_AUTHENTICATION, singleton.sAUTH_TYPE);
singleton.envProps.setProperty(Context.SECURITY_PRINCIPAL, singleton.sMANAGER_DN);
singleton.envProps.setProperty(Context.SECURITY_CREDENTIALS, singleton.sMANAGER_PASSWORD);
/*
* 绑定ldap服务器
*/
singleton.dirCtx = new InitialDirContext(singleton.envProps);
}
}

通过一个Hashtable或者Properties对象为LDAP的Context设置参数,而后初始化InitialDirContext,即可绑定LDAP服务。这相当于JDBC中获取数据库的Connection对象。

[b]绑定/创建LDAP条目对象[/b]
用户可以使用bind方法创建新的LDAP条目,下面的代码创建一个DN:"ou=Employee , dc=jsoso ,dc=net"的OrganizationUnit类LDAP条目如下:
	public boolean createOrganizationUnit(){
String ldapGroupDN = "ou=Employee , dc=jsoso ,dc=net";
try {
/*
* 查找是否已经存在指定的OU条目
* 如果存在,则打印OU条目的属性信息
* 如果不存在,则程序会抛出NamingException异常,进入异常处理
*/
Attributes attrs = dirContext.getAttributes(ldapGroupDN);
System.out.println("Find the group , attributes list :");
NamingEnumeration<String> nEnum = attrs.getIDs();
for( ; nEnum.hasMore() ; ){
String attrID = nEnum.next();
Attribute attr = (Attribute)attrs.get(attrID);
System.out.println(attr.toString());
}
return false;
} catch (NamingException e) {
/*
* 没有找到对应的Group条目,新增Group条目
*/
//创建objectclass属性
Attribute objclass = new BasicAttribute("objectclass");
objclass.add("top");
objclass.add("organizationalunit");
//创建cn属性
Attribute cn = new BasicAttribute("ou", "Employee");
//创建Attributes,并添加objectclass和cn属性
Attributes attrs = new BasicAttributes();
attrs.put(objclass);
attrs.put(cn);
//将属性绑定到新的条目上,创建该条目
try {
dirContext.bind(ldapGroupDN, null, attrs);
System.out.println("Group created successful");
return true;
} catch (NamingException e1) {
e1.printStackTrace();
}
}
return false;
}

或者使用createSubcontext方法创建亦可,以下例子我们新增一个inetorgperson类的LDAP条目:
	/**
* 创建LDAP用户条目
* @param user
* @return
*/
public boolean createUser(LDAPUser user){
if(user == null){
return false;
}

if(user.getUserID() == null || user.getUserID().length() == 0
|| user.getFirstName() == null || user.getFirstName().length() == 0
|| user.getLastName() == null || user.getLastName().length() == 0
|| user.getCommomName() == null || user.getCommomName().length() == 0){
return false;
}

//判断用户条目是否已经存在
if(isUserexist(user.getDistinguishedName())){
return true;
}

/*
* 新建条目属性集
*/
Attributes attrs = new BasicAttributes();
setBasicAttribute(attrs , "objectclass" , "top,person,organizationalPerson,inetorgperson");
setBasicAttribute(attrs , "cn" , user.getCommomName());
setBasicAttribute(attrs , "givenname" , user.getFirstName());
setBasicAttribute(attrs , "sn" , user.getLastName());
setBasicAttribute(attrs , "uid" , user.getUserID());
setBasicAttribute(attrs , "userpassword" , user.getPassword());

//添加用户条目节点
try {
dirContext.createSubcontext(user.getDistinguishedName(), attrs);
System.out.println("Add User(" + user.getDistinguishedName() + ") ok.");
return true;
} catch (NamingException e) {
e.printStackTrace();
}
return false;
}


[b]获取条目属性[/b]
下面一段代码获取entryDN参数指定条目中的属性集合,并打印到控制台
	/**
* 获取一个指定的LDAP Entry
* @param entryDN
*/
public void find(String entryDN){
try {
Attributes attrs = dirContext.getAttributes(entryDN);
if (attrs != null) {
NamingEnumeration<String> nEnum = attrs.getIDs();
for( ; nEnum.hasMore() ; ){
String attrID = nEnum.next();
Attribute attr = (Attribute)attrs.get(attrID);
System.out.println(attr.toString());
}
System.out.println();
}else{
System.out.println("No found binding.");
}
}catch(NamingException ne) {
ne.printStackTrace();
}
}


[b]修改条目属性[/b]
修改DN=user.getDistinguishedName()的条目中的cn、givenname、sn和userpassword四个属性值。
[color=blue](注:参数DirContext.REPLACE_ATTRIBUTE有另外两个常量:DirContext.ADD_ATTRIBUTE;DirContext.REMOVE_ATTRIBUTE,分别表示新增属性和删除属性。)[/color]
	/**
* 修改用户信息
* @param user
* @return
* @throws Exception
*/
public boolean modifyUser(LDAPUser user) throws Exception {
//用户对象为空
if (user == null) {
throw new Exception("No user information!n");
}

//检查uid
String userDN = user.getDistinguishedName();
if (userDN == null && userDN.length() == 0) {
throw new NamingException("No userDN you specify!n");
}

//判断用户条目是否已经存在
if(!isUserexist(userDN)){
return false;
}

//设置属性
Attributes attrs = new BasicAttributes();
setBasicAttribute(attrs, "cn", user.getCommomName());
setBasicAttribute(attrs, "givenname", user.getFirstName());
setBasicAttribute(attrs, "sn", user.getLastName());
setBasicAttribute(attrs, "userpassword", user.getPassword());
//修改属性
try{
dirContext.modifyAttributes(user.getDistinguishedName(),DirContext.REPLACE_ATTRIBUTE, attrs);
System.out.println("User(" + user.getDistinguishedName() + ") information modified.n");
return true;
}catch(NamingException ne){
ne.printStackTrace();
}
return false;
}


[b]删除条目[/b]
删除DN= userDN条目
	/**
* 删除用户
* @param userDN
* @return
*/
public boolean deleteUser(String userDN) {
if(!isUserexist(userDN)) {
return true;
}
try {
dirContext.destroySubcontext(userDN);
System.out.println("User( " + userDN + ") deleted.n");
return true;
} catch (NamingException e) {
e.printStackTrace();
}
return false;
}


[b]根据属性集搜索条目[/b]
根据属性集matchingAttributes中的匹配值,在上下文DN= "ou=People,dc=jsoso ,dc=net"中搜索它的所有子树中的匹配条目。
[color=blue](注:SearchControls的SCOPE参数详见SearchControls SCOPE补充说明)[/color]
          /**
* 通过属性搜索LDAP范例
* @return
*/
public void searchByAttribute(Attributes matchingAttributes){
String baseDN = "ou=People,dc=jsoso ,dc=net";
SearchControls cons = new SearchControls();
cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
try {
Name baseName = new LdapName(baseDN);
NamingEnumeration<SearchResult> ne = dirContext.search(baseName, matchingAttributes);
SearchResult entry = null;
for(;ne.hasMore();){
entry = ne.next();
showEntry(entry);
}
} catch (NamingException e) {
e.printStackTrace();
}
}


[b]根据过滤器搜索条目[/b]
根据过滤器条件,在上下文DN = "ou=People,dc=jsoso ,dc=net"中,搜索它的所有子树中的匹配条目。
[color=blue](注:过滤器filter的相关语法详见LDAP filter语法补充说明)[/color]
	/**
* 通过过滤器搜索LDAP范例
* @return
*/
public void searchByFilter(String filter){
String baseDN = "ou=People,dc=jsoso ,dc=net";
SearchControls cons = new SearchControls();
cons.setSearchScope(SearchControls.SUBTREE_SCOPE);
try {
NamingEnumeration<SearchResult> ne = dirContext.search(baseDN, filter , cons);
SearchResult entry = null;
for(;ne.hasMore();){
entry = ne.next();
showEntry(entry);
}
} catch (NamingException e) {
e.printStackTrace();
}
}


[size=large][b]相关补充[/b][/size]

[b]javax.naming.Name对象说明[/b]
在API中,我们常常见到对LDAP上下文条目有两种参数形式,一种是大家都熟悉的String参数,如: String baseDN = "ou=People,dc=jsoso ,dc=net";
另一种是使用javax.naming.Name类型的参数,那么Name类和String有什么区别呢?
简单的说,Name是对String类DN的封装,它把一个完整的DN字窜分解成了RDN的list。这个list的顺序刚好和String相反。就拿"ou=People,dc=jsoso ,dc=net"为例,Name中的RDN顺序是[0]=net,[1]=jsoso,[2]=People。这样做的好处是更方便对Name进行操作,比如取其前缀或者后缀。

[b]SearchControls SCOPE补充说明[/b]
[img]http://linliangyi2007.iteye.com/upload/picture/pic/8746/655c33eb-9277-3740-834c-63a17e48085e.gif[/img]

[b]LDAP filter语法补充说明[/b]
filter的运算符
[img]http://linliangyi2007.iteye.com/upload/picture/pic/8734/d1a62a84-b638-32d7-9d4f-f6829ba54dbf.gif[/img]
filter布尔运算符
[img]http://linliangyi2007.iteye.com/upload/picture/pic/8736/a151eb07-48b5-3d42-a191-67ea6f694aa8.gif[/img]

[b]搜索过滤器示例 [/b]

[list]
[*]下列过滤器将搜索包含一个或多个 manager 属性值的条目。这也称为存在搜索: manager=*
[*]下列过滤器将搜索包含通用名 Ray Kultgen 的条目。这也称为等价搜索:cn=Ray Kultgen
[*]下列过滤器返回所有不包含通用名 Ray Kultgen 的条目:(!(cn=Ray Kultgen))
[*]下列过滤器返回的所有条目中都有包含子字符串 X.500 的说明属性:description=*X.500*
[*]下列过滤器返回所有组织单元为 Marketing 且说明字段中不包含子字符串 X.500 的条目: (&(ou=Marketing)(!(description=*X.500*)))
[*]下列过滤器返回所有组织单元为 Marketing 且 manager 为 Julie Fulmer 或 Cindy Zwaska 的条目: (&(ou=Marketing)(|(manager=cn=Julie Fulmer,ou=Marketing,dc=siroe,dc=com)(manager=cn=Cindy Zwaska,ou=Marketing,dc=siroe,dc=com)))
[*]下列过滤器返回所有不代表人员的条目: (!(objectClass=person))
[*]下列过滤器返回所有不代表人员且通用名近似于 printer3b 的条目:(&(!(objectClass=person))(cn~=printer3b))
[/list]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值