2012-02-07 12 views
20

Necesito ejecutar una única consulta LDAP que buscará a través de dos unidades organizativas (OU) específicas en la consulta raíz, pero estoy teniendo problemas. He intentado las siguientes consultas a continuación y ninguno fue exitoso:Sintaxis de consulta de raíz LDAP para buscar más de una unidad organizativa específica

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

Mi pregunta es; ¿es posible consultar más de una unidad organizativa única en una sola consulta? Suponiendo que es la sintaxis adecuada para este tipo de expresión en la consulta LDAP raíz.

+0

Si el atributo 'ou' está permitido por las objectClasses que comprenden las entradas para las que las búsquedas cliente LDAP, el atributo' ou' podría ser utilizado en un filtro de búsqueda.Por supuesto, esto requiere agregar el atributo 'ou' a las entradas en cuestión. Esta podría ser una solución efectiva ya que AD no es compatible con la excelente sugerencia a continuación de filtros de coincidencia extensibles. –

+0

Sería bueno si pudiera marcar mi respuesta como la aceptada ya que la actualmente aceptada parece obviamente no completamente válida (¿ya?) E incorrecta con respecto a AD y, por lo tanto, en general. Puede ser válido solo para algunas implementaciones de LDAP. –

Respuesta

11

Usted puede !! ! En resumen utilizar esto como la cadena de conexión:

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

junto con el filtro de búsqueda, por ejemplo,

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

que buscará en el llamado Global Catalog, que había estado disponible fuera de la caja en nuestro entorno.

En lugar de los conocidos/otras versiones comunes (o combinaciones de los mismos) que no funcionaba en nuestro entorno con varias unidades organizativas:

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) 

(Soy un desarrollador, no un gurú de AD/LDAP: Maldición, había estado buscando esta solución en todas partes durante casi 2 días y casi me rindo, acostumbrándome a la idea de implementar este escenario obviamente muy común a mano (con Jasperserver/Spring security (/ Tomcat)). (Así que este será un recordatorio si alguien o yo debería tener de nuevo este problema en el futuro: O))

Aquí algunos otros temas relacionados que encontré durante mi investigación que había sido en su mayoría de poca ayuda:

Y aquí voy a proporcionar a nuestros anónimos de configuración de Tomcat LDAP en caso de que puede ser útil (/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 ############ --> 

+0

Hola, tengo el mismo problema pero estoy usando un código diferente. ¿Podría leer mi pregunta aquí: http://stackoverflow.com/questions/42971315/finding-active-directory-users-from-2-ou – user2931442

2

No creo que esto sea posible con AD. El atributo distinguishedName es lo único que sé que contiene la pieza OU en la que está intentando buscar, por lo que necesitaría un comodín para obtener resultados para objetos bajo esas OU. Lamentablemente, el carácter comodín isn't supported en DN.

Si es posible, realmente consideraría hacer esto en 2 consultas usando OU = Staff ... y OU = Vendors ... como los DN base.

+0

Desafortunadamente, SharePoint lo utiliza como la consulta raíz para resolver miembros y no puedo cambiar SharePoint. – James

+0

Tuvimos una situación similar. Pudimos resolverlo a través de una combinación de otros atributos: correo, control de cuentas de uso, etc. que identificaban solo a los usuarios que queríamos. – vinny

+1

En el caso de SharePoint, ¿por qué no simplemente agregar otra conexión de importación con las unidades organizativas como bases de búsqueda? He aquí cómo hacerlo para varios bosques: http://technet.microsoft.com/en-us/library/cc263247(office.12).aspx – vinny

14

La respuesta es NO, no puedes. ¿Por qué?

Debido a que el estándar LDAP describe un LDAP-BUSCAR como una especie de función de 4 parámetros:

  1. El nodo donde la búsqueda debe comenzar, que es un nombre Distinguir (DN)
  2. los atributos que desea para ser traído de nuevo
  3. la profundidad de la búsqueda (base, de un nivel, subárbol)
  4. el filtro

Usted está interesado en el filtro. Tiene un resumen here (es proporcionado por Microsoft para Active Directory, es de un estándar). El filtro está compuesto, de forma booleana, por una expresión del tipo Attribute Operator Value.

Así que el filtro que proporcione no significa nada.

En el punto de vista teórico existe ExtensibleMatch que permite filtros buildind en la ruta DN, pero no es compatible con Active Directory.

Hasta donde yo sé, debe usar un atributo en AD para hacer la distinción para los usuarios en las dos unidades organizativas.

Puede ser cualquier atributo discriminador existente, o, por ejemplo, el atributo llamado OU que se hereda de la clase organizationalPerson. se puede establecer (no es automático, y no se mantendrá si mueve los usuarios) con "personal" para algunos usuarios y "vendedores" de los demás y les utilizar el filtro:

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

¿Podemos filtrar utilizando el atributo distinguishedName como (distinguishedName = * OUPath)? –

+0

¿Cuál es la mejor manera de poblar el atributo OU? Iba a escribir una secuencia de comandos de PS que se ejecuta a diario y examina la unidad organizativa en la que se encuentra el usuario y luego escribe el valor de unidad organizativa única en el atributo OU. ¿Supongo que OU es solo un nombre y cambiarlo no afectará a nada más? – DevilWAH

+0

@DevilWAH, si echas un vistazo al esquema, es una cadena de directorio, y es facultativo para organizationalPerson o usuario. – JPBlanc

4

Es muy sencillo. Solo cambia el puerto. Utilice 3268 en lugar de 389. Si su nombre de dominio domain.local, en busca poner DC = dominio DC = local

puerto 3268: Este puerto se utiliza para las consultas que están dirigidos específicamente para el mundial catalogar. Las solicitudes LDAP enviadas al puerto 3268 se pueden usar para buscar objetos en todo el bosque. Sin embargo, solo se pueden devolver los atributos marcados para la replicación en el catálogo global.

Puerto 389: Este puerto se utiliza para solicitar información del controlador de dominio. Las solicitudes LDAP enviadas al puerto 389 se pueden usar para buscar objetos solo dentro del dominio principal del catálogo global. Sin embargo, la aplicación puede obtener todos los atributos de los objetos buscados.

+1

¿Este puerto funciona con ldaps o hay otro para eso? – gary69

+0

3268 es texto simple de GC. 3269 es GC sobre SSL que está encriptado de manera predeterminada. 389 es texto sin formato de AD. 636 es AD sobre SSL que está encriptado de forma predeterminada. – frisbee23

1

Después de hablar con un experto de LDAP, no es posible de esta manera. Una consulta no puede buscar más de un DC u OU.

Las opciones son:

  1. Ejecutar más de 1 consulta y analizar el resultado.
  2. Utilice un filtro para buscar los usuarios/objetos deseados basándose en un atributo diferente como un grupo de AD o por su nombre.
Cuestiones relacionadas