Active Directory中不支持NamingListener?

时间:2013-10-09 20:33:41

标签: java active-directory ldap jndi spring-ldap

我正在尝试运行:

    Map<String, String> environmentProperties = new HashMap<String, String>();
    environmentProperties.put("java.naming.security.authentication", "simple");
    environmentProperties.put("java.naming.ldap.attributes.binary", "tokenGroups objectSid");

    LdapContextSource contextSource = new LdapContextSource();
    contextSource.setAnonymousReadOnly(false);
    contextSource.setPooled(false);

    contextSource.setUserDn("CN=Administrator,CN=Users,DC=someDomain,DC=com");
    contextSource.setPassword("password");

    contextSource.setUrls(new String[]{"ldap://url.goes.here"});
    contextSource.setBaseEnvironmentProperties(environmentProperties);
    contextSource.setDirObjectFactory(null);
    contextSource.afterPropertiesSet();

    final SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    ContextExecutor contextExecutor = new ContextExecutor() {
       public Object executeWithContext(DirContext ctx) throws NamingException {
          EventDirContext ectx = (EventDirContext) ctx.lookup("CN=Users,,DC=someDomain,DC=com");
          ectx.addNamingListener("", "(cn=*)", searchControls, new LDAPChangeListener());
          return null;
       }
    };


    LdapTemplate ldapTemplate = new LdapTemplate(contextSource);
    ldapTemplate.setIgnorePartialResultException(true);

    ldapTemplate.executeReadOnly(contextExecutor);

但是,我的听众得到的第一条消息是:

  

javax.naming.OperationNotSupportedException:[LDAP:错误代码12 - 00000057:LdapErr:DSID-0C090753,注释:处理控制错误,数据0,v1db1];剩下的名字''       at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3127)       在com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3013)       在com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2820)       在com.sun.jndi.ldap.LdapNamingEnumeration.getNextBatch(LdapNamingEnumeration.java:129)

我还运行了这个代码,我发现here应该验证我的AD支持持久搜索,结果是真的。

static boolean isPersistentSearchSupported(LdapContext rootContext)
        throws NamingException {
    SearchResult rootDSE;
    NamingEnumeration searchResults;
    Attributes attrs;
    NamingEnumeration attrEnum;
    Attribute attr;
    NamingEnumeration values;
    String value;
    String[] attrNames = { "supportedControl" };
    SearchControls searchControls = new SearchControls();

    searchControls.setCountLimit(0); // 0 means no limit
    searchControls.setReturningAttributes(attrNames);
    searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);

    // search for the rootDSE object
    searchResults = rootContext.search("", "(objectClass=*)",
            searchControls);

    while (searchResults.hasMore()) {
        rootDSE = (SearchResult) searchResults.next();

        attrs = rootDSE.getAttributes();
        attrEnum = attrs.getAll();
        while (attrEnum.hasMore()) {
            attr = (Attribute) attrEnum.next();
            values = attr.getAll();
            while (values.hasMore()) {
                value = (String) values.next();
                if (value.equals("1.2.840.113556.1.4.528"))
                    return true;
            }
        }
    }
    return false;
}

从AD开始获取事件需要做什么?

3 个答案:

答案 0 :(得分:1)

根据documentation,范围不能为Subtree,搜索过滤器必须为(objectClass=*)才能进行持久搜索。

答案 1 :(得分:1)

更新: 我发现了这个:https://forums.oracle.com/thread/1157474?tstart=0 它基本上说AD不支持这个,并且我无法使上述代码工作。 但是,它确实提供了两种从AD获取此类通知的方法:

  1. 使用DirSync-我尝试了附加的代码,它没有用,但没有继续调查将在本文末尾列出的原因。
  2. 使用LDAP通知(https://forums.oracle.com/message/4698114) - 此代码有效,但是,它只返回创建/更改事件的结果,一旦对象被删除就不会通知,并且无法通过此方法获取它因为搜索过滤器无法更改,因为任何其他过滤器都不起作用。所以它不符合我的目的,但也许其他人觉得它很有用。
  3. 我认为DirSync可能是我唯一可行的解​​决方案,如果有的话。 但是,应该注意DirSync具有以下限制:

    • DirSync控件只能由权限较高的帐户使用,例如域管理员。
    • DirSync控件只能监视整个命名上下文。您不能限制DirSync搜索的范围,以仅在命名上下文中监视特定的子树,容器或对象。

    我希望这些信息将来可以帮助其他人。

答案 2 :(得分:0)

我想在几年前就这个主题进行研究之后,就这个主题添加一些额外的信息。

JNDI提供的NamingListener功能。如果您尝试在任何LDAP服务器上注册NamingListener,则该服务器必须支持“Persistent Search”扩展名。持久搜索扩展一直处于IETF草案阶段,因此没有正式的RFC#关联它。

很多LDAP服务器都不支持此扩展。我上一次研究这个主题是2008年,支持持久搜索扩展的LDAP服务器是389 Directory ServerOracle Internet Directory (OID)和OpenDS(现在称为OpenDJ)。

http://www-archive.mozilla.org/directory/ietf-docs/draft-smith-psearch-ldap-01.txt

http://www.redhat.com/archives/fedora-directory-users/2008-May/msg00120.html