5

現在、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は呼び出されません。

認証を試みる前に、ある種の接続オブジェクトを取得して、認証が成功したかどうかに関係なく、後でそれを閉じることができるようにする方法はありますか?

4

3 に答える 3

3

なぜ彼は優雅な接近と非優雅な接近の間を気にするのですか?明らかに、あなたのクローズは、あなたが成功した場合という唯一の関連するケースで実行されています。他の場合、閉じるものがないので、呼び出すことはできません。他の場合、JNDI LDAPプロバイダーはそれを閉じます、そして明らかにそれは中途半端な閉じをしているものです。これはすべて、JNDILDAPプロバイダーの内部にあります。あなたがそれについてできることは何もありません。私は彼がそれが実際に重要であることを心配する何か他のものを見つけることを提案します。

于 2013-01-24T23:57:46.217 に答える
2

LDAPを検索すると、通常は

NamingEnumeration<SearchResult> results

また、close()する必要があります:

} finally {
            if(results != null) {
                try {
                    results.close();
                } catch (NamingException e) {
                    LOG.error("Error closing LDAP results", e);
                }
            }
于 2014-09-24T12:54:48.937 に答える
0

認証の詳細を追加する前に、コンテキストオブジェクトを作成します。次に、addToEnvironmentを使用して資格情報を追加します。最後に、非常に単純な検索を実行します(私のアプローチは、ユーザー名の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
于 2016-02-17T01:24:43.970 に答える