【问题标题】:LDAP via JAVA without providing password通过 JAVA 进行 LDAP,无需提供密码
【发布时间】:2016-05-30 10:48:29
【问题描述】:

在 C# 中,我编写了以下代码来连接到 LDAP 服务器并进行相同的查询。

String ldapUrl = "LDAP://...";
            DirectoryEntry entry = new DirectoryEntry(ldapUrl);
            DirectorySearcher dSearch = new DirectorySearcher(entry);

            String Name = "ravi";
            dSearch.Filter = "(&(objectClass=user)(sAMAccountName=" + Name + "))";

            foreach (SearchResult sResultSet in dSearch.FindAll())
            {
                String data =  "Login Name :" + (GetProperty(sResultSet, "cn")) + "\r\n" +
                    "First Name :" + (GetProperty(sResultSet, "givenName")) + "\r\n" +
                    "Middle Initials :" + (GetProperty(sResultSet, "initials")) + "\r\n" +
                    "Last Name : " + (GetProperty(sResultSet, "sn"));
            }

如果您注意到,我没有在哪里提供用户名和/或密码。我认为它使用操作系统登录的用户凭据登录到 LDAP 服务器。

但在 JAVA 中

String url = "ldap://localhost:10389";
Hashtable env = new Hashtable();
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, "uid=admin,ou=system"***);
env.put(***Context.SECURITY_CREDENTIALS, "secret"***);

try {
    DirContext ctx = new InitialDirContext(env);
    System.out.println("connected");
    System.out.println(ctx.getEnvironment());

    ctx.close();

} catch (Exception ex) {
    System.out.println("error when trying to create the context");
}

java中有没有一种方法可以在不提供用户名和密码的情况下绑定到LDAP服务器?我尝试通过将 Context.SECURITY_AUTHENTICATION 设置为 NONE 来绑定,但它会引发不允许匿名登录的异常。我不使用匿名用户凭据,而是使用操作系统登录的用户凭据。

这可能吗?如何实现?

问候,

【问题讨论】:

  • 我假设您希望使用允许 Windows 操作系统提供凭据的 Windows 集成身份验证。挑战是从操作系统获取凭据。你的应用程序是基于 http 的吗?
  • 是的,Windows 集成身份验证,我们同时为应用程序客户端和基于 http 的服务提供服务。这是在 WAS 中运行的 Web 服务。 WAS 配置为 windows 服务,并配置为在有权查询 LDAP 的服务帐户下运行。应用程序将为我提供用户名。我只需要通过查询 LDAP 来确保这些用户可以访问我的服务。我知道可以将 WAS 配置为执行 AD 身份验证。但目前我们面临一些 cookie 问题,所以我无法使用它。
  • 那么,这在 JAVA 中是不可能的吗?嗯...我将不得不为 C# 编写 JNI 包装器:(
  • AFIK,是的,不确定您的详细信息。可能能够使用 JAAS 和 Kerberos,或者可能需要从 JNI 访问 LSA 或 SPPI。
  • 我使用 JNI 调用 C# dll ......问题是,JNI 很慢。每次通话大约需要 15-20 秒

标签: java c# ldap


【解决方案1】:

我使用 JNI 调用 C# dll...问题是 JNI 非常慢。每次通话大约需要 15-20 秒

【讨论】:

    【解决方案2】:

    使用命令行 (cmd),在 JAVA 中,:: 来自 stack Overflow Answer

    import com4j.Variant;
    import com4j.typelibs.ado20.ClassFactory;
    import com4j.typelibs.ado20._Command;
    import com4j.typelibs.ado20._Connection;
    import com4j.typelibs.ado20._Recordset;
    
    public static void queryADForComputers() throws Exception{
    
        String query            = "cn,sn,givenName,department";
        String filter           = "(&(objectclass=user)(objectcategory=person))";
        String namingContext    = "OU=Desktops,OU=Workstations,OU=HO,DC=win";
        _Connection conn        = ClassFactory.createConnection();
    
        conn.provider("ADsDSOObject");
        conn.open("Active Directory Provider","","",-1);
    
        _Command cmd            = ClassFactory.createCommand();
        cmd.activeConnection(conn);
        cmd.commandText("<LDAP://" + namingContext + ">;" + filter + ";" + query + ";subTree");
        _Recordset rs = cmd.execute(null, Variant.getMissing(), -1);
        System.out.println("Found " + rs.recordCount() + " users/computers/whatever i was looking for");
    
    //Then here you can use a while loop while(!rs.eof())
    //in which you can get each value as rs.fields().item(i).value();
    //in my case, i did rs.fields().item(i).value().toString()
    //or you can check for its type and go from there. 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 2023-03-27
      • 2013-01-19
      相关资源
      最近更新 更多