获取连接重置在会话中存储/检索InitialLdapContext时出现异常

时间:2013-10-03 07:22:34

标签: java active-directory ldap jndi

我有一个网页页面来管理活动目录组,在这个页面的初始化中,我用jndi连接到ldap,并在http会话中保存ldap上下文。

这是我如何连接到ldap:

 public static LdapContext connectToLdap(String host,
            String userDN, String userPassword,
            boolean ssl) throws Exception {

        System.out.println("connectToLdap");

        String hostPrefix = "ldap";
        String ldapPort = "389";
        if (ssl) {
            hostPrefix = "ldaps";
            ldapPort = "636";
        }
        String providerUrl = hostPrefix + "://" + host + ":" + ldapPort;
        //System.out.println("####### LDAP URL: " + providerUrl);
        LdapContext ldapContext;
        Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
        ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        ldapEnv.put(Context.PROVIDER_URL, providerUrl);
        ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
        ldapEnv.put(Context.SECURITY_PRINCIPAL, userDN);
        ldapEnv.put(Context.SECURITY_CREDENTIALS, userPassword);
        ldapEnv.put("com.sun.jndi.ldap.read.timeout", 1000 * 10 + "");
        if (ssl) {
            ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
        }
        ldapEnv.put(Context.REFERRAL, "ignore");
        try {
            ldapContext = new InitialLdapContext(ldapEnv, null);           
            System.out.println("success connection to ldap");
            return ldapContext;
        } catch (Exception e) {
            System.out.println("failure connection to ldap");
            e.printStackTrace();
            return null;
        }
    }
  • 我不关闭上下文,因为它将在用户会话期间重用。
  • 我把ldapcontext放在会话中,这样我就不必每个用户经常联系ldap,每个用户每个会话只有一个连接。

问题:我注意到有时10-15分钟后,活动目录组的检索失败,我得到例外:

javax.naming.CommunicationException: Connection reset [Root exception is java.net.SocketException: Connection reset]

任何想法为什么?请告知我为什么会遇到此问题以及如何解决此问题。

1 个答案:

答案 0 :(得分:1)

不要将LdapContext放在HTTP会话中,它不会实现Serializable接口,因此不能保证它可以存储/恢复到会话。

考虑一下,如果会话要存储在数据库中或者复制到另一个服务器,LdapContext会被转换为字节,以及它引用的任何套接字描述符,当你从字节中恢复时它会如何工作?

如果你需要长期联系,请将它放在一个单身人士中。

除此之外,服务器和网络设备通常会关闭[他们认为的]非活动网络连接,因此任何长期连接都需要进行测试或保持活动状态。

如果它仍然相关我会建议您使用({3}} UnboundID LDAP SDK for Javaconnection的(GPLv2,LGPLv2.1许可)pooling(无关联)比运送的JNDI实现好一点。