Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Пул соединений LDAP с Spring Security

Автор вопроса: r_pawarОтветов: 2

Я пытался настроить пул соединений LDAP, используя Spring Security и конфигурацию на основе xml.

Ниже моя конфигурация,

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

Как предоставить всю конфигурацию пула соединений? Я собираюсь использовать класс PoolingContextSource, поскольку он предоставляет свойства для настройки размера пула и т. д.

springspring-securityconnection-poolingspring-ldap

Ответы

Ответ 1 · рейтинг 1 · marthursson

Соединения в пуле не работают с аутентификацией, потому что аутентификация LDAP работает так, что подключение аутентифицируется при создании.

Ответ 2 · рейтинг 2 · trung

Они явно удалили объединение для привязок ldap (или, в случае Spring, authenticate):

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

ldapTemplate.authenticate ищет пользователя и вызывает contextSource.getContext для выполнения привязки ldap.

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;
    }
}

По умолчанию источники контекста отключают объединение. От AbstractContextSource.java (от которого наследуется LdapContextSource):

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);
      }
  }
...
}

И если вы попытаетесь использовать PoolingContextSource, вы получите UnsupportedOperationException, когда authenticate попытается позвонить getContext:

public class PoolingContextSource
        extends DelegatingBaseLdapPathContextSourceSupport
        implements ContextSource, DisposableBean {

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

Этот код взят из артефакта spring-ldap-core 2.3.1.RELEASE maven.

Вы по-прежнему можете создавать пулы соединений для поиска ldap с помощью PoolingContextSource, но пулы соединений для проверки подлинности работать не будут.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы