18

いくつかのレガシーJavaLDAPコードを維持しています。LDAPについてはほとんど何も知りません。

以下のプログラムは、基本的にユーザーIDとパスワードをLDAPサーバーに送信し、資格情報が適切かどうかを通知します。その場合、LDAPサーバーから受信したLDAP属性を出力し、そうでない場合は例外を出力します。

間違ったパスワードが与えられた場合、すべてがうまく機能します。「無効な資格情報」例外がスローされます。ただし、空白のパスワードがLDAPサーバーに送信された場合でも、認証は行われ、LDAP属性は引き続き返されます。

LDAPサーバーが空白のパスワードを許可しているためにこの不幸な状況ですか、それとも以下のコードを調整する必要がありますか?空白のパスワードがLDAPサーバーに送られ、拒否されますか?

私はデータ検証を実施しています。別の問題を解決するためにテスト環境でそれを外し、この問題に気づきました。私は、データ検証の下でこの問題が発生しないようにしたいと思います。

情報をよろしくお願いします

import javax.naming.*;
import javax.naming.directory.*;
import java.util.*;
import java.sql.*;

public class LDAPTEST {

    public static void main(String args[]) {

        String lcf                = "com.sun.jndi.ldap.LdapCtxFactory";
        String ldapurl            = "ldaps://ldap-cit.smew.acme.com:636/o=acme.com";
        String loginid            = "George.Jetson";
        String password           = "";
        DirContext ctx            = null;
        Hashtable env             = new Hashtable();
        Attributes attr           = null;
        Attributes resultsAttrs   = null;
        SearchResult result       = null;
        NamingEnumeration results = null;
        int iResults              = 0;
        int iAttributes           = 0;


        env.put(Context.INITIAL_CONTEXT_FACTORY, lcf);
        env.put(Context.PROVIDER_URL, ldapurl);
        env.put(Context.SECURITY_PROTOCOL, "ssl");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "uid=" + loginid + ",ou=People,o=acme.com");
        env.put(Context.SECURITY_CREDENTIALS, password);
        try {

            ctx     = new InitialDirContext(env);
            attr    = new BasicAttributes(true);
            attr.put(new BasicAttribute("uid",loginid));
            results = ctx.search("ou=People",attr);

            while (results.hasMore()) {
                result       = (SearchResult)results.next();
                resultsAttrs = result.getAttributes();

                for (NamingEnumeration enumAttributes  = resultsAttrs.getAll(); enumAttributes.hasMore();) {
                    Attribute a = (Attribute)enumAttributes.next();
                    System.out.println("attribute: " + a.getID() + " : " + a.get().toString());
                    iAttributes++;


                }// end for loop

                iResults++;
            }// end while loop

            System.out.println("Records  == " + iResults + " Attributes: " + iAttributes);

        }// end try
        catch (Exception e) {
            e.printStackTrace();
        }



    }// end function main()
}// end class LDAPTEST
4

4 に答える 4

21

残念ながら、DNと空のパスワードを使用した認証は、LDAPの欠点の1つであり、サーバーからの「認証されていない」肯定応答が発生します。一部のLDAPサーバーには、LDAPv3の最新リビジョン(RFC 4511)で推奨されていない動作を無効にする構成オプションがあり、デフォルトで無効になっている場合もあります。

最終的に、クライアントアプリケーションは入力パラメータをチェックし、パスワードが空でないことを確認する必要があります。

于 2012-09-11T13:21:14.537 に答える
9

認証方法を単純なものから変更する必要があります(これは、少なくともSSLなしでは、実稼働環境で使用するものではありません)。

ここに記載されているように:http://docs.oracle.com/javase/jndi/tutorial/ldap/security/simple.html

空の文字列、空のバイト/文字配列、またはnullをContext.SECURITY_CREDENTIALS環境プロパティに指定すると、認証メカニズムは「none」になります。これは、LDAPでは、単純な認証のためにパスワードが空でないことが必要なためです。パスワードが指定されていない場合、プロトコルは認証を自動的に「なし」に変換します。

于 2012-09-10T22:19:49.027 に答える
4

BIND操作には2つのタイプがありsimpleますSASL。単純なBINDの場合、次の4つの可能性があります。

  • 空のDNと空のパスワード:anonymous、認証は行われません。これは初期状態であり、BIND要求がサーバーによって受信されたときの状態でもあります。
  • 空でないDN、空のパスワード:unauthenticated、認証は行われません
  • 空でないDN、空でないパスワード:通常の場合、認証が試行されます
  • 空のDN、空でないパスワード:サーバーの動作はLDAP標準で定義されていません。認証は行われません。

接続が最初に確立されるとき、接続はですanonymous。各BIND要求は、接続状態をにリセットしますanonymous。BIND要求が成功するたびに、接続の許可状態が識別名の許可状態に変更されます。BIND要求が失敗するたびに、接続は認証されないままになります。

BINDのセマンティクスは、LDAPで定義されています:認証

于 2012-09-11T12:29:55.093 に答える
1

「空の」パスワードを送信すると、認証(つまりバインド)が匿名で行われるようになります。

このアクティビティを停止するために、空のパスワードまたはユーザーIDを検出するようにコードを変更できます。

一部のLDAP実装は、匿名バインドを停止できます。

于 2012-09-11T10:27:18.637 に答える