加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 此代码中的LDAP连接泄漏

发布时间:2020-12-15 08:32:15 所属栏目:Java 来源:网络整理
导读:有人可以解释一下为什么这段代码会随机“泄漏”LDAP连接吗?我可以看到已建立的TCP / IP连接数量随着时间的推移而增加,并且在某个阶段这会引发问题.我试着摆弄com.sun.jndi.ldap.connect环境属性(启用池,禁用它等)但它似乎没有帮助. 这意味着我的蹩脚代码已
有人可以解释一下为什么这段代码会随机“泄漏”LDAP连接吗?我可以看到已建立的TCP / IP连接数量随着时间的推移而增加,并且在某个阶段这会引发问题.我试着摆弄com.sun.jndi.ldap.connect环境属性(启用池,禁用它等)但它似乎没有帮助.

这意味着我的蹩脚代码已经有bug了.这应该如何做得更好,并确保我从不“泄漏”LDAP连接?

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class LdapUtil {
    private String ldap_context = "ou=myunit,dc=com";
    protected static String ldap_server = "ldap://ldapserver:389/";
    private String ldap_prefix = "(&(uid=";
    private String ldap_postfix = ")(objectclass=inetOrgPerson))";
    private String[] ldap_attributes = {"uid","departmentNumber","cn","postOfficeBox","mail"};
    private Properties ldap_properties;
    private SearchControls ldap_searchcontrols;
        private static String ldap_principal = "uid=bind_account,cn=users,ou=myunit,dc=com";
        private static String ldap_credentials = "qwerty";

    private List<String> getUserAttributes(final String userId) {
        List<String> UserAttributes = new ArrayList<String>();
        InitialDirContext ctx = null;
        NamingEnumeration<SearchResult> resultsEnum = null;
        NamingEnumeration<String> atrEnum = null;

        // Connect the LDAP
        try {
        ctx = new InitialDirContext(this.ldap_properties);
        // Prepare the query string
        String query = this.ldap_prefix+ userId+ this.ldap_postfix;
        // Query!
        resultsEnum = ctx.search(this.ldap_context,query,this.ldap_searchcontrols);

        // Enumerate the results
        while (resultsEnum.hasMore()) {
            SearchResult sr = (SearchResult) resultsEnum.nextElement();

            // Get all the attributes for a hit
            Attributes atr = sr.getAttributes();
            // Enumerate the attributes
            atrEnum = atr.getIDs();

            while (atrEnum.hasMore()) {
                    String nextid = atrEnum.nextElement();
                    String nextattribute = atr.get(nextid).toString();
                    UserAttributes.add(nextattribute);
            }

        }
        } catch ( Exception eom ) {
            System.out.println("LDAP exception");
        } finally {
            try {
                if (atrEnum!=null)
                atrEnum.close();
                if (resultsEnum!=null)
                resultsEnum.close();
                if (ctx!=null)
                ctx.close();
            } catch (NamingException eo) {
                // nothing
            } catch (NullPointerException eo) {
                // Nothing
            }
        } 
        return UserAttributes;
    }


    /*
     * Parses the LDAP search results and searches for selected attribute.
     */
    private String getAttribute (final List<String> attributes,final String attribuutti) {
        String result = null;
        // Let's go through all attributes
        for (int i = 0; i < attributes.size(); i++) {
            String attribute = attributes.get(i).toString();
            // Look for match
            if (attribute.startsWith(attribuutti)) {
                // Return the value after the space
                int k = attribute.indexOf(" ");
                result = attribute.substring(k+1,attribute.length());
            }
        }
        return result;
    }


    public LdapUtil(String remoteuser) {

        // Pre-initialize LDAP connection related properties
        this.ldap_properties = new Properties();
        this.ldap_properties.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        this.ldap_properties.put(Context.PROVIDER_URL,ldap_server) ;
        this.ldap_properties.put(Context.REFERRAL,"follow" );
        this.ldap_properties.put(Context.SECURITY_AUTHENTICATION,"simple");
        this.ldap_properties.put(Context.SECURITY_PRINCIPAL,ldap_principal);
        this.ldap_properties.put(Context.SECURITY_CREDENTIALS,ldap_credentials);
        this.ldap_properties.put("com.sun.jndi.ldap.read.timeout","10000");
        this.ldap_properties.put("com.sun.jndi.ldap.connect.timeout","10000");
        // Tried with both pooling and without - doesn't solve problems
        this.ldap_properties.put("com.sun.jndi.ldap.connect.pool","false");

        // Pre-initialize LDAP search controls
        this.ldap_searchcontrols = new SearchControls();
        this.ldap_searchcontrols.setSearchScope(SearchControls.SUBTREE_SCOPE);
        this.ldap_searchcontrols.setReturningAttributes(this.ldap_attributes);

            // The List for attributes
        List<String> attributes = null;

        attributes = getUserAttributes(remoteuser);
    }

}

解决方法

一个明显的问题是你的finally块是错误的. Ff close抛出异常,不会调用以下close方法.总是写下这样的代码:

final Res res = acquire();
try {
    use(res);
} finally {
    res.release();
}

即使这意味着嵌套尝试 – 终于.

(如果您使用的是旧版本的Sun JRE,则在例外情况下LDAP(和Kerberos)资源泄漏存在问题.“SunSolve” page)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读