2012-02-07 14 views
20

Ho bisogno di eseguire una singola query LDAP che effettuerà una ricerca attraverso due unità organizzative specifiche (OU) nella query di root, ma ho un problema. Ho provato le seguenti domande di seguito e nessuno dei due ha avuto esito positivo:Sintassi di query radice LDAP per cercare più di un'unità utente specifica

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

La mia domanda è; è possibile interrogare più di una singola OU in una singola query? Supponendo che si tratti della sintassi corretta per questo tipo di espressione nella query LDAP di root.

+0

Se l'attributo 'ou' è consentito dalle objectClasses che comprendono le voci per le quali le ricerche client LDAP, l'attributo' ou' potrebbe essere utilizzato in un filtro di ricerca.Ovviamente, ciò richiede l'aggiunta dell'attributo 'ou' alle voci in questione. Questa potrebbe essere una soluzione efficace poiché AD non supporta l'eccellente suggerimento sotto dei filtri di corrispondenza estendibili. –

+0

Sarebbe bello se tu potessi contrassegnare la mia risposta come accettata dal momento che l'attuale accettata sembra ovviamente non del tutto valida (più?) E errata rispetto a AD e quindi in generale. Potrebbe essere valido solo per alcune implementazioni LDAP. –

risposta

11

È possibile !! ! In uso a breve questo come la stringa di connessione:

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

insieme con il filtro di ricerca, ad esempio,

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

che cercherà nel cosiddetto Global Catalog, che era stata disponibile out-of-the-box nel nostro ambiente.

Al posto delle note/comuni altre versioni (o loro combinazioni) che non ha funzionato nel nostro ambiente con più unità organizzative:

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) 

(Io sono uno sviluppatore, non un guru AD/LDAP:) Accidenti, ho cercato questa soluzione ovunque per quasi 2 giorni e ho quasi rinunciato, abituandomi all'idea di dover implementare questo scenario ovviamente molto comune a mano (con Jasperserver/Spring security (/ Tomcat)). (Quindi questo sarà un ricordo se qualcun altro o io dovrei avere ancora questo problema in futuro: O))

Ecco alcuni altri thread correlati che ho trovato durante la mia ricerca che era stato per lo più di scarso aiuto:

E qui mi fornirà ai nostri anonima di configurazione di Tomcat LDAP in caso può essere utile (/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

Ciao, ho lo stesso problema ma sto usando un codice diverso. Potresti leggere la mia domanda qui: http://stackoverflow.com/questions/42971315/finding-active-directory-users-from-2-ou – user2931442

2

Non penso sia possibile con AD. L'attributo distinguishedName è l'unica cosa che so che contiene il pezzo OU su cui stai cercando di cercare, quindi avrai bisogno di un carattere jolly per ottenere risultati per gli oggetti sotto quelle OU. Sfortunatamente, il carattere jolly isn't supported su DN.

Se possibile, vorrei davvero fare questo in 2 query usando OU = Staff ... e OU = Venditori ... come i DN di base.

+0

Sfortunatamente questo viene utilizzato da SharePoint come query di root per risolvere i membri e non posso cambiare SharePoint. – James

+0

Abbiamo avuto una situazione simile. Siamo stati in grado di risolverlo attraverso una combinazione di altri attributi: mail, useraccountcontrol, ecc. Che identificavano solo gli utenti che volevamo. – vinny

+1

Nel caso di SharePoint, perché non aggiungere semplicemente un'altra connessione di importazione con le OU come basi di ricerca? Ecco come fare per più foreste: http://technet.microsoft.com/en-us/library/cc263247(office.12).aspx – vinny

14

La risposta è NO non è possibile. Perché?

perché lo standard LDAP descrive una LDAP-ricerca come tipo di funzione con 4 parametri:

  1. Il nodo in cui la ricerca deve iniziare, che è un Distinguere Nome (DN)
  2. gli attributi desiderati essere riportata
  3. la profondità della ricerca (base, un livello, sottostruttura)
  4. il filtro

Sei interessato al filtro. Hai un riepilogo here (è fornito da Microsoft per Active Directory, è da uno standard). Il filtro è composto, in modo booleano, dall'espressione del tipo Attribute Operator Value.

Quindi il filtro che date non significa nulla.

Dal punto di vista teorico c'è ExtensibleMatch che consente i filtri buildind sul percorso DN, ma non è supportato da Active Directory.

Per quanto ne so, è necessario utilizzare un attributo in AD per distinguere gli utenti nelle due unità organizzative.

Può essere qualsiasi attributo discriminatore esistente o, ad esempio, l'attributo chiamato OU che è ereditato dalla classe organizationalPerson. è possibile impostare (non è automatico, e non sarà mantenuto se si sposta gli utenti) con "personale" per alcuni utenti e "venditori" per gli altri e li utilizzare il filtro:

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

Possiamo filtrare usando l'attributo distinguishedName come (distinguishedName = * OUPath)? –

+0

Qual è il modo migliore per popolare l'attributo OU? Stavo per scrivere uno script PS che viene eseguito quotidianamente e guarda l'unità organizzativa in cui si trova un utente, quindi scrive il valore OU univoco dell'attributo OU. Immagino che OU sia solo un nome e cambiarlo non influirà su qualcos'altro? – DevilWAH

+0

@DevilWAH, Se si ha uno sguardo allo schema, si tratta di una stringa di directory ed è facoltativo per organizationPerson o utente. – JPBlanc

4

E 'semplice. Basta cambiare la porta. Usa 3268 invece di 389. Se il tuo nome di dominio domain.local, alla ricerca messo DC = DOMINIO, DC = LOCAL

Port 3268: Questa porta è utilizzata per le query che sono specificamente mirati per il mondiale Catalogare. Le richieste LDAP inviate alla porta 3268 possono essere utilizzate per cercare oggetti nell'intera foresta. Tuttavia, è possibile restituire solo gli attributi contrassegnati per la replica nel catalogo globale.

Porta 389: Questa porta viene utilizzata per richiedere informazioni dal controller di dominio. Le richieste LDAP inviate alla porta 389 possono essere utilizzate per cercare oggetti solo all'interno del dominio home del catalogo globale. Tuttavia, l'applicazione può ottenere tutti gli attributi degli oggetti ricercati.

+1

Questa porta funziona con ldaps o ce n'è un'altra per questo? – gary69

+0

3268 è un testo in formato GC. 3269 è GC su SSL che è crittografato per impostazione predefinita. 389 è un testo normale AD. 636 è AD su SSL che è crittografato per impostazione predefinita. – frisbee23

1

Dopo aver parlato con un esperto LDAP, non è possibile in questo modo. Una query non può cercare più di un DC o OU.

Le opzioni disponibili sono:

  1. Esegui più di 1 query e analizzare il risultato.
  2. Utilizzare un filtro per trovare gli utenti/oggetti desiderati in base a un attributo diverso come un gruppo di annunci o per nome.