Java、LDAP:让它不忽略空白密码?

Java、LDAP:让它不忽略空白密码?,java,ldap,Java,Ldap,我正在维护一些遗留的JavaLDAP代码。我对LDAP几乎一无所知 下面的程序基本上只是将用户ID和密码发送到LDAP服务器,如果凭据良好,则接收回通知。如果是,则打印从LDAP服务器接收的LDAP属性,如果不是,则打印异常 如果给出了错误的密码,所有这些都可以正常工作。引发“无效凭据”异常。但是,如果将空白密码发送到LDAP服务器,身份验证仍将发生,LDAP属性仍将返回 这种不愉快的情况是由于LDAP服务器允许使用空白密码,还是需要调整下面的代码?这样空白密码将以这样的方式馈送到LDAP服务器

我正在维护一些遗留的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

您需要将身份验证方法从简单更改为简单(这是而不是某种在生产环境中使用的方法,至少不需要SSL)

正如这里所述:

如果为Context.SECURITY\u CREDENTIALS环境属性提供空字符串、空字节/字符数组或null,则身份验证机制将为“无”。这是因为LDAP要求密码对于简单身份验证是非空的。如果未提供密码,协议会自动将身份验证转换为“无”


当您发送“空”密码时,身份验证(即绑定)以匿名方式完成

您的代码可以修改为检测到一个空密码或用户ID以停止此活动


一些LDAP实现可以停止任何匿名绑定。

有两种类型的绑定操作,
simple
SASL
。在简单绑定的情况下,有四种可能性:

  • 空DN和空密码:
    匿名
    ,不进行身份验证。这是初始状态,也是服务器收到绑定请求时的状态
  • 非空DN,空密码:
    未经身份验证
    ,不进行身份验证
  • 非空DN,非空密码:正常情况下,尝试身份验证
  • 空DN,非空密码:LDAP标准中未定义服务器行为。不进行身份验证
最初建立连接时,连接是匿名的。每个绑定请求都会将连接状态重置为
匿名
。每个成功的绑定请求都会将连接的授权状态更改为可分辨名称的授权状态。每个不成功的绑定请求都会使连接未经身份验证


BIND的语义在

中定义。不幸的是,使用DN和空密码进行身份验证是LDAP的一个难点,并且会导致服务器做出“未经身份验证”的肯定响应。 一些LDAP服务器具有配置选项来禁用最新版本的LDAPv3(RFC 4511)中不鼓励的行为,甚至在默认情况下将其禁用

最后,客户端应用程序应该检查输入参数并确保密码不是空的

亲切问候,


Ludovic

更改env.put(Context.SECURITY_AUTHENTICATION,“simple”)就足够了吗;到env.put(Context.SECURITY_身份验证,“strong”);?这会不会有意料之外的副作用?它只是关于接受/拒绝空白密码,还是会影响其他事情?我不确定,我们使用一些Novell类来连接ldap,但它没有说明这个值。您可能应该仔细阅读不同的autentication方法,您可能应该从这里开始:我将此作为本线程中第二个最有用的注释进行投票。非常感谢。谢谢,你告诉了我想知道的:除了对提交的密码进行严格的数据验证之外,我是否可以或应该做些什么。我试着用上面的代码切换到“strong”和“SASL”,结果得到一条异常消息,说(服务器?)不支持这种类型的身份验证。因此,由于服务器不支持任何其他功能,我可以继续了。