LDAP 连接池中的上下文是否需要显式关闭

问题描述 投票:0回答:2

我们正在使用以下 LDAP JNDI 连接池设置:

    DirContext ctx = null;
    try 
    {
        Hashtable<String, String> env = new Hashtable<String, String>();

        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldaps://" + server + ":" + serverPort);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, pUserName);
        env.put(Context.SECURITY_CREDENTIALS, pPassword);
        env.put(LdapContext.CONTROL_FACTORIES, "com.sun.jndi.ldap.ControlFactory");
        env.put(Context.SECURITY_PROTOCOL, "ssl");
        env.put("com.sun.jndi.ldap.read.timeout", "300000");

        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

        // load the location of keystore that holds trusted root certificates from web.xml
        ServletContext context = ApplicationServlet.getApplication().getServlet().getServletContext();
        String certificatePath = context.getInitParameter("AD_CERTIFICATE_PATH");

        System.setProperty("javax.net.ssl.trustStore",  certificatePath);
        //          System.setProperty("javax.net.debug", "all");

        // For connection pooling
        env.put("com.sun.jndi.ldap.connect.pool", "true");
        System.setProperty("com.sun.jndi.ldap.connect.pool.protocol", "plain ssl");
        System.setProperty("com.sun.jndi.ldap.connect.pool.maxsize", poolMaxSize);
        System.setProperty("com.sun.jndi.ldap.connect.pool.prefsize", poolPrefSize);
        System.setProperty("com.sun.jndi.ldap.connect.pool.timeout", poolTimeOut);
        System.setProperty("com.sun.jndi.ldap.connect.pool.debug", "fine");

        ctx = new InitialDirContext(env);
        return (DirContext) ctx;

在 Active Directory 中执行搜索后,我们将使用

ctx.close()
显式关闭上下文以将连接释放回池。

通过上述实现,我们面临着连接在获得连接后立即关闭的问题:

12:06:14,837 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-22) Create and use com.sun.jndi.ldap.LdapClient@26a2a0eb[eun1p3-be.stp-prod.st.com:636]
12:06:16,855 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-22) Close com.sun.jndi.ldap.LdapClient@26a2a0eb
12:06:18,301 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-23) Create and use com.sun.jndi.ldap.LdapClient@76e26d4a[eun1p3-be.stp-prod.st.com:636]
12:06:20,353 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-23) Close com.sun.jndi.ldap.LdapClient@76e26d4a
12:06:21,713 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-19) Create and use com.sun.jndi.ldap.LdapClient@4bb50913[eun1p3-be.stp-prod.st.com:636]
12:06:23,746 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-19) Close com.sun.jndi.ldap.LdapClient@4bb50913
12:06:25,366 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-6) Create and use com.sun.jndi.ldap.LdapClient@2a2eecb7[eun1p3-be.stp-prod.st.com:636]
12:06:27,473 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-6) Close com.sun.jndi.ldap.LdapClient@2a2eecb7
12:06:28,757 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-25) Create and use com.sun.jndi.ldap.LdapClient@3c34b0d[eun1p3-be.stp-prod.st.com:636]
12:06:30,855 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-25) Close com.sun.jndi.ldap.LdapClient@3c34b0d
12:06:32,214 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-22) Create and use com.sun.jndi.ldap.LdapClient@6d9ca028[eun1p3-be.stp-prod.st.com:636]
12:06:34,294 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-22) Close com.sun.jndi.ldap.LdapClient@6d9ca028
12:06:35,730 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-23) Create and use com.sun.jndi.ldap.LdapClient@72ed6bb2[eun1p3-be.stp-prod.st.com:636]
12:06:37,753 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-23) Close com.sun.jndi.ldap.LdapClient@72ed6bb2
12:06:39,184 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-19) Create and use com.sun.jndi.ldap.LdapClient@e87ce30[eun1p3-be.stp-prod.st.com:636]
12:06:41,266 ERROR [stderr] (http-eul151.sgp.st.com-10.75.32.13-10080-19) Close com.sun.jndi.ldap.LdapClient@e87ce30
active-directory ldap jndi
2个回答
3
投票

是的,您不仅要关闭所有

Contexts
,还要关闭所有
NamingEnumerations
。这就是连接返回池的方式。

您的日志中没有证据表明连接正在关闭。关闭的是

com.sun.jndi.ldap.LdapClients.


0
投票

我还在我的一个应用程序中使用 LDAP 实现,JDK 是 17。

当我尝试通过带参数的命令独立运行此类文件时,它会成功运行

命令:

java LdapIntegration 178258

但是当我将其放入我们的应用程序服务器(JBoss EAP 7.4)时,它开始给我错误:

Exception Message: javax.naming.NamingException: WFLYNAM0027: Failed instantiate InitialContextFactory com.sun.jndi.ldap.LdapCtxFactory from classloader ModuleClassLoader for Module "deployment.ABC.war" from Service Module Loader [Root exception is java.lang.IllegalAccessException: class org.jboss.as.naming.InitialContext cannot access class com.sun.jndi.ldap.LdapCtxFactory (in module java.naming) because module java.naming does not export com.sun.jndi.ldap to unnamed module @4b488eb5]

经过多次努力,我将以下行放入standalone.conf文件中

JAVA_OPTS="$JAVA_OPTS --add-opens=java.naming/com.sun.jndi.ldap=ALL-UNNAMED"

执行上述命令后,问题消失,但我的 jboss 宕机了。

下面是代码片段

    Hashtable env = new Hashtable();
            env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
            env.put("java.naming.provider.url", "ldap://IP:PORT");
            env.put("com.sun.jndi.ldap.connect.timeout", "60000");
            env.put("java.naming.security.authentication", "simple");
            env.put("java.naming.security.principal", "dummy\\"+userid.trim());

try {
            ctx = new InitialDirContext(env);
        }catch(Exception e1) {
            System.out.println("Naming Exception" + e1);
        }
        
        SearchControls searchcontrols = new SearchControls();
        searchcontrols.setSearchScope(2);

        String s1 = "DC=" + "DUMMY2" + ",DC=com";
        String s2 = "(&(sAMAccountName=" + userid + ")( distinguishedName=*))";
        NamingEnumeration results = null;

        Map<String, String> finalRecord = new Hashtable<>();

        try {
            results = ctx.search(s1, s2, searchcontrols);
            System.out.println("results in String " + results.toString());
            System.out.println("results " + results);

            while (results.hasMore()) {
                
                SearchResult searchResult = (SearchResult) results.next();
                Attributes attributes = searchResult.getAttributes();
                
                System.out.println("attributes "+attributes.toString());
}
        } catch (NamingException e) {

        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                }
            }
        }
© www.soinside.com 2019 - 2024. All rights reserved.