目前来自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是否成功?
答案 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