java jndi ldap_Java命名目录接口(JNDI)教程--LDAP用户的高级主题

LDAP用户的高级主题

本节提供LDAP和JNDI之间映射的详细信息。同时提供使用JNDI访问LDAP服务器的暗示和提示。

LDAP

X.500,一个CCITT的目录服务器标准,是OSI否为套件的一部分。X.500标准定义了客户端应用程序访问X.500目录的协议,叫做目录访问协议(DAP)。它在开放系统互连(OSI)协议栈的顶层。

因特网委员会认为需要X.500类型的访问但底层的网络基础架构(是TCP/IP而不是OSI)不同,基于X.500 DAP协议设计了一个新协议,叫做轻量级DAP或LDAP。RFC 2251定义了成为版本3的LDAP(LDAPv3),这是它的前身LDAP v2(RFC 1777)的改进。

LDAP协议的目的是容易实现,特别是创建小的简单的客户端。一种尝试简化的成果是大量使用字符串来减少结构的使用。例如DN,在协议中以字符串表示,属性类型名和大多数属性值也是如此。

这个协议包含客户端向服务器发送的请求,对于服务器的应答,不需要按照请求的顺序进行。每一个请求有一个ID,所以请求和应答可以匹配。这个协议可以工作在TCP或UDP中,最常用的是TCP。

因为焦点在客户端,LDAP组织同时定义了DN的字符串表达(RFC 2553),搜索过滤器(RFC 1960),属性语法(RFC 1778),为C语言提供的API(RFC 1823),访问LDAP访问的URL格式(RFC 1959)。

LDAP v3支持国际化,多种认证技术,referral,以及一般的部署技术。使用extensions和controls添加新特性时不需要修改协议。

LDAP v3

国际化

国际化是通过国际化字符集(ISO 10646)表示协议中的字符串元素(例如DN)。v3与v2不同,v2使用UTF-8编码字符串。

认证

除了匿名,简单(明文密码)认证,LDAPv3使用简单认证以及安全层(SASL)认证架构(RFC 2222)允许在LDAP中使用不同的认证技术。SASL定义了客户端和服务器之间数据交换的认证的挑战-应答协议。

现在定义了一些SASL技术:DIGEST-MD5, CRAM-MD5,匿名,扩展,S/Key, GSSAPI以及Kerberos v4。LDAP v3客户端可以使用任意一种SASL技术,提供给支持这种技术的LDAP v3服务器。而且,新的(还没有定义的)SASL技术可以在不改变LDAP的情况下使用。

referrals

referral是服务器发送个客户端的信息,表示请求的信息可以在其他地方发现(很可能是其他服务器)。在LDAP v2中,服务器由服务器处理referral,不返回到客户端。因为实现referral是非常负载的并且可能导致很复杂的客户端。当服务器构建以及部署后,referral就变得十分有用,但不是很多服务器支持服务端的referral处理。所以,使用一种方法修改协议允许返回referral。通过在将referral放置在“partial result”错误应答的错误信息中实现。

LDAP v3显式支持referrals,允许服务器直接向客户端返回referrals。referrals不再本课中介绍,您可以求助于JNDI教程关于符合在应用程序中控制referrals的信息。

部署

LDAP这种普通协议可以用来确保目录客户端和服务器“说同一种语言”。当不同的目录客户端和服务器部署在网络中时,这些实体都说同样的对象是非常有用的。

目录架构描述,在其他东西中间,对象的类型,目录可能有的对象的类型,对象的每个必须的或可选属性。LDAP v3定义架构(RFC 2252和RFC 2256)基于X.500标准为了在网络中查找基本对象定义,例如,国家,地区,组织,用户/人,用户组和设备。它定义了客户端访问服务器架构的方法,所以可以发现对象的类型以及服务器支持的属性。

LDAPv3进一步定义了表示属性值的一组语法(RFC 2252)。要编写访问架构信息的Java应用程序,请参考JNDI教程。

扩展

除了预定义的所有操作,例如“search”和“modify”之外,LDAPv3定义了“extended”操作。“extended”将请求当作参数并且返回应答。请求中包含标识请求的标识符和请求参数。应答中包含请求执行的结果。“extended”操作中的请求和应答叫做扩展。例如,可以为开始TLS定义扩展,它是客户端向服务器的请求,用来开始Start TLS协议。

扩展可以是标准的(LDAP委员会定义的)或者私有的(由供应商定义)。要编写使用扩展的程序请参考JNDI教程。

Controls

添加新特性的另一种方法是使用control。LDAP v3允许通过使用control修改所有操作的行为。一个操作中可以发送任意多个control,同时结果中也可以返回任意数量的control。例如,您可以和“search”操作一起发送排序control,告诉服务器根据“name”属性对结果进行。

和扩展一样,control可以是标准的也可以是私有的。标准control由平台提供。编写使用control的应用程序请参考JNDI教程。

将JNDI作为LDAP的API

JNDI和LDAP的模型在命名对象时都使用层次结构的名字空间。名字空间中的每一个对象都可能有属性,而且这些属性可以用来搜索对象。在这种层次上,两个模型是类似的,所以JNDI可以对LDAP进行很好的映射也没有什么稀奇的。

模型

您可以将LDAP的条目想象成JNDI的DirContext。每个LDAP条目包含名称和一组属性,以及可选的子条目集合。例如,LDAP条目“o=JNDITutorial”可能有属性“objectclass”和“o”,同时可能有子条目“ou=Groups”和“ou=People”。

在JNDI中,LDAP条目“o=JNDITutorial”可以表示成名为“o=JNDITutorial”的上下文,它有两个子上下文,名叫“ou=Groups”和“ou=People”。LDAP条目属性使用Attributes接口表示,而独立的属性通过Attribute接口表示。

关于LDAP操作如何通过JNDI进行访问的详细信息请参考下一部分。

名字

为了联合查询,您提供给JNDI上下文方法的名称可以跨越多个命名空间。这些叫做混合名字。当使用JNDI访问LDAP服务时,您需要明白字符串中的斜杠(“/”)在JNDI中特殊的含义。如果JNDI条目包含这个字符,需要进行转义(使用“\”)。例如,使用名称“cn=O/R”的LDAP条目在JNDI context的方法中,必须使用“cn=O\\/R”标识。关于名字的更多信息,请参考JNDI教程。LdapName和Rdn类简要介绍了创建和操作LDAP名字的方法。

协议中LDAP的名称总是完全的名字,表示从LDAP命名空间根开始的唯一条目(由服务器定义)。以下是一些LDAP全名的例子:

cn=John Smith, ou=Marketing, o=Some Corporation, c=gb

cn=Vinnie Ryan, ou=People, o=JNDITutorial

然而,在JNDI中,名字是相对的,即,您总是相对于上下文命名对象。例如,您可以相对于上下文“ou=People, o=JNDITutorial”对“cn=Vinnie Ryan”条目进行命名。或者,您可以相对于上下文“o=JNDITutorial”对条目“cn=Vinnie Ryan, ou=People”进行命名。或者,您可以创建初始上下文指向LDAP服务器命名空间的根,然后命名条目“cn=Vinnie Ryan, ou=People, o=JNDITutorial”。

在JNDI中,您同样可以使用LDAP的URL来命名LDAP条目。请参考JNDI教程中的LDAP URL讨论。

LDAP操作如何映射到JNDI API

LDAP定义了一组操作或请求(RFC 2251)。在JNDI中,这些操作被映射到DirContext和LdapContext接口中,它们都是Context的子接口。例如,当请求DirContext中的方法时。LDAP服务提供者通过将LDAP请求发送给LDAP服务器实现这个操作。

下表描述和LDAP操作对应的JNDI方法:

LDAP操作

对应的JNDI方法

bind

这是创建LDAP服务器初始连接的方式,对应JNDI中创建InitialDirContext对象。当应用程序创建初始上下文,它在环境参数中向服务器提供客户端认证信息。要修改一个已经存在上下文的认证信息,使用Context.addToEnvironment()和Context.removeFromEnvironment()。

Unbind

Context.close()用来释放上下文使用的资源。服务提供者的实现和LDAP的unbind操作有一些不同,资源在上下文之间共享,所以关闭上下文当资源被其他上下文使用时就不会释放。如果您的意图是释放所有资源,需要关闭所有上下文。

Search

JNDI中对应方法是DirContext.search()中接收搜索过滤器(RFC 2254)的重载形式。

modify

JNDI中对应方法是DirContext.modifyAttributes()中接收DirContext.ModificationItems数组的重载形式。示例请看修改属性一节。

Add

JNDI中对应方法是DirContext.bind()和DirContext.createSubcontext()。您可以使用它们添加一个新的LDAP条目。使用bind(),您不但需要指定新条目的属性集合同时需要和属性一起的Java对象。示例请参考关联属性的添加、替换绑定一节。

Delete

JNDI中对应的方法是Context.unbind()和Context.destroySubcontext()。您可以使用它们移除LDAP条目。

modify DN/RDN

JNDI中对应方法是Context.rename()。请参考重命名对象一节得到详细信息。

compare

在JNDI中可以使用DirContext.search()代替。示例请参考LDAP比较操作一节。

abandon

当您关闭上下文时,所有没有应答的请求都被放弃。类似的,当关闭NamingEnumeration,相应的LDAP“search”请求也放弃了。

Extended操作

JNDI中对应的方法是LdapContext.extendedOperation()。详细信息请参考JNDI教程。

LDAP错误码如何映射到JNDI异常

LDAP定义了一组状态码,它们是由LDAP服务器作为应答发送给客户端的(RFC 2251)。在JNDI中,错误条件由Naming Exceptions子类的检查的异常标识。请参考JNDI异常类概述中的Naming Exceptions。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LDAP(Lightweight Directory Access Protocol)是一种轻量级目录访问协议,旨在提供对目录服务的快速访问。在Java中,可以通过使用JNDIJava Naming and Directory Interface)API来操作LDAP。 下面是一些Java操作LDAP的常见步骤和示例代码: 1.创建连接对象 ``` Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=com"); env.put(Context.SECURITY_CREDENTIALS, "password"); DirContext ctx = new InitialDirContext(env); ``` 2.查询数据 ``` String base = "ou=people,dc=example,dc=com"; String filter = "(objectclass=person)"; SearchControls sc = new SearchControls(); sc.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration<SearchResult> results = ctx.search(base, filter, sc); while (results.hasMore()) { SearchResult sr = (SearchResult) results.next(); // 处理查询结果 } ``` 3.添加数据 ``` Attributes attrs = new BasicAttributes(); attrs.put("cn", "John Smith"); attrs.put("sn", "Smith"); attrs.put("givenName", "John"); attrs.put("mail", "[email protected]"); attrs.put("userPassword", "password"); ctx.createSubcontext("cn=John Smith,ou=people,dc=example,dc=com", attrs); ``` 4.修改数据 ``` ModificationItem[] mods = new ModificationItem[1]; mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("mail", "[email protected]")); ctx.modifyAttributes("cn=John Smith,ou=people,dc=example,dc=com", mods); ``` 5.删除数据 ``` ctx.destroySubcontext("cn=John Smith,ou=people,dc=example,dc=com"); ``` 这些是Java操作LDAP的一些基本步骤和示例代码,但实际应用中还需要考虑LDAP服务器的具体配置和授权等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值