Синтаксис корневого запроса LDAP для поиска более чем одного конкретного подразделения

Мне нужно запустить один запрос LDAP, который будет выполнять поиск по двум конкретным организационным единицам (OU) в корневом запросе, однако мне очень сложно это сделать. Я пробовал следующие запросы ниже, и ни один из них не был успешным:

(|(OU=Staff,DC=my,DC=super,DC=org)(OU=Vendors,DC=my,DC=super,DC=org))

((OU=Staff,DC=my,DC=super,DC=org) | (OU=Vendors,DC=my,DC=super,DC=org))

Мой вопрос: возможно ли запросить более одного OU в одном запросе? Предполагая, что это то, что является правильным синтаксисом для этого типа выражения в корневом запросе LDAP.

Ответ 1

Вы можете!!! Вкратце используйте это как строку соединения:

ldap://<host>:3268/DC=<my>,DC=<domain>?cn

вместе с вашим фильтром поиска, например

(&(sAMAccountName={0})(&((objectCategory=person)(objectclass=user)(mail=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(memberOf:1.2.840.113556.1.4.1941:=CN=<some-special-nested-group>,OU=<ou3>,OU=<ou2>,OU=<ou1>,DC=<dc3>,DC=<dc2>,DC=<dc1>))))

Это будет поиск в так называемом решение, скрытое в комментарии LarreDo с 2006 года

какой-то Microsoft ответил на вопрос о лучших практиках как дизайн вашей организации в каталоге , заявив, что использование нескольких подразделений высшего уровня в крупных компаниях не является чем-то необычным или даже подходящим Tim Wong (2011) добавил, что эта может быть проблемой неразрешимых имен DNS в ForestDNSZones (часть используемого домена верхнего уровня AD) пример кода для его реализации вручную при использовании Spring безопасности (например, также используется в Jasper) John Morrissey (2012) предположил, что может быть связано с некоторыми настройками безопасности, и это может сработать, если вы используете TLS (я думаю если сервер LDAP хочет ограничить такие глобальные поиски небезопасных подключений - что не показало бы мне хорошего (своего рода полупеченого) подхода безопасности) awatkins (2012) использовал некоторый подход к взлому в коде mod_ldap.c (любого программного обеспечения )

И здесь я предоставлю нашу анонимную конфигурацию Tomcat LDAP, если она может быть полезной (/var/lib/tomcat7/webapps/jasperserver/WEB-INF/applicationContext-externalAUTH-LDAP.xml):

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<!-- ############ LDAP authentication ############ - Sample configuration 
    of external authentication via an external LDAP server. -->


<bean id="proxyAuthenticationProcessingFilter"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.BaseAuthenticationProcessingFilter">
    <property name="authenticationManager">
        <ref local="ldapAuthenticationManager" />
    </property>
    <property name="externalDataSynchronizer">
        <ref local="externalDataSynchronizer" />
    </property>

    <property name="sessionRegistry">
        <ref bean="sessionRegistry" />
    </property>

    <property name="internalAuthenticationFailureUrl" value="/login.html?error=1" />
    <property name="defaultTargetUrl" value="/loginsuccess.html" />
    <property name="invalidateSessionOnSuccessfulAuthentication"
        value="true" />
    <property name="migrateInvalidatedSessionAttributes" value="true" />
</bean>

<bean id="proxyAuthenticationSoapProcessingFilter"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.DefaultAuthenticationSoapProcessingFilter">
    <property name="authenticationManager" ref="ldapAuthenticationManager" />
    <property name="externalDataSynchronizer" ref="externalDataSynchronizer" />

    <property name="invalidateSessionOnSuccessfulAuthentication"
        value="true" />
    <property name="migrateInvalidatedSessionAttributes" value="true" />
    <property name="filterProcessesUrl" value="/services" />
</bean>

<bean id="proxyRequestParameterAuthenticationFilter"
    class="com.jaspersoft.jasperserver.war.util.ExternalRequestParameterAuthenticationFilter">
    <property name="authenticationManager">
        <ref local="ldapAuthenticationManager" />
    </property>
    <property name="externalDataSynchronizer" ref="externalDataSynchronizer" />

    <property name="authenticationFailureUrl">
        <value>/login.html?error=1</value>
    </property>
    <property name="excludeUrls">
        <list>
            <value>/j_spring_switch_user</value>
        </list>
    </property>
</bean>

<bean id="proxyBasicProcessingFilter"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.ExternalAuthBasicProcessingFilter">
    <property name="authenticationManager" ref="ldapAuthenticationManager" />
    <property name="externalDataSynchronizer" ref="externalDataSynchronizer" />

    <property name="authenticationEntryPoint">
        <ref local="basicProcessingFilterEntryPoint" />
    </property>
</bean>

<bean id="proxyAuthenticationRestProcessingFilter"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.DefaultAuthenticationRestProcessingFilter">
    <property name="authenticationManager">
        <ref local="ldapAuthenticationManager" />
    </property>
    <property name="externalDataSynchronizer">
        <ref local="externalDataSynchronizer" />
    </property>

    <property name="filterProcessesUrl" value="/rest/login" />
    <property name="invalidateSessionOnSuccessfulAuthentication"
        value="true" />
    <property name="migrateInvalidatedSessionAttributes" value="true" />
</bean>



<bean id="ldapAuthenticationManager" class="org.springframework.security.providers.ProviderManager">
    <property name="providers">
        <list>
            <ref local="ldapAuthenticationProvider" />
            <ref bean="${bean.daoAuthenticationProvider}" />
            <!--anonymousAuthenticationProvider only needed if filterInvocationInterceptor.alwaysReauthenticate 
                is set to true <ref bean="anonymousAuthenticationProvider"/> -->
        </list>
    </property>
</bean>

<bean id="ldapAuthenticationProvider"
    class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
    <constructor-arg>
        <bean
            class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
            <constructor-arg>
                <ref local="ldapContextSource" />
            </constructor-arg>
            <property name="userSearch" ref="userSearch" />
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean
            class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
            <constructor-arg index="0">
                <ref local="ldapContextSource" />
            </constructor-arg>
            <constructor-arg index="1">
                <value></value>
            </constructor-arg>

            <property name="groupRoleAttribute" value="cn" />
            <property name="convertToUpperCase" value="true" />
            <property name="rolePrefix" value="ROLE_" />
            <property name="groupSearchFilter"
                value="(&amp;(member={0})(&amp;(objectCategory=Group)(objectclass=group)(cn=my-nested-group-name)))" />
            <property name="searchSubtree" value="true" />
            <!-- Can setup additional external default roles here <property name="defaultRole" 
                value="LDAP"/> -->
        </bean>
    </constructor-arg>
</bean>

<bean id="userSearch"
    class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    <constructor-arg index="0">
        <value></value>
    </constructor-arg>
    <constructor-arg index="1">
        <value>(&amp;(sAMAccountName={0})(&amp;((objectCategory=person)(objectclass=user)(mail=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(memberOf:1.2.840.113556.1.4.1941:=CN=my-nested-group-name,OU=ou3,OU=ou2,OU=ou1,DC=dc3,DC=dc2,DC=dc1))))
        </value>
    </constructor-arg>
    <constructor-arg index="2">
        <ref local="ldapContextSource" />
    </constructor-arg>
    <property name="searchSubtree">
        <value>true</value>
    </property>
</bean>

<bean id="ldapContextSource"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.ldap.JSLdapContextSource">
    <constructor-arg value="ldap://myhost:3268/DC=dc3,DC=dc2,DC=dc1?cn" />
    <!-- manager user name and password (may not be needed) -->
    <property name="userDn" value="CN=someuser,OU=ou4,OU=1,DC=dc3,DC=dc2,DC=dc1" />
    <property name="password" value="somepass" />
    <!--End Changes -->
</bean>
<!-- ############ LDAP authentication ############ -->

<!-- ############ JRS Synchronizer ############ -->
<bean id="externalDataSynchronizer"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.ExternalDataSynchronizerImpl">
    <property name="externalUserProcessors">
        <list>
            <ref local="externalUserSetupProcessor" />
            <!-- Example processor for creating user folder -->
            <!--<ref local="externalUserFolderProcessor"/> -->
        </list>
    </property>
</bean>

<bean id="abstractExternalProcessor"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.processors.AbstractExternalUserProcessor"
    abstract="true">
    <property name="repositoryService" ref="${bean.repositoryService}" />
    <property name="userAuthorityService" ref="${bean.userAuthorityService}" />
    <property name="tenantService" ref="${bean.tenantService}" />
    <property name="profileAttributeService" ref="profileAttributeService" />
    <property name="objectPermissionService" ref="objectPermissionService" />
</bean>

<bean id="externalUserSetupProcessor"
    class="com.jaspersoft.jasperserver.api.security.externalAuth.processors.ExternalUserSetupProcessor"
    parent="abstractExternalProcessor">
    <property name="userAuthorityService">
        <ref bean="${bean.internalUserAuthorityService}" />
    </property>
    <property name="defaultInternalRoles">
        <list>
            <value>ROLE_USER</value>
        </list>
    </property>

    <property name="organizationRoleMap">
        <map>
            <!-- Example of mapping customer roles to JRS roles -->
            <entry>
                <key>
                    <value>ROLE_MY-NESTED-GROUP-NAME</value>
                </key>
                <!-- JRS role that the <key> external role is mapped to -->
                <value>ROLE_USER</value>
            </entry>
        </map>
    </property>
</bean>

<!--bean id="externalUserFolderProcessor" class="com.jaspersoft.jasperserver.api.security.externalAuth.processors.ExternalUserFolderProcessor" 
    parent="abstractExternalProcessor"> <property name="repositoryService" ref="${bean.unsecureRepositoryService}"/> 
    </bean -->

<!-- ############ JRS Synchronizer ############ -->

Ответ 2

Ответ НЕТ, вы не можете. Почему?

Поскольку стандарт LDAP описывает LDAP-SEARCH как функцию с 4 параметрами:

  • node, где должен начинаться поиск, который является Distinguish Name (DN)
  • Атрибуты, которые вы хотите вернуть
  • Глубина поиска (базовая, одноуровневая, поддерево)
  • Фильтр

Вас интересует фильтр. У вас есть сводка здесь (она предоставлена ​​Microsoft для Active Directory, это со стандарта). Фильтр формируется логическим способом посредством выражения типа Attribute Operator Value.

Итак, фильтр, который вы даете, ничего не значит.

С теоретической точки зрения существует ExtensibleMatch, который позволяет создавать фильтры на пути DN, но не поддерживается Active Directory.

Насколько я знаю, вы должны использовать атрибут в AD, чтобы сделать различие для пользователей в двух подразделениях.

Это может быть любой существующий атрибут дискриминатора, или, например, атрибут, называемый OU, который наследуется от класса organizationalPerson. вы можете установить его (он не автоматический и не будет поддерживаться, если вы переместите пользователей) с "персоналом" для некоторых пользователей и "поставщиков" для других, и они используют фильтр:

(&(objectCategory=person)(|(ou=staff)(ou=vendors)))

Ответ 3

Это просто. Просто измените порт. Используйте 3268 вместо 389. Если ваше доменное имя DOMAIN.LOCAL, в поиске положите DC = DOMAIN, DC = LOCAL

Порт 3268: Этот порт используется для запросов, специально предназначенных для глобального каталога. Запросы LDAP, отправленные на порт 3268, могут использоваться для поиска объектов во всем лесу. Однако могут возвращаться только атрибуты, помеченные для репликации в глобальный каталог.

Порт 389: Этот порт используется для запроса информации от контроллера домена. Запросы LDAP, отправленные на порт 389, могут использоваться для поиска объектов только в домашнем домене глобальных каталогов. Тем не менее, приложение может получить все найденные объекты атрибутов.

Ответ 4

Я не думаю, что это возможно с AD. Атрибут distinctName - это единственное, что я знаю о том, что содержит часть OU, на которую вы пытаетесь выполнить поиск, поэтому вам понадобится шаблон для получения результатов для объектов под этими подразделениями. К сожалению, подстановочный знак не поддерживается в DN.

Если это вообще возможно, я бы действительно посмотрел на это в двух запросах, используя OU = Staff... и OU = Vendors... в качестве базовых DN.

Ответ 5

После разговора с экспертом LDAP это невозможно. Один запрос не может искать более одного DC или OU.

Ваши варианты:

  • Запустите более одного запроса и проанализируйте результат.
  • Используйте фильтр, чтобы найти желаемых пользователей/объектов на основе другого атрибута, такого как группа AD или по имени.