2016-06-06 17 views
0

Ich habe versucht, LDAP-Verbindungspooling mit Spring-Sicherheit und XML-basierte Konfiguration einzurichten.LDAP-Verbindungspooling mit Federsicherheit

Unten ist meine Konfiguration,

<authentication-manager id="authenticationManager"> 
     <ldap-authentication-provider server-ref="ldapServer" 
     user-dn-pattern="uid={0},ou=users" 
     group-search-filter="(&amp;(objectClass=groupOfUniqueNames)(uniqueMember={0}))" 
     group-search-base="ou=groups" 
     group-role-attribute="cn" 
     role-prefix="ROLE_" 
     user-context-mapper-ref="ldapContextMapperImpl"> 
     </ldap-authentication-provider> 
</authentication-manager> 

Wie stelle ich die alle Connection-Pooling-Konfiguration? Ich beabsichtige, PoolingContextSource-Klasse zu verwenden, da sie Eigenschaften zum Konfigurieren der Poolgröße usw. bereitstellt.

Antwort

1

Gepoolte Verbindungen funktionieren nicht mit der Authentifizierung, da die Authentifizierung bei der LDAP-Authentifizierung so funktioniert, dass die Verbindung beim Erstellen authentifiziert wird.

+0

Wenn dies der Fall ist, warum ist Manager DN und Passwort gegeben? Nach meinem Verständnis, Client verbindet sich mit dem LDAP-Server mit Manger DN und Passwort und später senden Bind-Anfrage, die den Benutzer dn und Passwort hat, die für die Authentifizierung verwendet wird. Also die erste Verbindung, die mit Hilfe von Manager-DN und Passwort erstellt wurde - ist es nicht gepoolt? – rpawar

+0

Wenn eine LDAP-basierte Authentifizierung über die BIND-Operation verwendet wird, erstellt auch in einer Webanwendung jeder angemeldete Benutzer eine eigene ldap-Verbindung. Dies würde zu vielen LDAP-Verbindungen führen. Gibt es keine Möglichkeit, einen Pool zu erstellen und Verbindungen für diese wiederzuverwenden? Wie stellen wir mindestens den Leerlauf oder Timeout für diese Verbindungen ein? – rpawar

+0

Die für jeden einzelnen Benutzer erstellte Verbindung sollte automatisch von der Spring LDAP-Infrastruktur geschlossen werden, sodass Sie sich keine Gedanken darüber machen müssen. Darüber hinaus wird eine Manager-LDAP-Verbindung erstellt und für die Suche nach dem Benutzer vor der Authentifizierung verwendet. Diese Verbindung wird ebenfalls automatisch geschlossen und dies sollte theoretisch möglich sein, um zu poolen, aber es scheint, dass der ldap-Server-XML dies nicht unterstützt. Das ldap-server-Element scheint jedoch nur eine ContextSource-Instanz zu erstellen. Sie könnten also versuchen, eine zu erstellen und diese stattdessen zu verwenden. – marthursson

0

Sie explizit entfernt Pooling für LDAP-Bindungen (oder im Frühjahr Fall ein authenticate):

https://github.com/spring-projects/spring-ldap/issues/216

ldapTemplate.authenticate sucht den Benutzer und ruft contextSource.getContext die LDAP-Bindung auszuführen.

private AuthenticationStatus authenticate(Name base, 
          String filter, 
          String password, 
          SearchControls searchControls, 
          final AuthenticatedLdapEntryContextCallback callback, 
          final AuthenticationErrorCallback errorCallback) { 

    List<LdapEntryIdentification> result = search(base, filter, searchControls, new LdapEntryIdentificationContextMapper()); 
    if (result.size() == 0) { 
     String msg = "No results found for search, base: '" + base + "'; filter: '" + filter + "'."; 
     LOG.info(msg); 
     return AuthenticationStatus.EMPTYRESULT; 
    } else if (result.size() > 1) { 
     String msg = "base: '" + base + "'; filter: '" + filter + "'."; 
     throw new IncorrectResultSizeDataAccessException(msg, 1, result.size()); 
    } 

    final LdapEntryIdentification entryIdentification = result.get(0); 

    try { 
     DirContext ctx = contextSource.getContext(entryIdentification.getAbsoluteName().toString(), password); 
     executeWithContext(new ContextExecutor<Object>() { 
      public Object executeWithContext(DirContext ctx) throws javax.naming.NamingException { 
       callback.executeWithContext(ctx, entryIdentification); 
       return null; 
      } 
     }, ctx); 
     return AuthenticationStatus.SUCCESS; 
    } 
    catch (Exception e) { 
     LOG.debug("Authentication failed for entry with DN '" + entryIdentification.getAbsoluteName() + "'", e); 
     errorCallback.execute(e); 
     return AuthenticationStatus.UNDEFINED_FAILURE; 
    } 
} 

Standardmäßig deaktivieren Kontextquellen das Pooling. Von AbstractContextSource.java (was LdapContextSource erbt von):

public abstract class AbstractContextSource implements BaseLdapPathContextSource, InitializingBean { 
... 
    public DirContext getContext(String principal, String credentials) { 
     // This method is typically called for authentication purposes, which means that we 
     // should explicitly disable pooling in case passwords are changed (LDAP-183). 
     return doGetContext(principal, credentials, EXPLICITLY_DISABLE_POOLING); 
    } 

    private DirContext doGetContext(String principal, String credentials, boolean explicitlyDisablePooling) { 
     Hashtable<String, Object> env = getAuthenticatedEnv(principal, credentials); 
     if(explicitlyDisablePooling) { 
      env.remove(SUN_LDAP_POOLING_FLAG); 
     } 

     DirContext ctx = createContext(env); 

     try { 
      authenticationStrategy.processContextAfterCreation(ctx, principal, credentials); 
      return ctx; 
     } 
     catch (NamingException e) { 
      closeContext(ctx); 
      throw LdapUtils.convertLdapException(e); 
     } 
    } 
... 
} 

Und wenn Sie die PoolingContextSource verwenden versuchen, dann werden Sie eine UnsupportedOperationException erhalten, wenn authenticategetContext zu nennen versucht:

public class PoolingContextSource 
     extends DelegatingBaseLdapPathContextSourceSupport 
     implements ContextSource, DisposableBean { 

... 
    @Override 
    public DirContext getContext(String principal, String credentials) { 
     throw new UnsupportedOperationException("Not supported for this implementation"); 
    } 
} 

Dieser Code ist von der spring-ldap-core 2.3.1.RELEASE Mavenartefakt.

Sie können weiterhin Verbindungspooling für ldap-Suchen mit der PoolingContextSource durchführen, aber Verbindungspooling für Authentifizierungen funktioniert nicht.