Синтаксис корневого запроса LDAP для поиска более одного определенного подразделения - PullRequest
24 голосов
/ 08 февраля 2012

Мне нужно выполнить один запрос 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.

Ответы [ 5 ]

18 голосов
/ 27 сентября 2013

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

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>))))

Это будет искать в так называемом Глобальном каталоге , который был доступен "из коробки" в нашей среде.

Вместо известных / распространенных других версий (или их комбинаций), которые НЕ работали в нашей среде с несколькими OU:

ldap://<host>/DC=<my>,DC=<domain>
ldap://<host>:389/DC=<my>,DC=<domain>  (standard port)
ldap://<host>/OU=<someOU>,DC=<my>,DC=<domain>
ldap://<host>/CN=<someCN>,DC=<my>,DC=<domain>
ldap://<host>/(|(OU=<someOU1>)(OU=<someOU2>)),DC=<my>,DC=<domain> (search filters here shouldn't work at all by definition)

(Я разработчик, а не гуру AD / LDAP :) Черт, я искал это решение везде почти 2 дня и почти сдался, привыкнув к мысли, что мне, возможно, придется реализовать этот, очевидно, очень распространенный сценарий. вручную (с помощью Jasperserver / Spring security (/ Tomcat)). (Так что это будет напоминанием, если у кого-то еще или у меня снова возникнет эта проблема в будущем: O))

Вот некоторые другие связанные темы, которые я нашел во время моего исследования, которые в основном мало помогали:

И здесь я предоставлю нашу анонимную конфигурацию 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 ############ -->

15 голосов
/ 08 февраля 2012

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

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

  1. Узел, с которого должен начинаться поиск, который является отличительным именем (DN)
  2. Атрибуты, которые вы хотите вернуть
  3. Глубина поиска (базовое, одноуровневое, поддерево)
  4. Фильтр

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

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

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

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

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

(&(objectCategory=person)(|(ou=staff)(ou=vendors)))
5 голосов
/ 27 января 2016

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

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

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

2 голосов
/ 08 февраля 2012

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

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

1 голос
/ 09 августа 2017

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

Возможны следующие варианты:

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