【问题标题】:Get RootDSE from Active Directory anonymously using Java JNDI classes使用 Java JNDI 类从 Active Directory 匿名获取 RootDSE
【发布时间】:2021-04-28 07:07:33
【问题描述】:

这个问题无疑是this one 的重复,但它没有答案。此外,您可能倾向于认为this answer 解决了问题,但事实并非如此。 (我怀疑那些回答的人实际上是否尝试过 Active Directory,他们可能尝试过其他一些 LDAP 实现)。

目标是检索 RootDSE, 无需与用户进行身份验证,即所谓的匿名连接。 (是的,AD 支持这个)

这是我尝试过的(使用 Java 8):

import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class MyMain {

    public static void main(String[] args) throws NamingException {
        Properties props = new Properties();
        props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        props.put(Context.PROVIDER_URL, "ldap://myadsrv.mynet.net:389");
        props.put(Context.SECURITY_AUTHENTICATION, "none"); // shouldn't be necessary, but just to make a point of it

        LdapContext ctx = new InitialLdapContext(props, null);

        // Force a bind on the connection
        ctx.reconnect(ctx.getConnectControls());

        // Get the RootDSE
        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
        searchControls.setReturningAttributes(new String[]{"namingContexts"});
        NamingEnumeration<SearchResult> result = ctx.search("", "objectClass=*", searchControls);
    }
}

无论我做什么,我总是会遇到以下异常。在上面的示例中,它将发生在最后一行,即ctx.search(....)。例外:

Exception in thread "main" javax.naming.NamingException: 
  [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C09072B, 
    comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v2580]; 
  remaining name ''

我尝试过其他工具,例如 Apache Directory Studio(开源 LDAP 浏览器,用 Java 编写)和 ldapsearch(来自OpenLDAP suite 的命令行工具),这些工具确实能够检索未经身份验证的 RootDSE。我已经使用 Wireshark 来弄清楚这些工具与我的 JNDI 实现的不同之处,并且可以看到一些差异,但我不太确定我完全理解 Wireshark 输出(并且不知道如何将其转换为 JNDI,因为后者是非常高级的,但 Wireshark 当然是非常低级的)。但至少证明了这是可能的。

【问题讨论】:

    标签: java active-directory ldap jndi


    【解决方案1】:

    Active Directory 不支持RFC 3296 指定的管理引用控制。如果匿名 LDAP 客户端在请求中一起发送它,则会导致 Active Directory 出现这种有点误导性的错误。

    不幸的是,Java JNDI 中的默认设置是随每个搜索请求一起发送 Manage Referral Control (OID = 2.16.840.1.113730.3.4.2)。

    最简单的解决办法是设置

    props.put(Context.REFERRAL, "throw");   // anything but 'ignore' will work
    

    这将阻止 Java JNDI 随每个请求发送 Manage Referral Control。

    我想我会选择throw,因为如果将请求推迟到其他地方,它可以完全控制请求的时间。将Context.REFERRAL 值设置为除ignore(默认值)之外的任何允许值将阻止JNDI LDAP 提供程序发送管理引用控制,从而使Active Directory 满意。

    Oracle JNDI Tutorial 中的更多信息确实提到(第一页底部)默认行为与 Active Directory 不兼容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多