Java LDAP graceful disconnect

时间:2013-01-24 23:15:05

标签: java connection ldap

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

    Hashtable<String, String> env = new Hashtable<String, String>();

    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());
            }
        }
    }

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

  

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

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

但是,当身份验证失败时,实际上会从new InitialLdapContext(env, null)行引发异常。因此,不返回任何上下文,也不会在任何上下文中调用close。

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

正常搜索LDAP返回

NamingEnumeration<SearchResult> results

你还需要关闭():

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

答案 2 :(得分:0)

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

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

Hashtable<String,String> environment = new Hashtable<String,String>();
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