有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

连接Java 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 - closing from [ipaddress]:44724 - A1 - Client aborted connection -

他说,断开连接也是一种优雅的认证。我猜这是因为我在那种情况下做了ctx.close()

然而,当身份验证失败时,实际上会从new InitialLdapContext(env, null)行抛出一个异常。因此,不会返回任何上下文,也不会对任何上下文调用close

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


共 (3) 个答案

  1. # 1 楼答案

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

    这种方法的另一个好处是:可以维护一个上下文对象池,避免为了执行身份验证而不断连接/断开连接

    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
    
  2. # 2 楼答案

    搜索LDAP通常会返回

    NamingEnumeration<SearchResult> results
    

    您还需要关闭()

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

    为什么他会在意优雅和不优雅的亲密关系?很明显,你的结案是在唯一相关的案例中执行的:你成功的案例。在另一种情况下,没有什么要关闭的,所以你不能打电话。在另一种情况下,JNDI LDAP提供程序会关闭它,显然,正是它在进行流产关闭。在JNDI LDAP提供程序中,这些都是隐藏的。你对此无能为力。我建议他找点别的事来担心,这其实很重要