Java LDAP graceful disconnect

目前从java我用以下代码连接到LDAP,非常典型的例子:

Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, url); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, user); env.put(Context.SECURITY_CREDENTIALS, password); LdapContext ctx = null; try { ctx = new InitialLdapContext(env, null); return true; } catch (NamingException ex) { return false; } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException e) { log.warn(e.getMessage()); } } } 

这在validation用户方面起作用。 但是LDAP管理员告诉我,当绑定不成功时,我没有正常断开连接。 LDAP端的错误是(例如):

[24 / Jan / 2013:13:20:44 -0500] conn = 249 op = -1 msgId = -1 – 从[ipaddress]关闭:44724 – A1 – 客户端中止连接 –

他还说,当validation成功时,断开连接是优雅的。 我想这是因为我在那种情况下做了ctx.close()

但是,当身份validation失败时,实际上会new InitialLdapContext(env, null)行抛出exception。 因此,不返回任何上下文,并且不会在任何上下文中调用close。

在尝试身份validation之前,是否有某种方法可以检索某种连接对象,以便我可以在事后关闭它,无论auth是否成功?

他为什么要关心优雅和不优雅的关系呢? 很明显,你的关闭正在唯一相关的情况下执行:你成功的情况。 在另一种情况下,没有什么可以关闭,所以你可以打电话。 在另一种情况下,JNDI LDAP提供程序将关闭它,显然它正在进行中断关闭。 这一切都在JNDI LDAP提供程序中。 你无能为力。 我建议他找到别的东西担心这实际上很重要。

正常搜索LDAP会返回

 NamingEnumeration results 

你还需要关闭():

 } finally { if(results != null) { try { results.close(); } catch (NamingException e) { LOG.error("Error closing LDAP results", e); } } 

在添加任何身份validation详细信息之前构造上下文对象 然后,使用addToEnvironment添加凭据。 最后,执行一个非常简单的搜索(我的方法是查找用户名的distinguishedName属性)。 如果凭据不好,搜索将失败,并且您仍然需要关闭上下文对象。

此方法的另一个好处是:您可以维护上下文对象池,并避免不断连接/断开连接以执行身份validation。

 Hashtable environment = new Hashtable(); environment.put("java.naming.provider.url", url); environment.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory"); InitialLdapContext context = new InitialLdapContext(environment, null); ... context.addToEnvironment("java.naming.security.principal", principal); context.addToEnvironment("java.naming.security.credentials", credentials); ... // execute some kind of search, based on your needs