[java-identity-provider] 01/01: Changes to support the ldaptive v2 API.
Daniel Fisher
dfisher at vt.edu
Sat Aug 28 02:07:16 UTC 2021
This is an automated email from the git hooks/post-receive script.
dfisher pushed a commit to branch dev/ldaptive-v2
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=c5de7582dcc298e16819e6d33f5f1a1d7c0cc089
commit c5de7582dcc298e16819e6d33f5f1a1d7c0cc089
Author: Daniel Fisher <dfisher at vt.edu>
AuthorDate: Tue Dec 1 12:00:41 2020 -0500
Changes to support the ldaptive v2 API.
---
.../AbstractExecutableSearchFilterBuilder.java | 19 +-
.../resolver/dc/ldap/ExecutableSearchFilter.java | 12 +-
...ParameterizedExecutableSearchFilterBuilder.java | 4 +-
.../dc/ldap/SearchResultMappingStrategy.java | 6 +-
.../ldap/StringAttributeValueMappingStrategy.java | 12 +-
.../TemplatedExecutableSearchFilterBuilder.java | 10 +-
.../dc/ldap/impl/ConnectionFactoryValidator.java | 8 +-
.../resolver/dc/ldap/impl/LDAPDataConnector.java | 45 ++--
.../dc/ldap/impl/LDAPDataConnectorTest.java | 39 +--
.../resolver/dc/ldap/impl/Regressions.java | 11 +-
.../dc/ldap/impl/LDAPDataConnectorParser.java | 290 ++++++++++-----------
.../dc/ldap/LDAPDataConnectorParserTest.java | 165 ++++++------
.../ldap-attribute-resolver-spring-context.xml | 82 +++---
...dap-attribute-resolver-spring-props-context.xml | 89 +++----
.../authn/AbstractTemplateSearchDnResolver.java | 16 +-
.../idp/authn/PooledTemplateSearchDnResolver.java | 84 ------
.../idp/authn/TemplateSearchDnResolver.java | 19 +-
.../config/LDAPAuthenticationFactoryBean.java | 162 +++++-------
.../idp/authn/impl/LDAPCredentialValidator.java | 123 ++++-----
.../principal/impl/LDAPPrincipalSerializer.java | 4 +-
.../DefaultAuthenticationResultSerializerTest.java | 11 +-
.../authn/impl/LDAPCredentialValidatorTest.java | 23 +-
.../idp/authn/impl/ValidateCredentialsTest.java | 6 +-
23 files changed, 537 insertions(+), 703 deletions(-)
diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/AbstractExecutableSearchFilterBuilder.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/AbstractExecutableSearchFilterBuilder.java
index ca58514a5..52e0fc60f 100644
--- a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/AbstractExecutableSearchFilterBuilder.java
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/AbstractExecutableSearchFilterBuilder.java
@@ -21,12 +21,11 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.ldaptive.ConnectionFactory;
+import org.ldaptive.FilterTemplate;
import org.ldaptive.LdapException;
-import org.ldaptive.Response;
import org.ldaptive.ResultCode;
-import org.ldaptive.SearchExecutor;
-import org.ldaptive.SearchFilter;
-import org.ldaptive.SearchResult;
+import org.ldaptive.SearchOperation;
+import org.ldaptive.SearchResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,7 +48,7 @@ public abstract class AbstractExecutableSearchFilterBuilder extends AbstractInit
* @return executable search filter
*/
// Checkstyle: AnonInnerLength OFF
- protected ExecutableSearchFilter build(@Nonnull final SearchFilter searchFilter) {
+ protected ExecutableSearchFilter build(@Nonnull final FilterTemplate searchFilter) {
return new ExecutableSearchFilter() {
/** {@inheritDoc} */
@@ -58,20 +57,22 @@ public abstract class AbstractExecutableSearchFilterBuilder extends AbstractInit
}
/** {@inheritDoc} */
- @Nonnull public SearchResult execute(@Nonnull final SearchExecutor executor,
+ @Nonnull public SearchResponse execute(@Nonnull final SearchOperation operation,
@Nonnull final ConnectionFactory factory) throws LdapException {
- final Response<SearchResult> response = executor.search(factory, searchFilter);
+ final SearchOperation op = SearchOperation.copy(operation);
+ op.setConnectionFactory(factory);
+ final SearchResponse response = op.execute(searchFilter);
log.trace("Search returned response {}", response);
if (response.getResultCode() != ResultCode.SUCCESS) {
// It's possible for the LDAP to return partial results and report either a size limit or
// time limit result code. Throw if we don't receive all results.
throw new LdapException("Search operation did not return success: " + response.getResultCode());
}
- return response.getResult();
+ return response;
}
/** {@inheritDoc} */
- @Nonnull public SearchFilter getSearchFilter() {
+ @Nonnull public FilterTemplate getSearchFilter() {
return searchFilter;
}
diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ExecutableSearchFilter.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ExecutableSearchFilter.java
index 669003250..811ce0d43 100644
--- a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ExecutableSearchFilter.java
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ExecutableSearchFilter.java
@@ -21,9 +21,9 @@ import javax.annotation.Nonnull;
import org.ldaptive.ConnectionFactory;
import org.ldaptive.LdapException;
-import org.ldaptive.SearchExecutor;
-import org.ldaptive.SearchFilter;
-import org.ldaptive.SearchResult;
+import org.ldaptive.FilterTemplate;
+import org.ldaptive.SearchOperation;
+import org.ldaptive.SearchResponse;
import net.shibboleth.idp.attribute.resolver.dc.ExecutableSearch;
@@ -33,14 +33,14 @@ public interface ExecutableSearchFilter extends ExecutableSearch {
/**
* Performs an LDAP search and returns the results.
*
- * @param executor configured to perform searches
+ * @param operation configured to perform searches
* @param factory ready-to-use connection factory
*
* @return the result of this search filter
*
* @throws LdapException thrown if there is an error performing the search
*/
- @Nonnull SearchResult execute(@Nonnull SearchExecutor executor, @Nonnull ConnectionFactory factory)
+ @Nonnull SearchResponse execute(@Nonnull SearchOperation operation, @Nonnull ConnectionFactory factory)
throws LdapException;
/**
@@ -48,5 +48,5 @@ public interface ExecutableSearchFilter extends ExecutableSearch {
*
* @return search filter
*/
- @Nonnull SearchFilter getSearchFilter();
+ @Nonnull FilterTemplate getSearchFilter();
}
\ No newline at end of file
diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ParameterizedExecutableSearchFilterBuilder.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ParameterizedExecutableSearchFilterBuilder.java
index 9e3313ad1..7aea81829 100644
--- a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ParameterizedExecutableSearchFilterBuilder.java
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/ParameterizedExecutableSearchFilterBuilder.java
@@ -22,7 +22,7 @@ import java.util.Map;
import javax.annotation.Nonnull;
-import org.ldaptive.SearchFilter;
+import org.ldaptive.FilterTemplate;
import net.shibboleth.idp.attribute.IdPAttributeValue;
import net.shibboleth.idp.attribute.resolver.ResolutionException;
@@ -69,7 +69,7 @@ public class ParameterizedExecutableSearchFilterBuilder extends AbstractExecutab
@Override public ExecutableSearchFilter build(@Nonnull final AttributeResolutionContext resolutionContext,
@Nonnull final Map<String, List<IdPAttributeValue>> dependencyAttributes) throws ResolutionException {
ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
- final SearchFilter sf = new SearchFilter(searchFilter);
+ final FilterTemplate sf = new FilterTemplate(searchFilter);
sf.setParameter("principalName", resolutionContext.getPrincipal());
if (dependencyAttributes != null && !dependencyAttributes.isEmpty()) {
for (final Map.Entry<String, List<IdPAttributeValue>> entry : dependencyAttributes.entrySet()) {
diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/SearchResultMappingStrategy.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/SearchResultMappingStrategy.java
index 00422d07d..465729bfc 100644
--- a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/SearchResultMappingStrategy.java
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/SearchResultMappingStrategy.java
@@ -17,13 +17,13 @@
package net.shibboleth.idp.attribute.resolver.dc.ldap;
-import org.ldaptive.SearchResult;
+import org.ldaptive.SearchResponse;
import net.shibboleth.idp.attribute.resolver.dc.MappingStrategy;
/**
- * Strategy for mapping from a {@link SearchResult} to a collection of
+ * Strategy for mapping from a {@link SearchResponse} to a collection of
* {@link net.shibboleth.idp.attribute.IdPAttribute}s.
*/
-public interface SearchResultMappingStrategy extends MappingStrategy<SearchResult> {
+public interface SearchResultMappingStrategy extends MappingStrategy<SearchResponse> {
}
\ No newline at end of file
diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/StringAttributeValueMappingStrategy.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/StringAttributeValueMappingStrategy.java
index fd88d3a01..a10eb0cfb 100644
--- a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/StringAttributeValueMappingStrategy.java
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/StringAttributeValueMappingStrategy.java
@@ -36,7 +36,7 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
import org.ldaptive.LdapAttribute;
import org.ldaptive.LdapEntry;
-import org.ldaptive.SearchResult;
+import org.ldaptive.SearchResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory;
* A simple {@link SearchResultMappingStrategy} that iterates over all result entries and includes all attribute values
* as strings.
*/
-public class StringAttributeValueMappingStrategy extends AbstractMappingStrategy<SearchResult>
+public class StringAttributeValueMappingStrategy extends AbstractMappingStrategy<SearchResponse>
implements SearchResultMappingStrategy {
/** Class logger. */
@@ -52,21 +52,21 @@ public class StringAttributeValueMappingStrategy extends AbstractMappingStrategy
// Checkstyle: CyclomaticComplexity OFF
/** {@inheritDoc} */
- @Override @Nullable public Map<String,IdPAttribute> map(@Nonnull final SearchResult results)
+ @Override @Nullable public Map<String,IdPAttribute> map(@Nonnull final SearchResponse results)
throws ResolutionException {
Constraint.isNotNull(results, "Results can not be null");
- if (results.size() == 0) {
+ if (results.entrySize() == 0) {
log.debug("Results did not contain any entries, nothing to map");
if (isNoResultAnError()) {
throw new NoResultAnErrorResolutionException("No entries returned from search");
}
return null;
- } else if (results.size() > 1 && isMultipleResultsAnError()) {
+ } else if (results.entrySize() > 1 && isMultipleResultsAnError()) {
throw new MultipleResultAnErrorResolutionException("Multiple entries returned from search");
}
- final Map<String,IdPAttribute> attributes = new HashMap<>(results.size());
+ final Map<String,IdPAttribute> attributes = new HashMap<>(results.entrySize());
final Map<String,String> aliases = getResultRenamingMap();
diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java
index 000634af9..f38169634 100644
--- a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java
@@ -31,7 +31,7 @@ import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.VelocityException;
-import org.ldaptive.SearchFilter;
+import org.ldaptive.FilterTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -191,7 +191,7 @@ public class TemplatedExecutableSearchFilterBuilder extends AbstractExecutableSe
}
try {
- final SearchFilter searchFilter = new SearchFilter(merge(context));
+ final FilterTemplate searchFilter = new FilterTemplate(merge(context));
return super.build(searchFilter);
} catch (final VelocityException e) {
log.error("Error running template: {}", e.getMessage());
@@ -256,7 +256,7 @@ public class TemplatedExecutableSearchFilterBuilder extends AbstractExecutableSe
}
/**
- * Returns {@link SearchFilter#encodeValue} if value is a string.
+ * Returns {@link FilterTemplate#encodeValue} if value is a string.
*
* @param value to encode
*
@@ -264,9 +264,9 @@ public class TemplatedExecutableSearchFilterBuilder extends AbstractExecutableSe
*/
private Object encode(final Object value) {
if (value instanceof String){
- return SearchFilter.encodeValue((String) value);
+ return FilterTemplate.encodeValue((String) value);
} else if (value instanceof byte[]) {
- return SearchFilter.encodeValue((byte[]) value);
+ return FilterTemplate.encodeValue((byte[]) value);
}
return value;
}
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/ConnectionFactoryValidator.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/ConnectionFactoryValidator.java
index f0123d613..70368ffd7 100644
--- a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/ConnectionFactoryValidator.java
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/ConnectionFactoryValidator.java
@@ -94,9 +94,7 @@ public class ConnectionFactoryValidator extends AbstractInitializableComponent i
/** {@inheritDoc} */
@Override public void validate() throws ValidationException {
- Connection connection = null;
- try {
- connection = connectionFactory.getConnection();
+ try (Connection connection = connectionFactory.getConnection()) {
if (connection == null) {
log.error("Unable to retrieve connections from configured connection factory");
if (isThrowValidateError()) {
@@ -109,10 +107,6 @@ public class ConnectionFactoryValidator extends AbstractInitializableComponent i
if (isThrowValidateError()) {
throw new ValidationException(e);
}
- } finally {
- if (connection != null) {
- connection.close();
- }
}
}
}
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
index 1143d71e0..2839583da 100644
--- a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
@@ -27,8 +27,8 @@ import org.ldaptive.Connection;
import org.ldaptive.ConnectionConfig;
import org.ldaptive.ConnectionFactory;
import org.ldaptive.LdapException;
-import org.ldaptive.SearchExecutor;
-import org.ldaptive.SearchResult;
+import org.ldaptive.SearchOperation;
+import org.ldaptive.SearchResponse;
import org.ldaptive.ssl.SSLContextInitializer;
import org.ldaptive.ssl.SslConfig;
import org.ldaptive.ssl.X509SSLContextInitializer;
@@ -60,7 +60,7 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
private ConnectionFactory connectionFactory;
/** For executing LDAP searches. */
- private SearchExecutor searchExecutor;
+ private SearchOperation searchOperation;
/** Whether the default validator is being used. */
private boolean defaultValidator = true;
@@ -96,24 +96,24 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
}
/**
- * Gets the search executor for executing searches.
+ * Gets the search operation for executing searches.
*
- * @return search executor for executing searches
+ * @return search operation for executing searches
*/
- public SearchExecutor getSearchExecutor() {
- return searchExecutor;
+ public SearchOperation getSearchOperation() {
+ return searchOperation;
}
/**
* Sets the search executor for executing searches.
*
- * @param executor search executor for executing searches
+ * @param operation search operation for executing searches
*/
- public void setSearchExecutor(@Nonnull final SearchExecutor executor) {
+ public void setSearchOperation(@Nonnull final SearchOperation operation) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
- searchExecutor = Constraint.isNotNull(executor, "LDAP search executor can not be null");
+ searchOperation = Constraint.isNotNull(operation, "LDAP search executor can not be null");
}
/** {@inheritDoc} */
@@ -133,8 +133,8 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
if (connectionFactory == null) {
throw new ComponentInitializationException(getLogPrefix() + " No connection factory was configured");
}
- if (searchExecutor == null) {
- throw new ComponentInitializationException(getLogPrefix() + " No search executor was configured");
+ if (searchOperation == null) {
+ throw new ComponentInitializationException(getLogPrefix() + " No search operation was configured");
}
if (defaultValidator) {
@@ -165,16 +165,9 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
* @throws ComponentInitializationException if we detect an SSL issue
*/
private void policeForJVMTrust() throws ComponentInitializationException {
- Connection conn = null;
try {
- conn = connectionFactory.getConnection();
- if (conn == null) {
- log.debug("{} No connection to probe", getLogPrefix());
- return;
- }
- final ConnectionConfig connConfig = conn.getConnectionConfig();
+ final ConnectionConfig connConfig = connectionFactory.getConnectionConfig();
if (connConfig.getUseStartTLS() ||
- connConfig.getUseSSL() ||
connConfig.getLdapUrl().toLowerCase().contains("ldaps://")) {
final SslConfig sslConfig = connConfig.getSslConfig();
if (sslConfig != null) {
@@ -188,16 +181,8 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
}
}
}
- } catch (final GeneralSecurityException | LdapException e) {
+ } catch (final GeneralSecurityException e) {
log.debug("{} Failed to inspect TLS implementation", getLogPrefix(), e);
- } finally {
- if (conn != null) {
- try {
- conn.close();
- } catch (final Exception e) {
- log.debug("{} Error closing LDAP connection", getLogPrefix(), e);
- }
- }
}
}
// CheckStyle: CyclomaticComplexity ON
@@ -218,7 +203,7 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
throw new ResolutionException(getLogPrefix() + " Search filter cannot be null");
}
try {
- final SearchResult result = filter.execute(searchExecutor, connectionFactory);
+ final SearchResponse result = filter.execute(searchOperation, connectionFactory);
log.trace("{} Search returned {}", getLogPrefix(), result);
return getMappingStrategy().map(result);
} catch (final LdapException e) {
diff --git a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java
index 72691a8d3..e8be89586 100644
--- a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java
+++ b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java
@@ -34,7 +34,8 @@ import javax.annotation.Nonnull;
import org.apache.velocity.runtime.RuntimeConstants;
import org.ldaptive.ConnectionFactory;
import org.ldaptive.DefaultConnectionFactory;
-import org.ldaptive.SearchExecutor;
+import org.ldaptive.SearchOperation;
+import org.ldaptive.SearchRequest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -124,10 +125,10 @@ public class LDAPDataConnectorTest {
connector.setId(TEST_CONNECTOR_NAME);
final ConnectionFactory connectionFactory = new DefaultConnectionFactory("ldap://localhost:10389");
connector.setConnectionFactory(connectionFactory);
- final SearchExecutor searchExecutor = new SearchExecutor();
- searchExecutor.setBaseDn(TEST_BASE_DN);
- searchExecutor.setReturnAttributes(TEST_RETURN_ATTRIBUTES);
- connector.setSearchExecutor(searchExecutor);
+ final SearchOperation searchOperation = new SearchOperation();
+ searchOperation.setRequest(
+ SearchRequest.builder().dn(TEST_BASE_DN).returnAttributes(TEST_RETURN_ATTRIBUTES).build());
+ connector.setSearchOperation(searchOperation);
connector.setExecutableSearchBuilder(builder == null ?
newParameterizedExecutableSearchFilterBuilder("(uid={principalName})") : builder);
connector.setValidator(newConnectionFactoryValidator(connectionFactory));
@@ -156,10 +157,10 @@ public class LDAPDataConnectorTest {
}
connector.setFailFastInitialize(true);
- final SearchExecutor searchExecutor = new SearchExecutor();
- searchExecutor.setBaseDn(TEST_BASE_DN);
- searchExecutor.setReturnAttributes(TEST_RETURN_ATTRIBUTES);
- connector.setSearchExecutor(searchExecutor);
+ final SearchOperation searchOperation = new SearchOperation();
+ searchOperation.setRequest(
+ SearchRequest.builder().dn(TEST_BASE_DN).returnAttributes(TEST_RETURN_ATTRIBUTES).build());
+ connector.setSearchOperation(searchOperation);
try {
connector.initialize();
fail("No filter builder");
@@ -198,7 +199,7 @@ public class LDAPDataConnectorTest {
// OK
}
assertEquals(connector.getConnectionFactory(), connectionFactory);
- assertEquals(connector.getSearchExecutor(), searchExecutor);
+ assertEquals(connector.getSearchOperation(), searchOperation);
assertEquals(connector.getExecutableSearchBuilder(), requestBuilder);
assertEquals(connector.getMappingStrategy(), mappingStrategy);
}
@@ -209,7 +210,7 @@ public class LDAPDataConnectorTest {
final ConnectionFactory connectionFactory = new DefaultConnectionFactory("ldap://localhost:55555");
connector.setConnectionFactory(connectionFactory);
- connector.setSearchExecutor(new SearchExecutor());
+ connector.setSearchOperation(new SearchOperation());
connector.setExecutableSearchBuilder(newParameterizedExecutableSearchFilterBuilder("(uid={principalName})"));
connector.setFailFastInitialize(true);
@@ -268,10 +269,10 @@ public class LDAPDataConnectorTest {
final ExecutableSearchFilter filter = builder.build(context, dependsAttributes);
assertEquals(
filter.getSearchFilter().format(),
- "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2a))");
+ "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2A))");
assertEquals(
filter.getResultCacheKey(),
- "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2a))");
+ "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2A))");
}
@Test public void escape() throws ComponentInitializationException, ResolutionException {
@@ -282,8 +283,8 @@ public class LDAPDataConnectorTest {
TestSources.createResolutionContext("domain\\user*", TestSources.IDP_ENTITY_ID,
TestSources.SP_ENTITY_ID);
final ExecutableSearchFilter filter = builder.build(context, null);
- assertEquals(filter.getSearchFilter().format(), "(cn=domain\\5cuser\\2a)");
- assertEquals(filter.getResultCacheKey(), "(cn=domain\\5cuser\\2a)");
+ assertEquals(filter.getSearchFilter().format(), "(cn=domain\\5Cuser\\2A)");
+ assertEquals(filter.getResultCacheKey(), "(cn=domain\\5Cuser\\2A)");
}
@Test public void resolveTemplate() throws ComponentInitializationException, ResolutionException {
@@ -342,10 +343,10 @@ public class LDAPDataConnectorTest {
final ExecutableSearchFilter filter = builder.build(context, dependsAttributes);
assertEquals(
filter.getSearchFilter().format(),
- "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2a))");
+ "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2A))");
assertEquals(
filter.getResultCacheKey(),
- "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2a))");
+ "(&(cn=PETER_THE_PRINCIPAL)(eduPersonEntitlement=entitlement1)(eduPersonEntitlement=entitlement\\2A))");
}
@Test public void escapeTemplate() throws ComponentInitializationException, ResolutionException {
@@ -357,8 +358,8 @@ public class LDAPDataConnectorTest {
TestSources.createResolutionContext("domain\\user*", TestSources.IDP_ENTITY_ID,
TestSources.SP_ENTITY_ID);
final ExecutableSearchFilter filter = builder.build(context, null);
- assertEquals(filter.getSearchFilter().format(), "(cn=domain\\5cuser\\2a)");
- assertEquals(filter.getResultCacheKey(), "(cn=domain\\5cuser\\2a)");
+ assertEquals(filter.getSearchFilter().format(), "(cn=domain\\5Cuser\\2A)");
+ assertEquals(filter.getResultCacheKey(), "(cn=domain\\5Cuser\\2A)");
}
protected void resolve(final ExecutableSearchBuilder<ExecutableSearchFilter> builder) throws ComponentInitializationException,
diff --git a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/Regressions.java b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/Regressions.java
index f3c22c5ef..6dd280240 100644
--- a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/Regressions.java
+++ b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/Regressions.java
@@ -25,7 +25,8 @@ import java.util.Map;
import org.ldaptive.ConnectionFactory;
import org.ldaptive.DefaultConnectionFactory;
-import org.ldaptive.SearchExecutor;
+import org.ldaptive.SearchOperation;
+import org.ldaptive.SearchRequest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -108,10 +109,10 @@ public class Regressions {
connector.setId(TEST_CONNECTOR_NAME);
final ConnectionFactory connectionFactory = new DefaultConnectionFactory("ldap://localhost:10390");
connector.setConnectionFactory(connectionFactory);
- final SearchExecutor searchExecutor = new SearchExecutor();
- searchExecutor.setBaseDn(TEST_BASE_DN);
- searchExecutor.setReturnAttributes(TEST_RETURN_ATTRIBUTES);
- connector.setSearchExecutor(searchExecutor);
+ final SearchOperation searchOperation = new SearchOperation();
+ searchOperation.setRequest(
+ SearchRequest.builder().dn(TEST_BASE_DN).returnAttributes(TEST_RETURN_ATTRIBUTES).build());
+ connector.setSearchOperation(searchOperation);
connector.setExecutableSearchBuilder(builder == null ? LDAPDataConnectorTest.newParameterizedExecutableSearchFilterBuilder(
"(uid={principalName})") : builder);
connector.setValidator(LDAPDataConnectorTest.newConnectionFactoryValidator(connectionFactory));
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java
index 463c4bcb4..4491107b9 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java
@@ -30,24 +30,21 @@ import org.ldaptive.BindConnectionInitializer;
import org.ldaptive.ConnectionConfig;
import org.ldaptive.Credential;
import org.ldaptive.DefaultConnectionFactory;
+import org.ldaptive.FilterTemplate;
+import org.ldaptive.PooledConnectionFactory;
import org.ldaptive.RandomConnectionStrategy;
import org.ldaptive.RoundRobinConnectionStrategy;
-import org.ldaptive.SearchExecutor;
-import org.ldaptive.SearchFilter;
+import org.ldaptive.SearchConnectionValidator;
+import org.ldaptive.SearchOperation;
import org.ldaptive.SearchRequest;
import org.ldaptive.SearchScope;
import org.ldaptive.handler.CaseChangeEntryHandler;
import org.ldaptive.handler.CaseChangeEntryHandler.CaseChange;
import org.ldaptive.handler.DnAttributeEntryHandler;
-import org.ldaptive.handler.SearchEntryHandler;
-import org.ldaptive.pool.BlockingConnectionPool;
+import org.ldaptive.handler.LdapEntryHandler;
+import org.ldaptive.handler.SearchResultHandler;
import org.ldaptive.pool.IdlePruneStrategy;
-import org.ldaptive.pool.PoolConfig;
-import org.ldaptive.pool.PooledConnectionFactory;
-import org.ldaptive.pool.SearchValidator;
-import org.ldaptive.referral.SearchReferralHandler;
-import org.ldaptive.sasl.DigestMd5Config;
-import org.ldaptive.sasl.GssApiConfig;
+import org.ldaptive.referral.FollowSearchReferralHandler;
import org.ldaptive.sasl.Mechanism;
import org.ldaptive.sasl.SaslConfig;
import org.ldaptive.ssl.AllowAnyHostnameVerifier;
@@ -105,17 +102,17 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
* </p>
*
* <ul>
- * <li>{@link SearchExecutor#setTimeLimit(Duration)} defaults to 3s, overridden by the "searchTimeLimit" attribute.
+ * <li>search time limit defaults to 3s, overridden by the "searchTimeLimit" attribute.
* </li>
- * <li>{@link SearchExecutor#setSizeLimit(long)} defaults to 1, overridden by the "maxResultSize" attribute.</li>
- * <li>{@link SearchRequest#setBaseDn(String)} default to "", overridden by the "validateDN" attribute.</li>
- * <li>{@link SearchFilter#SearchFilter(String)} defaults to "(objectClass=*)", overridden by the "validateFilter"
+ * <li>search size limit defaults to 1, overridden by the "maxResultSize" attribute.</li>
+ * <li>search base dn default to "", overridden by the "validateDN" attribute.</li>
+ * <li>search filter defaults to "(objectClass=*)", overridden by the "validateFilter"
* attribute.</li>
- * <li>{@link PoolConfig#setMinPoolSize(int)} defaults to 0 if neither the attribute "poolInitialSize" nor the
+ * <li>pool min size defaults to 0 if neither the attribute "poolInitialSize" nor the
* attribute "minPoolSize" are set.</li>
- * <li>{@link PoolConfig#setMaxPoolSize(int)} defaults to 3 if neither the attribute "poolMaxIdleSize" nor the
+ * <li>pool max size defaults to 3 if neither the attribute "poolMaxIdleSize" nor the
* attribute "maxPoolSize" are set.</li>
- * <li>{@link PoolConfig#setValidatePeriod(Duration)} defaults to 30m, overridden by the attribute
+ * <li>pool validation period defaults to 30m, overridden by the attribute
* "validateTimerPeriod"</li>
* </ul>
*
@@ -146,10 +143,6 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
final V2Parser v2Parser = new V2Parser(config, getLogPrefix());
- final BeanDefinitionBuilder connectionFactory =
- BeanDefinitionBuilder.genericBeanDefinition(DefaultConnectionFactory.class);
- connectionFactory.addConstructorArgValue(v2Parser.createConnectionConfig(parserContext));
-
final String searchBuilderID = v2Parser.getBeanSearchBuilderID();
if (searchBuilderID != null) {
builder.addPropertyReference("executableSearchBuilder", searchBuilderID);
@@ -160,18 +153,19 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
}
}
- final BeanDefinition connectionPool = v2Parser.createConnectionPool(connectionFactory.getBeanDefinition());
- BeanDefinitionBuilder pooledConnectionFactory = null;
- if (connectionPool != null) {
- pooledConnectionFactory = BeanDefinitionBuilder.genericBeanDefinition(PooledConnectionFactory.class);
- pooledConnectionFactory.addConstructorArgValue(connectionPool);
- builder.addPropertyValue("connectionFactory", pooledConnectionFactory.getBeanDefinition());
+ final BeanDefinitionBuilder connectionFactory =
+ BeanDefinitionBuilder.genericBeanDefinition(DefaultConnectionFactory.class);
+ connectionFactory.addConstructorArgValue(v2Parser.createConnectionConfig(parserContext));
+
+ final BeanDefinition pooledConnectionFactory = v2Parser.createPooledConnectionFactory(parserContext);
+ if (pooledConnectionFactory != null) {
+ builder.addPropertyValue("connectionFactory", pooledConnectionFactory);
} else {
builder.addPropertyValue("connectionFactory", connectionFactory.getBeanDefinition());
}
- final BeanDefinition searchExecutor = v2Parser.createSearchExecutor();
- builder.addPropertyValue("searchExecutor", searchExecutor);
+ final BeanDefinition searchOperation = v2Parser.createSearchOperation();
+ builder.addPropertyValue("searchOperation", searchOperation);
final String mappingStrategyID = AttributeSupport.getAttributeValue(config, new QName("mappingStrategyRef"));
if (mappingStrategyID != null) {
@@ -188,8 +182,7 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
builder.addPropertyReference("validator", validatorID);
} else {
if (pooledConnectionFactory != null) {
- builder.addPropertyValue("validator",
- v2Parser.createValidator(pooledConnectionFactory.getBeanDefinition()));
+ builder.addPropertyValue("validator", v2Parser.createValidator(pooledConnectionFactory));
} else {
builder.addPropertyValue("validator", v2Parser.createValidator(connectionFactory.getBeanDefinition()));
}
@@ -324,7 +317,7 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
connectionInitializer.addPropertyValue("bindSaslConfig", saslConfig);
}
if (principal != null || principalCredential != null || saslConfig != null) {
- connectionConfig.addPropertyValue("connectionInitializer", connectionInitializer.getBeanDefinition());
+ connectionConfig.addPropertyValue("connectionInitializers", connectionInitializer.getBeanDefinition());
}
final String connectionStrategy = AttributeSupport.getAttributeValue(
configElement, new QName("connectionStrategy"));
@@ -485,12 +478,12 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
}
/**
- * Creates a new search executor bean definition from a v2 XML configuration.
+ * Creates a new search operation bean definition from a v2 XML configuration.
*
- * @return search executor bean definition
+ * @return search operation bean definition
*/
// CheckStyle: CyclomaticComplexity|MethodLength OFF
- @Nonnull public BeanDefinition createSearchExecutor() {
+ @Nonnull public BeanDefinition createSearchOperation() {
final String baseDn = AttributeSupport.getAttributeValue(configElement, new QName("baseDN"));
final String searchScope = AttributeSupport.getAttributeValue(configElement, new QName("searchScope"));
final String derefAliases = AttributeSupport.getAttributeValue(configElement, new QName("derefAliases"));
@@ -502,38 +495,41 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
final String lowercaseAttributeNames =
AttributeSupport.getAttributeValue(configElement, new QName("lowercaseAttributeNames"));
- final BeanDefinitionBuilder searchExecutor =
- BeanDefinitionBuilder.genericBeanDefinition(SearchExecutor.class);
+ final BeanDefinitionBuilder searchRequest =
+ BeanDefinitionBuilder.genericBeanDefinition(SearchRequest.class);
if (baseDn != null) {
- searchExecutor.addPropertyValue("baseDn", baseDn);
+ searchRequest.addPropertyValue("baseDn", baseDn);
}
if (searchScope != null) {
- searchExecutor.addPropertyValue("searchScope", searchScope);
+ searchRequest.addPropertyValue("searchScope", searchScope);
}
if (derefAliases != null) {
- searchExecutor.addPropertyValue("derefAliases", derefAliases);
+ searchRequest.addPropertyValue("derefAliases", derefAliases);
}
+
+ final BeanDefinitionBuilder searchOperation =
+ BeanDefinitionBuilder.genericBeanDefinition(SearchOperation.class);
if (followReferrals != null) {
final BeanDefinitionBuilder handler =
- BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildReferralHandler");
+ BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildReferralHandlers");
handler.addConstructorArgValue(followReferrals);
- searchExecutor.addPropertyValue("referralHandler", handler.getBeanDefinition());
+ searchOperation.addPropertyValue("searchResultHandlers", handler.getBeanDefinition());
}
if (searchTimeLimit != null) {
- searchExecutor.addPropertyValue("timeLimit", searchTimeLimit);
+ searchRequest.addPropertyValue("timeLimit", searchTimeLimit);
} else {
- searchExecutor.addPropertyValue("timeLimit", Duration.ofSeconds(3));
+ searchRequest.addPropertyValue("timeLimit", Duration.ofSeconds(3));
}
if (maxResultSize != null) {
- searchExecutor.addPropertyValue("sizeLimit", maxResultSize);
+ searchRequest.addPropertyValue("sizeLimit", maxResultSize);
} else {
- searchExecutor.addPropertyValue("sizeLimit", 1);
+ searchRequest.addPropertyValue("sizeLimit", 1);
}
final BeanDefinitionBuilder handlers =
BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildSearchEntryHandlers");
handlers.addConstructorArgValue(lowercaseAttributeNames);
- searchExecutor.addPropertyValue("searchEntryHandlers", handlers.getBeanDefinition());
+ searchOperation.addPropertyValue("entryHandlers", handlers.getBeanDefinition());
final List<Element> returnAttrsElements = ElementSupport.getChildElementsByTagNameNS(configElement,
AttributeResolverNamespaceHandler.NAMESPACE, "ReturnAttributes");
@@ -548,7 +544,7 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
final BeanDefinitionBuilder returnAttrs =
BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildStringList");
returnAttrs.addConstructorArgValue(ElementSupport.getElementContentAsString(returnAttrsElement));
- searchExecutor.addPropertyValue("returnAttributes", returnAttrs.getBeanDefinition());
+ searchRequest.addPropertyValue("returnAttributes", returnAttrs.getBeanDefinition());
}
final List<Element> binaryAttrsElements = ElementSupport.getChildElementsByTagNameNS(configElement,
@@ -564,10 +560,11 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
final BeanDefinitionBuilder binaryAttrs =
BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildStringList");
binaryAttrs.addConstructorArgValue(ElementSupport.getElementContentAsString(binaryAttrsElement));
- searchExecutor.addPropertyValue("binaryAttributes", binaryAttrs.getBeanDefinition());
+ searchRequest.addPropertyValue("binaryAttributes", binaryAttrs.getBeanDefinition());
}
- return searchExecutor.getBeanDefinition();
+ searchOperation.addPropertyValue("request", searchRequest.getBeanDefinition());
+ return searchOperation.getBeanDefinition();
}
// CheckStyle: CyclomaticComplexity|MethodLength ON
@@ -592,14 +589,13 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
// CheckStyle: CyclomaticComplexity ON
/**
- * Creates a new connection pool bean definition from a v2 XML configuration.
- *
- * @param connectionFactory used by the connection pool
- *
- * @return connection pool bean definition
+ * Creates a new pooled connection factory bean definition from a v2 XML configuration.
+ *
+ * @param parserContext bean definition parsing context
+ * @return pooled connection factory bean definition
*/
// CheckStyle: MethodLength OFF
- @Nullable public BeanDefinition createConnectionPool(final BeanDefinition connectionFactory) {
+ @Nullable public BeanDefinition createPooledConnectionFactory(@Nonnull final ParserContext parserContext) {
final Element poolConfigElement = getConnectionPoolElement();
if (null == poolConfigElement) {
@@ -617,11 +613,12 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
final String expirationTime =
AttributeSupport.getAttributeValue(poolConfigElement, new QName("expirationTime"));
- final BeanDefinitionBuilder pool =
- BeanDefinitionBuilder.genericBeanDefinition(BlockingConnectionPool.class);
- pool.addPropertyValue("name", "resolver-pool");
+ final BeanDefinitionBuilder connectionFactory =
+ BeanDefinitionBuilder.genericBeanDefinition(PooledConnectionFactory.class);
+ connectionFactory.addPropertyValue("name", "resolver-pool");
+ connectionFactory.addPropertyValue("connectionConfig", createConnectionConfig(parserContext));
if (blockWaitTime != null) {
- pool.addPropertyValue("blockWaitTime", blockWaitTime);
+ connectionFactory.addPropertyValue("blockWaitTime", blockWaitTime);
}
if (expirationTime != null) {
final String prunePeriod =
@@ -632,85 +629,60 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
strategy.addConstructorArgValue(prunePeriod);
}
strategy.addConstructorArgValue(expirationTime);
- pool.addPropertyValue("pruneStrategy", strategy.getBeanDefinition());
+ connectionFactory.addPropertyValue("pruneStrategy", strategy.getBeanDefinition());
+ }
+
+ final String minPoolSize = AttributeSupport.getAttributeValue(poolConfigElement, new QName("minPoolSize"));
+ final String maxPoolSize = AttributeSupport.getAttributeValue(poolConfigElement, new QName("maxPoolSize"));
+ final String validatePeriodically =
+ AttributeSupport.getAttributeValue(poolConfigElement, new QName("validatePeriodically"));
+ final String validateOnCheckout =
+ AttributeSupport.getAttributeValue(poolConfigElement, new QName("validateOnCheckout"));
+
+ if (minPoolSize == null) {
+ connectionFactory.addPropertyValue("minPoolSize", 0);
+ } else {
+ connectionFactory.addPropertyValue("minPoolSize", minPoolSize);
+ }
+ if (maxPoolSize == null) {
+ connectionFactory.addPropertyValue("maxPoolSize", 3);
+ } else {
+ connectionFactory.addPropertyValue("maxPoolSize", maxPoolSize);
+ }
+ if (validatePeriodically != null) {
+ connectionFactory.addPropertyValue("validatePeriodically", validatePeriodically);
+ }
+ if (validateOnCheckout != null) {
+ connectionFactory.addPropertyValue("validateOnCheckOut", validateOnCheckout);
}
- pool.addPropertyValue("poolConfig", createPoolConfig());
final BeanDefinitionBuilder validator =
BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildSearchValidator");
- validator.addConstructorArgValue(
- AttributeSupport.getAttributeValue(poolConfigElement, new QName("validatePeriodically")));
validator.addConstructorArgValue(
AttributeSupport.getAttributeValue(poolConfigElement, new QName("validateDN")));
validator.addConstructorArgValue(
AttributeSupport.getAttributeValue(poolConfigElement, new QName("validateFilter")));
- pool.addPropertyValue("validator", validator.getBeanDefinition());
+ validator.addConstructorArgValue(
+ AttributeSupport.getAttributeValue(poolConfigElement, new QName("validateTimerPeriod")));
+ connectionFactory.addPropertyValue("validator", validator.getBeanDefinition());
- pool.addPropertyValue("connectionFactory", connectionFactory);
final String failFastInitialize =
AttributeSupport.getAttributeValue(poolConfigElement, new QName("failFastInitialize"));
if (failFastInitialize != null) {
// V4 Deprecation
DeprecationSupport.warnOnce(ObjectType.ATTRIBUTE, "failfastInitialize (on a ConnectionPool element)",
null, "failfastInitialize (on a DataConnector)");
- pool.addPropertyValue("failFastInitialize", failFastInitialize);
+ connectionFactory.addPropertyValue("failFastInitialize", failFastInitialize);
} else if (configElement.hasAttributeNS(null, ATTR_FAIL_FAST)) {
- pool.addPropertyValue("failFastInitialize",
+ connectionFactory.addPropertyValue("failFastInitialize",
StringSupport.trimOrNull(configElement.getAttributeNS(null, ATTR_FAIL_FAST)));
}
- pool.setInitMethodName("initialize");
- return pool.getBeanDefinition();
+ connectionFactory.setInitMethodName("initialize");
+ return connectionFactory.getBeanDefinition();
}
// CheckStyle: MethodLength ON
- /**
- * Creates a new pool config bean definition from a v2 XML configuration.
- *
- * @return pool config bean definition
- */
- @Nullable protected BeanDefinition createPoolConfig() {
- final Element poolConfigElement = getConnectionPoolElement();
- if (poolConfigElement == null) {
- return null;
- }
-
- final String minPoolSize = AttributeSupport.getAttributeValue(poolConfigElement, new QName("minPoolSize"));
- final String maxPoolSize = AttributeSupport.getAttributeValue(poolConfigElement, new QName("maxPoolSize"));
- final String validatePeriodically =
- AttributeSupport.getAttributeValue(poolConfigElement, new QName("validatePeriodically"));
- final String validateTimerPeriod =
- AttributeSupport.getAttributeValue(poolConfigElement, new QName("validateTimerPeriod"));
- final String validateOnCheckout =
- AttributeSupport.getAttributeValue(poolConfigElement, new QName("validateOnCheckout"));
-
- final BeanDefinitionBuilder poolConfig = BeanDefinitionBuilder.genericBeanDefinition(PoolConfig.class);
- if (minPoolSize == null) {
- poolConfig.addPropertyValue("minPoolSize", 0);
- } else {
- poolConfig.addPropertyValue("minPoolSize", minPoolSize);
- }
- if (maxPoolSize == null) {
- poolConfig.addPropertyValue("maxPoolSize", 3);
- } else {
- poolConfig.addPropertyValue("maxPoolSize", maxPoolSize);
- }
- if (validatePeriodically != null) {
- poolConfig.addPropertyValue("validatePeriodically", validatePeriodically);
- }
- if (validateTimerPeriod != null) {
- poolConfig.addPropertyValue("validatePeriod", validateTimerPeriod);
- } else {
- poolConfig.addPropertyValue("validatePeriod", Duration.ofMinutes(30));
- }
- if (validateOnCheckout != null) {
- poolConfig.addPropertyValue("validateOnCheckOut", validateOnCheckout);
- } else {
- poolConfig.addPropertyValue("validateOnCheckOut", false);
- }
- return poolConfig.getBeanDefinition();
- }
-
/**
* Creates a new sasl config bean definition from a v2 XML configuration.
*
@@ -735,41 +707,41 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
final List<Element> saslProperties = ElementSupport.getChildElementsByTagNameNS(saslConfigElement,
AttributeResolverNamespaceHandler.NAMESPACE, "SASLProperty");
- final BeanDefinitionBuilder saslConfig;
- if ("DIGEST_MD5".equals(mechanism)) {
- saslConfig = BeanDefinitionBuilder.genericBeanDefinition(DigestMd5Config.class);
- if (realm != null) {
- saslConfig.addPropertyValue("realm", realm);
- }
- } else if ("GSSAPI".equals(mechanism)) {
- saslConfig = BeanDefinitionBuilder.genericBeanDefinition(GssApiConfig.class);
- if (realm != null) {
- saslConfig.addPropertyValue("realm", realm);
- }
- } else {
- saslConfig = BeanDefinitionBuilder.genericBeanDefinition(SaslConfig.class);
- saslConfig.addPropertyValue("mechanism", mechanism);
- }
+ final BeanDefinitionBuilder saslConfig = BeanDefinitionBuilder.genericBeanDefinition(SaslConfig.class);
+ saslConfig.addPropertyValue("mechanism", mechanism);
if (authorizationId != null) {
saslConfig.addPropertyValue("authorizationId", authorizationId);
}
+ if (realm != null) {
+ saslConfig.addPropertyValue("realm", realm);
+ }
if (!saslProperties.isEmpty()) {
for (final Element property : saslProperties) {
final String name = AttributeSupport.getAttributeValue(property, null, "name");
final String value = AttributeSupport.getAttributeValue(property, null, "value");
if ("javax.security.sasl.qop".equals(name)) {
- if ("auth".equalsIgnoreCase(value)) {
- saslConfig.addPropertyValue("qualityOfProtection", "AUTH");
- } else if ("auth-int".equalsIgnoreCase(value)) {
- saslConfig.addPropertyValue("qualityOfProtection", "AUTH_INT");
- } else if ("auth-conf".equalsIgnoreCase(value)) {
- saslConfig.addPropertyValue("qualityOfProtection", "AUTH_CONF");
- } else {
- saslConfig.addPropertyValue("qualityOfProtection", value);
+ final String[] splitValues = value.split(",");
+ final String[] values = new String[splitValues.length];
+ for (int i = 0; i < splitValues.length; i++) {
+ if ("auth".equalsIgnoreCase(splitValues[i].trim())) {
+ values[i] = "AUTH";
+ } else if ("auth-int".equalsIgnoreCase(splitValues[i].trim())) {
+ values[i] = "AUTH_INT";
+ } else if ("auth-conf".equalsIgnoreCase(splitValues[i].trim())) {
+ values[i] = "AUTH_CONF";
+ } else {
+ values[i] = splitValues[i].trim();
+ }
}
+ saslConfig.addPropertyValue("qualityOfProtection", values);
} else if ("javax.security.sasl.strength".equals(name)) {
- saslConfig.addPropertyValue("securityStrength", value);
+ final String[] splitValues = value.split(",");
+ final String[] values = new String[splitValues.length];
+ for (int i = 0; i < splitValues.length; i++) {
+ values[i] = splitValues[i].trim();
+ }
+ saslConfig.addPropertyValue("securityStrength", values);
} else if ("javax.security.sasl.server.authentication".equals(name)) {
saslConfig.addPropertyValue("mutualAuthentication", value);
}
@@ -865,19 +837,18 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
}
/**
- * Returns a search validator or null if validatePeriodically is false.
+ * Returns a search validator.
*
- * @param validatePeriodically whether to create a search validator
* @param validateDN baseDN to search on
* @param validateFilter to search with
+ * @param validatePeriod period over which to validate connection when periodic validation in enabled
*
* @return search validator or null
*/
- @Nullable public static SearchValidator buildSearchValidator(@Nullable final String validatePeriodically,
- @Nullable final String validateDN, @Nullable final String validateFilter) {
- if (!Boolean.valueOf(validatePeriodically)) {
- return null;
- }
+ @Nullable public static SearchConnectionValidator buildSearchValidator(
+ @Nullable final String validateDN,
+ @Nullable final String validateFilter,
+ @Nullable final String validatePeriod) {
final SearchRequest searchRequest = new SearchRequest();
searchRequest.setReturnAttributes("1.1");
searchRequest.setSearchScope(SearchScope.OBJECT);
@@ -887,14 +858,17 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
} else {
searchRequest.setBaseDn("");
}
- final SearchFilter searchFilter = new SearchFilter();
+ final FilterTemplate searchFilter = new FilterTemplate();
if (validateFilter != null) {
searchFilter.setFilter(validateFilter);
} else {
searchFilter.setFilter("(objectClass=*)");
}
- searchRequest.setSearchFilter(searchFilter);
- final SearchValidator validator = new SearchValidator();
+ searchRequest.setFilter(searchFilter);
+ final SearchConnectionValidator validator = new SearchConnectionValidator();
+ if (validatePeriod != null) {
+ validator.setValidatePeriod(Duration.parse(validatePeriod));
+ }
validator.setSearchRequest(searchRequest);
return validator;
}
@@ -924,9 +898,9 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
* @param lowercaseAttributeNames boolean string value
* @return list of search entry handlers
*/
- @Nonnull public static List<SearchEntryHandler> buildSearchEntryHandlers(
+ @Nonnull public static List<LdapEntryHandler> buildSearchEntryHandlers(
@Nullable final String lowercaseAttributeNames) {
- final List<SearchEntryHandler> handlers = new ArrayList<>();
+ final List<LdapEntryHandler> handlers = new ArrayList<>();
handlers.add(new DnAttributeEntryHandler());
if (Boolean.valueOf(lowercaseAttributeNames)) {
final CaseChangeEntryHandler entryHandler = new CaseChangeEntryHandler();
@@ -937,16 +911,18 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
}
/**
- * Returns a search referral handler or null if followReferrals is false.
+ * Returns search referral handlers or null if followReferrals is false.
*
* @param followReferrals whether to create a search referral handler
*
- * @return search referral handler or null
+ * @return search result handlers or null
*/
- @Nonnull public static SearchReferralHandler buildReferralHandler(
+ @Nonnull public static List<SearchResultHandler> buildReferralHandlers(
@Nullable final String followReferrals) {
+ final List<SearchResultHandler> handlers = new ArrayList<>();
if (followReferrals != null && Boolean.valueOf(followReferrals)) {
- return new SearchReferralHandler();
+ handlers.add(new FollowSearchReferralHandler());
+ return handlers;
}
return null;
}
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/LDAPDataConnectorParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/LDAPDataConnectorParserTest.java
index d77dabee0..3f0d74480 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/LDAPDataConnectorParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/LDAPDataConnectorParserTest.java
@@ -35,22 +35,25 @@ import java.util.Map;
import java.util.stream.Collectors;
import org.ldaptive.BindConnectionInitializer;
+import org.ldaptive.BindResponse;
import org.ldaptive.ConnectionConfig;
import org.ldaptive.DefaultConnectionFactory;
-import org.ldaptive.SearchExecutor;
-import org.ldaptive.pool.BlockingConnectionPool;
+import org.ldaptive.PooledConnectionFactory;
+import org.ldaptive.SearchOperation;
+import org.ldaptive.filter.EqualityFilter;
import org.ldaptive.pool.IdlePruneStrategy;
-import org.ldaptive.pool.PoolConfig;
-import org.ldaptive.pool.PooledConnectionFactory;
-import org.ldaptive.pool.SearchValidator;
-import org.ldaptive.referral.SearchReferralHandler;
-import org.ldaptive.sasl.DigestMd5Config;
+import org.ldaptive.SearchConnectionValidator;
+import org.ldaptive.referral.FollowSearchReferralHandler;
+import org.ldaptive.sasl.DefaultSaslClientRequest;
+import org.ldaptive.sasl.DigestMD5BindRequest;
import org.ldaptive.sasl.Mechanism;
import org.ldaptive.sasl.QualityOfProtection;
+import org.ldaptive.sasl.SaslClient;
import org.ldaptive.sasl.SaslConfig;
import org.ldaptive.sasl.SecurityStrength;
import org.ldaptive.ssl.CredentialConfig;
import org.ldaptive.ssl.SslConfig;
+import org.ldaptive.transport.TransportConnection;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource;
@@ -102,7 +105,17 @@ public class LDAPDataConnectorParserTest {
private InMemoryDirectoryServer directoryServer;
private GenericApplicationContext pendingTeardownContext = null;
-
+
+ /** Override the default SASL client for testing. */
+ public static class TestSaslClient implements SaslClient<DefaultSaslClientRequest>
+ {
+
+ @Override
+ public BindResponse bind(final TransportConnection conn, final DefaultSaslClientRequest request) {
+ return BindResponse.builder().resultCode(org.ldaptive.ResultCode.SUCCESS).build();
+ }
+ }
+
@AfterMethod public void tearDownTestContext() {
if (null == pendingTeardownContext ) {
return;
@@ -165,6 +178,9 @@ public class LDAPDataConnectorParserTest {
directoryServer.importFromLDIF(true,
"src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldapDataConnectorTest.ldif");
directoryServer.startListening();
+ System.setProperty(
+ "org.ldaptive.sasl.defaultSaslClient",
+ TestSaslClient.class.getName());
}
/**
@@ -172,6 +188,7 @@ public class LDAPDataConnectorParserTest {
*/
@AfterClass public void teardownDirectoryServer() {
directoryServer.shutDown(true);
+ System.clearProperty("org.ldaptive.sasl.defaultSaslClient");
}
@Test public void v2Config() throws Exception {
@@ -235,9 +252,8 @@ public class LDAPDataConnectorParserTest {
final ConnectionConfig connConfig = connFactory.getConnectionConfig();
assertNotNull(connConfig);
assertEquals(connConfig.getLdapUrl(), "ldap://localhost:10389");
- assertFalse(connConfig.getUseSSL());
assertFalse(connConfig.getUseStartTLS());
- final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializer();
+ final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializers()[0];
assertEquals(connInitializer.getBindDn(), "cn=Directory Manager");
assertEquals(connInitializer.getBindCredential().getString(), "password");
assertEquals(connConfig.getConnectTimeout(), Duration.ofSeconds(3));
@@ -248,12 +264,12 @@ public class LDAPDataConnectorParserTest {
final CredentialConfig credentialConfig = sslConfig.getCredentialConfig();
assertNotNull(credentialConfig);
- final SearchExecutor searchExecutor = dataConnector.getSearchExecutor();
- assertNotNull(searchExecutor);
- assertEquals(searchExecutor.getBaseDn(), "");
- assertNull(searchExecutor.getSearchFilter());
- assertEquals(searchExecutor.getTimeLimit(), Duration.ofSeconds(3));
- assertNull(searchExecutor.getReferralHandler());
+ final SearchOperation searchOperation = dataConnector.getSearchOperation();
+ assertNotNull(searchOperation);
+ assertEquals(searchOperation.getRequest().getBaseDn(), "");
+ assertNull(searchOperation.getRequest().getFilter());
+ assertEquals(searchOperation.getRequest().getTimeLimit(), Duration.ofSeconds(3));
+ assertNull(searchOperation.getSearchResultHandlers());
final ConnectionFactoryValidator validator = (ConnectionFactoryValidator) dataConnector.getValidator();
assertNotNull(validator);
@@ -287,45 +303,42 @@ public class LDAPDataConnectorParserTest {
assertEquals(Duration.ZERO, dataConnector.getNoRetryDelay());
final PooledConnectionFactory connFactory = (PooledConnectionFactory) dataConnector.getConnectionFactory();
assertNotNull(connFactory);
- final BlockingConnectionPool connPool = (BlockingConnectionPool) connFactory.getConnectionPool();
- assertNotNull(connPool);
- assertNull(connPool.getBlockWaitTime());
- assertEquals("resolver-pool", connPool.getName());
- final PoolConfig poolConfig = connPool.getPoolConfig();
- assertNotNull(poolConfig);
- assertEquals(poolConfig.getMinPoolSize(), 0);
- assertEquals(poolConfig.getMaxPoolSize(), 3);
- assertFalse(poolConfig.isValidatePeriodically());
- assertEquals(poolConfig.getValidatePeriod(), Duration.ofMinutes(30));
- assertTrue(connPool.getFailFastInitialize());
- assertNull(connPool.getValidator());
-
- final IdlePruneStrategy pruneStrategy = (IdlePruneStrategy) connPool.getPruneStrategy();
+ // note that default value changed from null to PT1M
+ assertEquals(connFactory.getBlockWaitTime(), Duration.ofMinutes(1));
+ assertEquals("resolver-pool", connFactory.getName());
+ assertEquals(connFactory.getMinPoolSize(), 0);
+ assertEquals(connFactory.getMaxPoolSize(), 3);
+ assertFalse(connFactory.isValidatePeriodically());
+ // note that pooled connection factories have a validator by default
+ assertNotNull(connFactory.getValidator());
+ assertEquals(connFactory.getValidator().getValidatePeriod(), Duration.ofMinutes(30));
+ assertTrue(connFactory.getFailFastInitialize());
+
+ final IdlePruneStrategy pruneStrategy = (IdlePruneStrategy) connFactory.getPruneStrategy();
assertNotNull(pruneStrategy);
assertEquals(pruneStrategy.getPrunePeriod(), Duration.ofMinutes(5));
assertEquals(pruneStrategy.getIdleTime(), Duration.ofMinutes(10));
- final ConnectionConfig connConfig = connPool.getConnectionFactory().getConnectionConfig();
+ final ConnectionConfig connConfig = connFactory.getConnectionConfig();
assertNotNull(connConfig);
assertEquals(connConfig.getLdapUrl(), "ldap://localhost:10389");
- assertFalse(connConfig.getUseSSL());
assertFalse(connConfig.getUseStartTLS());
- final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializer();
+ final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializers()[0];
assertEquals(connInitializer.getBindDn(), "cn=Directory Manager");
assertEquals(connInitializer.getBindCredential().getString(), "password");
assertEquals(connConfig.getConnectTimeout(), Duration.ofSeconds(3));
assertEquals(connConfig.getResponseTimeout(), Duration.ofSeconds(3));
- final SslConfig sslConfig = connPool.getConnectionFactory().getConnectionConfig().getSslConfig();
+ final SslConfig sslConfig = connFactory.getConnectionConfig().getSslConfig();
assertNotNull(sslConfig);
final CredentialConfig credentialConfig = sslConfig.getCredentialConfig();
assertNotNull(credentialConfig);
- final SearchExecutor searchExecutor = dataConnector.getSearchExecutor();
- assertNotNull(searchExecutor);
- assertEquals(searchExecutor.getBaseDn(), "");
- assertNull(searchExecutor.getSearchFilter());
- assertEquals(searchExecutor.getTimeLimit(), Duration.ofSeconds(3));
+ final SearchOperation searchOperation = dataConnector.getSearchOperation();
+ assertNotNull(searchOperation);
+ assertEquals(searchOperation.getRequest().getBaseDn(), "");
+ assertNull(searchOperation.getRequest().getFilter());
+ assertEquals(searchOperation.getRequest().getTimeLimit(), Duration.ofSeconds(3));
final ConnectionFactoryValidator validator = (ConnectionFactoryValidator) dataConnector.getValidator();
assertNotNull(validator);
@@ -383,7 +396,7 @@ public class LDAPDataConnectorParserTest {
assertNotNull(connFactory);
final ConnectionConfig connConfig = connFactory.getConnectionConfig();
assertNotNull(connConfig);
- final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializer();
+ final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializers()[0];
assertNotNull(connInitializer);
assertEquals(connInitializer.getBindDn(), "manager at shibboleth.net");
assertEquals(connInitializer.getBindCredential().getString(), "password");
@@ -392,9 +405,9 @@ public class LDAPDataConnectorParserTest {
assertEquals(saslConfig.getMechanism(), Mechanism.DIGEST_MD5);
assertEquals(saslConfig.getAuthorizationId(), "authzID");
assertEquals(saslConfig.getMutualAuthentication(), Boolean.TRUE);
- assertEquals(saslConfig.getQualityOfProtection(), QualityOfProtection.AUTH_INT);
- assertEquals(saslConfig.getSecurityStrength(), SecurityStrength.HIGH);
- assertEquals(((DigestMd5Config) saslConfig).getRealm(), "shibboleth.net");
+ assertEquals(saslConfig.getQualityOfProtection()[0], QualityOfProtection.AUTH_INT);
+ assertEquals(saslConfig.getSecurityStrength()[0], SecurityStrength.HIGH);
+ assertEquals(saslConfig.getRealm(), "shibboleth.net");
}
@Test public void v2AuthenticationTypeConfig() throws Exception {
@@ -408,14 +421,14 @@ public class LDAPDataConnectorParserTest {
assertNotNull(connFactory);
final ConnectionConfig connConfig = connFactory.getConnectionConfig();
assertNotNull(connConfig);
- final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializer();
+ final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializers()[0];
assertNotNull(connInitializer);
assertEquals(connInitializer.getBindDn(), "manager at shibboleth.net");
assertEquals(connInitializer.getBindCredential().getString(), "password");
final SaslConfig saslConfig = connInitializer.getBindSaslConfig();
assertNotNull(saslConfig);
assertEquals(saslConfig.getMechanism(), Mechanism.DIGEST_MD5);
- assertEquals(saslConfig.getAuthorizationId(), "");
+ assertNull(saslConfig.getAuthorizationId());
assertNull(saslConfig.getMutualAuthentication());
assertNull(saslConfig.getQualityOfProtection());
assertNull(saslConfig.getSecurityStrength());
@@ -432,17 +445,18 @@ public class LDAPDataConnectorParserTest {
assertNotNull(connFactory);
final ConnectionConfig connConfig = connFactory.getConnectionConfig();
assertNotNull(connConfig);
- final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializer();
+ final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializers()[0];
assertNotNull(connInitializer);
final SaslConfig saslConfig = connInitializer.getBindSaslConfig();
assertNull(saslConfig);
- final SearchExecutor searchExecutor = dataConnector.getSearchExecutor();
- assertNotNull(searchExecutor);
- assertEquals(searchExecutor.getBaseDn(), "");
- assertNull(searchExecutor.getSearchFilter());
- assertEquals(searchExecutor.getTimeLimit(), Duration.ofSeconds(3));
- final SearchReferralHandler referralHandler = (SearchReferralHandler) searchExecutor.getReferralHandler();
+ final SearchOperation searchOperation = dataConnector.getSearchOperation();
+ assertNotNull(searchOperation);
+ assertNotNull(searchOperation.getRequest());
+ assertEquals(searchOperation.getRequest().getBaseDn(), "");
+ assertNull(searchOperation.getRequest().getFilter());
+ assertEquals(searchOperation.getRequest().getTimeLimit(), Duration.ofSeconds(3));
+ final FollowSearchReferralHandler referralHandler = (FollowSearchReferralHandler) searchOperation.getSearchResultHandlers()[0];
assertNotNull(referralHandler);
}
@@ -457,7 +471,7 @@ public class LDAPDataConnectorParserTest {
assertNotNull(connFactory);
final ConnectionConfig connConfig = connFactory.getConnectionConfig();
assertNotNull(connConfig);
- final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializer();
+ final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializers()[0];
assertNotNull(connInitializer);
assertNull(connInitializer.getBindDn());
assertNull(connInitializer.getBindCredential());
@@ -589,50 +603,45 @@ public class LDAPDataConnectorParserTest {
final PooledConnectionFactory connFactory = (PooledConnectionFactory) dataConnector.getConnectionFactory();
assertNotNull(connFactory);
- final BlockingConnectionPool connPool = (BlockingConnectionPool) connFactory.getConnectionPool();
- assertNotNull(connPool);
- assertEquals(connPool.getBlockWaitTime(), Duration.ofSeconds(5));
- assertEquals(connPool.getName(), "resolver-pool");
- final PoolConfig poolConfig = connPool.getPoolConfig();
- assertNotNull(poolConfig);
- assertEquals(poolConfig.getMinPoolSize(), 5);
- assertEquals(poolConfig.getMaxPoolSize(), 10);
- assertTrue(poolConfig.isValidatePeriodically());
- assertEquals(poolConfig.getValidatePeriod(), Duration.ofMinutes(15));
- assertFalse(connPool.getFailFastInitialize());
-
- final SearchValidator searchValidator = (SearchValidator) connPool.getValidator();
+ assertEquals(connFactory.getBlockWaitTime(), Duration.ofSeconds(5));
+ assertEquals(connFactory.getName(), "resolver-pool");
+ assertEquals(connFactory.getMinPoolSize(), 5);
+ assertEquals(connFactory.getMaxPoolSize(), 10);
+ assertTrue(connFactory.isValidatePeriodically());
+ assertEquals(connFactory.getValidator().getValidatePeriod(), Duration.ofMinutes(15));
+ assertFalse(connFactory.getFailFastInitialize());
+
+ final SearchConnectionValidator searchValidator = (SearchConnectionValidator) connFactory.getValidator();
assertNotNull(searchValidator);
assertEquals(searchValidator.getSearchRequest().getBaseDn(), "dc=shibboleth,dc=net");
- assertEquals(searchValidator.getSearchRequest().getSearchFilter().getFilter(), "(ou=people)");
+ assertEquals(searchValidator.getSearchRequest().getFilter(), new EqualityFilter("ou", "people"));
- final IdlePruneStrategy pruneStrategy = (IdlePruneStrategy) connPool.getPruneStrategy();
+ final IdlePruneStrategy pruneStrategy = (IdlePruneStrategy) connFactory.getPruneStrategy();
assertNotNull(pruneStrategy);
assertEquals(pruneStrategy.getPrunePeriod(), Duration.ofMinutes(5));
assertEquals(pruneStrategy.getIdleTime(), Duration.ofMinutes(10));
- final ConnectionConfig connConfig = connPool.getConnectionFactory().getConnectionConfig();
+ final ConnectionConfig connConfig = connFactory.getConnectionConfig();
assertNotNull(connConfig);
assertEquals(connConfig.getLdapUrl(), "ldap://localhost:10389");
- assertFalse(connConfig.getUseSSL());
assertTrue(connConfig.getUseStartTLS());
- final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializer();
+ final BindConnectionInitializer connInitializer = (BindConnectionInitializer) connConfig.getConnectionInitializers()[0];
assertEquals(connInitializer.getBindDn(), "cn=Directory Manager");
assertEquals(connInitializer.getBindCredential().getString(), "password");
assertEquals(connConfig.getConnectTimeout(), Duration.ofSeconds(2));
assertEquals(connConfig.getResponseTimeout(), Duration.ofSeconds(4));
- final SslConfig sslConfig = connPool.getConnectionFactory().getConnectionConfig().getSslConfig();
+ final SslConfig sslConfig = connFactory.getConnectionConfig().getSslConfig();
assertNotNull(sslConfig);
final CredentialConfig credentialConfig = sslConfig.getCredentialConfig();
assertNotNull(credentialConfig);
- final SearchExecutor searchExecutor = dataConnector.getSearchExecutor();
- assertNotNull(searchExecutor);
- assertEquals(searchExecutor.getBaseDn(), "ou=people,dc=shibboleth,dc=net");
- assertNull(searchExecutor.getSearchFilter());
- assertEquals(searchExecutor.getTimeLimit(), Duration.ofSeconds(7));
- assertNull(searchExecutor.getReferralHandler());
+ final SearchOperation searchOperation = dataConnector.getSearchOperation();
+ assertNotNull(searchOperation);
+ assertEquals(searchOperation.getRequest().getBaseDn(), "ou=people,dc=shibboleth,dc=net");
+ assertNull(searchOperation.getRequest().getFilter());
+ assertEquals(searchOperation.getRequest().getTimeLimit(), Duration.ofSeconds(7));
+ assertNull(searchOperation.getSearchResultHandlers());
final ConnectionFactoryValidator validator = (ConnectionFactoryValidator) dataConnector.getValidator();
assertNotNull(validator);
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-context.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-context.xml
index 932903987..e156f4a73 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-context.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-context.xml
@@ -2,53 +2,53 @@
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
- <bean id="connectionFactory" class="org.ldaptive.pool.PooledConnectionFactory">
- <property name="connectionPool">
- <bean class="org.ldaptive.pool.BlockingConnectionPool" init-method="initialize" p:blockWaitTime="PT5S" p:failFastInitialize="false" p:name="resolver-pool">
- <constructor-arg index="0">
- <bean class="org.ldaptive.pool.PoolConfig" p:minPoolSize="5" p:maxPoolSize="10"
- p:validatePeriodically="true" p:validatePeriod="PT15M" />
- </constructor-arg>
- <constructor-arg index="1">
- <bean class="org.ldaptive.DefaultConnectionFactory">
- <property name="connectionConfig">
- <bean class="org.ldaptive.ConnectionConfig" p:ldapUrl="ldap://localhost:10389"
- p:useStartTLS="true" p:connectTimeout="PT2S" p:responseTimeout="PT4S">
- <property name="connectionInitializer">
- <bean class="org.ldaptive.BindConnectionInitializer" p:bindDn="cn=Directory Manager"
- p:bindCredential="password" />
- </property>
- <property name="sslConfig">
- <bean class="org.ldaptive.ssl.SslConfig">
- <property name="credentialConfig">
- <bean class="org.ldaptive.ssl.X509CredentialConfig"
- p:trustCertificates="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/server.crt"
- p:authenticationCertificate="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.crt"
- p:authenticationKey="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.pkcs8" />
- </property>
- </bean>
- </property>
- </bean>
- </property>
- </bean>
- </constructor-arg>
- <property name="validator">
- <bean class="org.ldaptive.pool.SearchValidator">
- <property name="searchRequest">
- <bean class="org.ldaptive.SearchRequest">
- <constructor-arg value="dc=shibboleth,dc=net" />
- <constructor-arg value="(ou=people)" />
- </bean>
+ <bean id="connectionFactory" class="org.ldaptive.PooledConnectionFactory" init-method="initialize"
+ p:blockWaitTime="PT5S"
+ p:failFastInitialize="false"
+ p:name="resolver-pool"
+ p:minPoolSize="5"
+ p:maxPoolSize="10"
+ p:validatePeriodically="true">
+ <property name="connectionConfig">
+ <bean class="org.ldaptive.ConnectionConfig" p:ldapUrl="ldap://localhost:10389"
+ p:useStartTLS="true"
+ p:connectTimeout="PT2S" p:responseTimeout="PT4S">
+ <property name="connectionInitializers">
+ <bean class="org.ldaptive.BindConnectionInitializer" p:bindDn="cn=Directory Manager"
+ p:bindCredential="password" />
+ </property>
+ <property name="sslConfig">
+ <bean class="org.ldaptive.ssl.SslConfig">
+ <property name="credentialConfig">
+ <bean class="org.ldaptive.ssl.X509CredentialConfig"
+ p:trustCertificates="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/server.crt"
+ p:authenticationCertificate="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.crt"
+ p:authenticationKey="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.pkcs8" />
</property>
</bean>
</property>
- <property name="pruneStrategy">
- <bean class="org.ldaptive.pool.IdlePruneStrategy" p:prunePeriod="PT5M" p:idleTime="PT10M" />
+ </bean>
+ </property>
+ <property name="validator">
+ <bean class="org.ldaptive.SearchConnectionValidator" p:validatePeriod="PT15M">
+ <property name="searchRequest">
+ <bean class="org.ldaptive.SearchRequest">
+ <constructor-arg value="dc=shibboleth,dc=net" />
+ <constructor-arg value="(ou=people)" />
+ </bean>
</property>
</bean>
</property>
+ <property name="pruneStrategy">
+ <bean class="org.ldaptive.pool.IdlePruneStrategy" p:prunePeriod="PT5M"
+ p:idleTime="PT10M" />
+ </property>
+ </bean>
+ <bean class="org.ldaptive.SearchOperation">
+ <property name="request">
+ <bean class="org.ldaptive.SearchRequest" p:baseDn="ou=people,dc=shibboleth,dc=net" p:returnAttributes="uid,homephone,mail" p:timeLimit="PT7S" />
+ </property>
</bean>
- <bean class="org.ldaptive.SearchExecutor" p:baseDn="ou=people,dc=shibboleth,dc=net" p:returnAttributes="uid,homephone,mail" p:timeLimit="PT7S" />
<bean id="cache" class="com.google.common.cache.Cache" factory-bean="cacheBuilderExternal" factory-method="build" />
<bean id="filter" class="net.shibboleth.idp.attribute.resolver.dc.ldap.TemplatedExecutableSearchFilterBuilder"
p:templateText="(uid=${resolutionContext.principal})" p:velocityEngine-ref="shibboleth.VelocityEngine"
@@ -62,5 +62,5 @@
</property>
</bean>
<bean id="validator" class="net.shibboleth.idp.attribute.resolver.dc.ldap.impl.ConnectionFactoryValidator"
- p:connectionFactory-ref="connectionFactory" p:throwValidateError="true" />
+ p:connectionFactory-ref="connectionFactory" p:throwValidateError="true" />
</beans>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-props-context.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-props-context.xml
index c2fd91d9a..e11b6a604 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-props-context.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/ldap-attribute-resolver-spring-props-context.xml
@@ -4,57 +4,53 @@
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
- <bean id="connectionFactory" class="org.ldaptive.pool.PooledConnectionFactory">
- <property name="connectionPool">
- <bean class="org.ldaptive.pool.BlockingConnectionPool" init-method="initialize"
- p:blockWaitTime="%{connectionPool.blockWaitTime}" p:failFastInitialize="%{connectionPool.failFastInitialize}" p:name="resolver-pool">
- <constructor-arg index="0">
- <bean class="org.ldaptive.pool.PoolConfig" p:minPoolSize="%{connectionPool.minPoolSize}"
- p:maxPoolSize="%{connectionPool.maxPoolSize}" p:validatePeriodically="%{connectionPool.validatePeriodically}"
- p:validatePeriod="%{connectionPool.validatePeriod}" />
- </constructor-arg>
- <constructor-arg index="1">
- <bean class="org.ldaptive.DefaultConnectionFactory">
- <property name="connectionConfig">
- <bean class="org.ldaptive.ConnectionConfig" p:ldapUrl="%{connectionConfig.ldapURL}"
- p:useStartTLS="%{connectionConfig.useStartTLS}"
- p:connectTimeout="%{connectionConfig.connectTimeout}" p:responseTimeout="%{connectionConfig.responseTimeout}">
- <property name="connectionInitializer">
- <bean class="org.ldaptive.BindConnectionInitializer" p:bindDn="%{connectionConfig.bindDn}"
- p:bindCredential="%{connectionConfig.bindCredential}" />
- </property>
- <property name="sslConfig">
- <bean class="org.ldaptive.ssl.SslConfig">
- <property name="credentialConfig">
- <bean class="org.ldaptive.ssl.X509CredentialConfig"
- p:trustCertificates="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/server.crt"
- p:authenticationCertificate="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.crt"
- p:authenticationKey="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.pkcs8" />
- </property>
- </bean>
- </property>
- </bean>
- </property>
- </bean>
- </constructor-arg>
- <property name="validator">
- <bean class="org.ldaptive.pool.SearchValidator">
- <property name="searchRequest">
- <bean class="org.ldaptive.SearchRequest">
- <constructor-arg value="%{connectionPool.validator.baseDn}" />
- <constructor-arg value="%{connectionPool.validator.filter}" />
- </bean>
+ <bean id="connectionFactory" class="org.ldaptive.PooledConnectionFactory" init-method="initialize"
+ p:blockWaitTime="%{connectionPool.blockWaitTime}"
+ p:failFastInitialize="%{connectionPool.failFastInitialize}"
+ p:name="resolver-pool"
+ p:minPoolSize="%{connectionPool.minPoolSize}"
+ p:maxPoolSize="%{connectionPool.maxPoolSize}"
+ p:validatePeriodically="%{connectionPool.validatePeriodically}">
+ <property name="connectionConfig">
+ <bean class="org.ldaptive.ConnectionConfig" p:ldapUrl="%{connectionConfig.ldapURL}"
+ p:useStartTLS="%{connectionConfig.useStartTLS}"
+ p:connectTimeout="%{connectionConfig.connectTimeout}" p:responseTimeout="%{connectionConfig.responseTimeout}">
+ <property name="connectionInitializers">
+ <bean class="org.ldaptive.BindConnectionInitializer" p:bindDn="%{connectionConfig.bindDn}"
+ p:bindCredential="%{connectionConfig.bindCredential}" />
+ </property>
+ <property name="sslConfig">
+ <bean class="org.ldaptive.ssl.SslConfig">
+ <property name="credentialConfig">
+ <bean class="org.ldaptive.ssl.X509CredentialConfig"
+ p:trustCertificates="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/server.crt"
+ p:authenticationCertificate="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.crt"
+ p:authenticationKey="file:src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/client.pkcs8" />
</property>
</bean>
</property>
- <property name="pruneStrategy">
- <bean class="org.ldaptive.pool.IdlePruneStrategy" p:prunePeriod="%{connectionPool.pruneStrategy.prunePeriod}"
- p:idleTime="%{connectionPool.pruneStrategy.idleTime}" />
+ </bean>
+ </property>
+ <property name="validator">
+ <bean class="org.ldaptive.SearchConnectionValidator" p:validatePeriod="%{connectionPool.validatePeriod}">
+ <property name="searchRequest">
+ <bean class="org.ldaptive.SearchRequest">
+ <constructor-arg value="%{connectionPool.validator.baseDn}" />
+ <constructor-arg value="%{connectionPool.validator.filter}" />
+ </bean>
</property>
</bean>
</property>
+ <property name="pruneStrategy">
+ <bean class="org.ldaptive.pool.IdlePruneStrategy" p:prunePeriod="%{connectionPool.pruneStrategy.prunePeriod}"
+ p:idleTime="%{connectionPool.pruneStrategy.idleTime}" />
+ </property>
+ </bean>
+ <bean class="org.ldaptive.SearchOperation">
+ <property name="request">
+ <bean class="org.ldaptive.SearchRequest" p:baseDn="%{search.baseDn}" p:returnAttributes="%{search.returnAttributes}" p:timeLimit="%{search.timeLimit}" />
+ </property>
</bean>
- <bean class="org.ldaptive.SearchExecutor" p:baseDn="%{search.baseDn}" p:returnAttributes="%{search.returnAttributes}" p:timeLimit="%{search.timeLimit}" />
<bean id="cacheBuilder" class="com.google.common.cache.CacheBuilder" factory-method="from">
<constructor-arg value="%{cache.cacheBuilderSpec}" />
</bean>
@@ -70,7 +66,6 @@
</map>
</property>
</bean>
- <bean id="validator" class="net.shibboleth.idp.attribute.resolver.dc.ldap.impl.ConnectionFactoryValidator"
- p:connectionFactory-ref="connectionFactory" p:throwValidateError="true" />
-
+ <bean id="validator" class="net.shibboleth.idp.attribute.resolver.dc.ldap.impl.ConnectionFactoryValidator"
+ p:connectionFactory-ref="connectionFactory" p:throwValidateError="true" />
</beans>
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractTemplateSearchDnResolver.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractTemplateSearchDnResolver.java
index 40497cfe3..66eaa9d4e 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractTemplateSearchDnResolver.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractTemplateSearchDnResolver.java
@@ -29,14 +29,14 @@ import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.VelocityException;
-import org.ldaptive.SearchFilter;
-import org.ldaptive.auth.AbstractSearchDnResolver;
+import org.ldaptive.FilterTemplate;
+import org.ldaptive.auth.SearchDnResolver;
import org.ldaptive.auth.User;
/**
* Base class for {@link Template} based search dn resolvers.
*/
-public abstract class AbstractTemplateSearchDnResolver extends AbstractSearchDnResolver {
+public abstract class AbstractTemplateSearchDnResolver extends SearchDnResolver {
/** Template. */
private final Template template;
@@ -66,8 +66,8 @@ public abstract class AbstractTemplateSearchDnResolver extends AbstractSearchDnR
return template;
}
- @Override protected SearchFilter createSearchFilter(final User user) {
- final SearchFilter filter = new SearchFilter();
+ @Override protected FilterTemplate createFilterTemplate(final User user) {
+ final FilterTemplate filter = new FilterTemplate();
if (user != null && user.getContext() != null) {
final VelocityContext context = (VelocityContext) user.getContext();
final EventCartridge cartridge = new EventCartridge();
@@ -116,7 +116,7 @@ public abstract class AbstractTemplateSearchDnResolver extends AbstractSearchDnR
}
/**
- * Returns {@link SearchFilter#encodeValue} if value is a string or byte array.
+ * Returns {@link FilterTemplate#encodeValue} if value is a string or byte array.
*
* @param value to encode
*
@@ -124,9 +124,9 @@ public abstract class AbstractTemplateSearchDnResolver extends AbstractSearchDnR
*/
private Object encode(final Object value) {
if (value instanceof String){
- return SearchFilter.encodeValue((String) value);
+ return FilterTemplate.encodeValue((String) value);
} else if (value instanceof byte[]) {
- return SearchFilter.encodeValue((byte[]) value);
+ return FilterTemplate.encodeValue((byte[]) value);
}
return value;
}
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/PooledTemplateSearchDnResolver.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/PooledTemplateSearchDnResolver.java
deleted file mode 100644
index 93324ac14..000000000
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/PooledTemplateSearchDnResolver.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID licenses this file to You under the Apache
- * License, Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.authn;
-
-import java.util.Arrays;
-import org.apache.velocity.app.VelocityEngine;
-import org.apache.velocity.exception.VelocityException;
-import org.ldaptive.Connection;
-import org.ldaptive.LdapException;
-import org.ldaptive.pool.PooledConnectionFactory;
-import org.ldaptive.pool.PooledConnectionFactoryManager;
-
-/**
- * {@link net.shibboleth.utilities.java.support.velocity.Template}-based pooled search dn resolver.
- */
-public class PooledTemplateSearchDnResolver extends AbstractTemplateSearchDnResolver
- implements PooledConnectionFactoryManager {
-
- /** Connection factory. */
- private PooledConnectionFactory factory;
-
- /**
- * Creates a new pooled template search DN resolver.
- *
- * @param engine velocity engine
- * @param filter filter template
- *
- * @throws VelocityException if velocity is not configured properly or the filter template is invalid
- */
- public PooledTemplateSearchDnResolver(final VelocityEngine engine, final String filter) throws VelocityException {
- super(engine, filter);
- }
-
- /**
- * Creates a new pooled template search DN resolver.
- *
- * @param cf connection factory
- * @param engine velocity engine
- * @param filter filter template
- *
- * @throws VelocityException if velocity is not configured properly or the filter template is invalid
- */
- public PooledTemplateSearchDnResolver(final PooledConnectionFactory cf, final VelocityEngine engine,
- final String filter) throws VelocityException {
- super(engine, filter);
- setConnectionFactory(cf);
- }
-
- @Override public PooledConnectionFactory getConnectionFactory() {
- return factory;
- }
-
- @Override public void setConnectionFactory(final PooledConnectionFactory cf) {
- factory = cf;
- }
-
- @Override protected Connection getConnection() throws LdapException {
- return factory.getConnection();
- }
-
- @Override public String toString() {
- return String.format(
- "[%s@%d::factory=%s, templateName=%s, baseDn=%s, userFilter=%s, userFilterParameters=%s, "
- + "allowMultipleDns=%s, subtreeSearch=%s, derefAliases=%s]",
- getClass().getName(), hashCode(), factory, getTemplate().getTemplateName(), getBaseDn(),
- getUserFilter(), Arrays.toString(getUserFilterParameters()), getAllowMultipleDns(), getSubtreeSearch(),
- getDerefAliases());
- }
-}
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/TemplateSearchDnResolver.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/TemplateSearchDnResolver.java
index b09c59ad6..af8910d23 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/TemplateSearchDnResolver.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/TemplateSearchDnResolver.java
@@ -30,9 +30,6 @@ import org.ldaptive.LdapException;
*/
public class TemplateSearchDnResolver extends AbstractTemplateSearchDnResolver implements ConnectionFactoryManager {
- /** Connection factory. */
- private ConnectionFactory factory;
-
/**
* Creates a new template search DN resolver.
*
@@ -60,25 +57,11 @@ public class TemplateSearchDnResolver extends AbstractTemplateSearchDnResolver i
setConnectionFactory(cf);
}
- @Override public ConnectionFactory getConnectionFactory() {
- return factory;
- }
-
- @Override public void setConnectionFactory(final ConnectionFactory cf) {
- factory = cf;
- }
-
- @Override protected Connection getConnection() throws LdapException {
- final Connection conn = factory.getConnection();
- conn.open();
- return conn;
- }
-
@Override public String toString() {
return String.format(
"[%s@%d::factory=%s, templateName=%s, baseDn=%s, userFilter=%s, userFilterParameters=%s, "
+ "allowMultipleDns=%s, subtreeSearch=%s, derefAliases=%s]",
- getClass().getName(), hashCode(), factory, getTemplate().getTemplateName(), getBaseDn(),
+ getClass().getName(), hashCode(), getConnectionFactory(), getTemplate().getTemplateName(), getBaseDn(),
getUserFilter(), Arrays.toString(getUserFilterParameters()), getAllowMultipleDns(), getSubtreeSearch(),
getDerefAliases());
}
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/LDAPAuthenticationFactoryBean.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/LDAPAuthenticationFactoryBean.java
index a1078a096..63c8b5f2d 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/LDAPAuthenticationFactoryBean.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/LDAPAuthenticationFactoryBean.java
@@ -20,31 +20,28 @@ package net.shibboleth.idp.authn.config;
import java.time.Duration;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.idp.authn.PooledTemplateSearchDnResolver;
+
import net.shibboleth.idp.authn.TemplateSearchDnResolver;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.primitive.DeprecationSupport;
-import net.shibboleth.utilities.java.support.primitive.DeprecationSupport.ObjectType;
import org.apache.velocity.app.VelocityEngine;
import org.ldaptive.ActivePassiveConnectionStrategy;
import org.ldaptive.BindConnectionInitializer;
-import org.ldaptive.BindRequest;
import org.ldaptive.ConnectionConfig;
import org.ldaptive.ConnectionInitializer;
import org.ldaptive.Credential;
import org.ldaptive.DefaultConnectionFactory;
-import org.ldaptive.LdapURL;
+import org.ldaptive.FilterTemplate;
+import org.ldaptive.PooledConnectionFactory;
import org.ldaptive.RandomConnectionStrategy;
import org.ldaptive.RoundRobinConnectionStrategy;
-import org.ldaptive.SearchFilter;
+import org.ldaptive.SearchConnectionValidator;
import org.ldaptive.SearchRequest;
import org.ldaptive.SearchScope;
+import org.ldaptive.SimpleBindRequest;
import org.ldaptive.auth.Authenticator;
-import org.ldaptive.auth.BindAuthenticationHandler;
+import org.ldaptive.auth.SimpleBindAuthenticationHandler;
import org.ldaptive.auth.FormatDnResolver;
-import org.ldaptive.auth.PooledBindAuthenticationHandler;
-import org.ldaptive.auth.PooledSearchEntryResolver;
import org.ldaptive.auth.SearchEntryResolver;
import org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler;
import org.ldaptive.auth.ext.EDirectoryAuthenticationResponseHandler;
@@ -52,13 +49,9 @@ import org.ldaptive.auth.ext.FreeIPAAuthenticationResponseHandler;
import org.ldaptive.auth.ext.PasswordExpirationAuthenticationResponseHandler;
import org.ldaptive.auth.ext.PasswordPolicyAuthenticationRequestHandler;
import org.ldaptive.auth.ext.PasswordPolicyAuthenticationResponseHandler;
-import org.ldaptive.pool.BindPassivator;
-import org.ldaptive.pool.BlockingConnectionPool;
+import org.ldaptive.pool.BindConnectionPassivator;
import org.ldaptive.pool.IdlePruneStrategy;
-import org.ldaptive.pool.Passivator;
-import org.ldaptive.pool.PoolConfig;
-import org.ldaptive.pool.PooledConnectionFactory;
-import org.ldaptive.pool.SearchValidator;
+import org.ldaptive.pool.ConnectionPassivator;
import org.ldaptive.ssl.AllowAnyHostnameVerifier;
import org.ldaptive.ssl.CredentialConfig;
import org.ldaptive.ssl.SslConfig;
@@ -197,9 +190,6 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
/** Whether to use startTLS for connections. */
private boolean useStartTLS;
- /** Whether to use LDAPS for connections. */
- private boolean useSSL;
-
/** Whether to use the allow-all hostname verifier. */
private boolean disableHostnameVerification;
@@ -322,10 +312,6 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
useStartTLS = b;
}
- public void setUseSSL(final boolean b) {
- useSSL = b;
- }
-
public void setDisableHostnameVerification(final boolean b) {
disableHostnameVerification = b;
}
@@ -515,25 +501,26 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
}
config.setSslConfig(createSslConfig());
if (initializer != null) {
- config.setConnectionInitializer(initializer);
+ config.setConnectionInitializers(initializer);
}
return config;
}
/**
- * Returns a new blocking connection pool. Wires a {@link SearchValidator} by default.
+ * Returns a new pooled connection factory. Wires a {@link SearchConnectionValidator} by default.
*
* @param name of the connection pool
* @param config to assign to the pool
*
* @return new blocking connection pool
*/
- protected BlockingConnectionPool createConnectionPool(final String name, final ConnectionConfig config) {
- return createConnectionPool(name, config, new SearchValidator());
+ protected PooledConnectionFactory createPooledConnectionFactory(final String name, final ConnectionConfig config) {
+ return createPooledConnectionFactory(
+ name, config, SearchConnectionValidator.builder().period(validatePeriod).build());
}
/**
- * Returns a new blocking connection pool using the supplied search validator.
+ * Returns a new pooled connection factory using the supplied search validator.
*
* @param name of the connection pool
* @param config to assign to the pool
@@ -541,9 +528,9 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
*
* @return new blocking connection pool
*/
- protected BlockingConnectionPool createConnectionPool(final String name, final ConnectionConfig config,
- final SearchValidator validator) {
- return createConnectionPool(name, config, validator, null);
+ protected PooledConnectionFactory createPooledConnectionFactory(final String name, final ConnectionConfig config,
+ final SearchConnectionValidator validator) {
+ return createPooledConnectionFactory(name, config, validator, null);
}
/**
@@ -557,28 +544,28 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
*
* @return new blocking connection pool
*/
- protected BlockingConnectionPool createConnectionPool(final String name, final ConnectionConfig config,
- final SearchValidator validator, final Passivator passivator) {
- final PoolConfig poolConfig = new PoolConfig();
- poolConfig.setMinPoolSize(minPoolSize);
- poolConfig.setMaxPoolSize(maxPoolSize);
- poolConfig.setValidateOnCheckOut(validateOnCheckout);
- poolConfig.setValidatePeriodically(validatePeriodically);
- poolConfig.setValidatePeriod(validatePeriod);
- final BlockingConnectionPool pool = new BlockingConnectionPool();
- pool.setName(name);
- pool.setBlockWaitTime(blockWaitTime);
- pool.setPoolConfig(poolConfig);
- pool.setPruneStrategy(new IdlePruneStrategy(prunePeriod, idleTime));
- pool.setValidator(validator);
- pool.setPassivator(passivator);
- pool.setFailFastInitialize(false);
- pool.setConnectionFactory(new DefaultConnectionFactory(config));
- pool.initialize();
- return pool;
- }
-
- protected SearchValidator createSearchValidator(final String baseDn, final String filter) {
+ protected PooledConnectionFactory createPooledConnectionFactory(
+ final String name, final ConnectionConfig config,
+ final SearchConnectionValidator validator, final ConnectionPassivator passivator) {
+ final PooledConnectionFactory factory = new PooledConnectionFactory();
+ factory.setConnectionConfig(config);
+ factory.setMinPoolSize(minPoolSize);
+ factory.setMaxPoolSize(maxPoolSize);
+ factory.setValidateOnCheckOut(validateOnCheckout);
+ factory.setValidatePeriodically(validatePeriodically);
+ factory.setName(name);
+ factory.setBlockWaitTime(blockWaitTime);
+ factory.setPruneStrategy(new IdlePruneStrategy(prunePeriod, idleTime));
+ factory.setValidator(validator);
+ if (passivator != null) {
+ factory.setPassivator(passivator);
+ }
+ factory.setFailFastInitialize(false);
+ factory.initialize();
+ return factory;
+ }
+
+ protected SearchConnectionValidator createSearchValidator(final String baseDn, final String filter) {
final SearchRequest searchRequest = new SearchRequest();
searchRequest.setReturnAttributes("1.1");
searchRequest.setSearchScope(SearchScope.OBJECT);
@@ -588,22 +575,22 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
} else {
searchRequest.setBaseDn("");
}
- final SearchFilter searchFilter = new SearchFilter();
+ final FilterTemplate searchFilter = new FilterTemplate();
if (filter != null) {
searchFilter.setFilter(filter);
} else {
searchFilter.setFilter("(objectClass=*)");
}
- searchRequest.setSearchFilter(searchFilter);
- return new SearchValidator(searchRequest);
+ searchRequest.setFilter(searchFilter);
+ return SearchConnectionValidator.builder().request(searchRequest).period(validatePeriod).build();
}
- protected Passivator createPoolPassivator(final PassivatorType type) {
+ protected ConnectionPassivator createPoolPassivator(final PassivatorType type) {
switch(type) {
case BIND:
- return new BindPassivator(new BindRequest(bindDn, new Credential(bindDnCredential)));
+ return new BindConnectionPassivator(new SimpleBindRequest(bindDn, new Credential(bindDnCredential)));
case ANONYMOUS_BIND:
- return new BindPassivator();
+ return new BindConnectionPassivator();
case NONE:
default:
return null;
@@ -613,30 +600,18 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
// Checkstyle: CyclomaticComplexity|MethodLength OFF
@Override
protected Authenticator createInstance() throws Exception {
- // check for deprecated useSSL property
- if (useSSL) {
- DeprecationSupport.warn(ObjectType.PROPERTY, "useSSL", "LDAP authentication",
- "use of ldaps:// scheme in connection URL");
- final LdapURL url = new LdapURL(ldapUrl);
- for (final String s : url.getHostnamesWithSchemeAndPort()) {
- if (!s.startsWith("ldaps://")) {
- throw new IllegalArgumentException("useSSL property specified but URL scheme is not ldaps:// for " + s);
- }
- }
- }
final Authenticator authenticator = new Authenticator();
if (disablePooling) {
authenticator.setAuthenticationHandler(
- new BindAuthenticationHandler(new DefaultConnectionFactory(createConnectionConfig())));
+ new SimpleBindAuthenticationHandler(new DefaultConnectionFactory(createConnectionConfig())));
} else {
authenticator.setAuthenticationHandler(
- new PooledBindAuthenticationHandler(
- new PooledConnectionFactory(
- createConnectionPool(
+ new SimpleBindAuthenticationHandler(
+ createPooledConnectionFactory(
"bind-pool",
createConnectionConfig(),
createSearchValidator(validateDn, validateFilter),
- createPoolPassivator(bindPoolPassivatorType)))));
+ createPoolPassivator(bindPoolPassivatorType))));
}
switch(authenticatorType) {
case BIND_SEARCH:
@@ -650,16 +625,15 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
createConnectionConfig(new BindConnectionInitializer(bindDn, new Credential(bindDnCredential)))));
authenticator.setDnResolver(bindSearchDnResolver);
} else {
- final PooledTemplateSearchDnResolver bindSearchDnResolver =
- new PooledTemplateSearchDnResolver(velocityEngine, userFilter);
+ final TemplateSearchDnResolver bindSearchDnResolver =
+ new TemplateSearchDnResolver(velocityEngine, userFilter);
bindSearchDnResolver.setBaseDn(baseDn);
bindSearchDnResolver.setSubtreeSearch(subtreeSearch);
bindSearchDnResolver.setConnectionFactory(
- new PooledConnectionFactory(
- createConnectionPool(
+ createPooledConnectionFactory(
"dn-search-pool",
createConnectionConfig(new BindConnectionInitializer(bindDn, new Credential(bindDnCredential))),
- createSearchValidator(validateDn, validateFilter))));
+ createSearchValidator(validateDn, validateFilter)));
authenticator.setDnResolver(bindSearchDnResolver);
}
authenticator.setResolveEntryOnFailure(resolveEntryOnFailure);
@@ -671,7 +645,7 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
case AD:
authenticator.setDnResolver(new FormatDnResolver(dnFormat));
authenticator.setResolveEntryOnFailure(resolveEntryOnFailure);
- authenticator.setAuthenticationResponseHandlers(new ActiveDirectoryAuthenticationResponseHandler());
+ authenticator.setResponseHandlers(new ActiveDirectoryAuthenticationResponseHandler());
break;
case ANON_SEARCH:
if (disablePooling) {
@@ -682,16 +656,15 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
anonSearchDnResolver.setConnectionFactory(new DefaultConnectionFactory(createConnectionConfig()));
authenticator.setDnResolver(anonSearchDnResolver);
} else {
- final PooledTemplateSearchDnResolver anonSearchDnResolver =
- new PooledTemplateSearchDnResolver(velocityEngine, userFilter);
+ final TemplateSearchDnResolver anonSearchDnResolver =
+ new TemplateSearchDnResolver(velocityEngine, userFilter);
anonSearchDnResolver.setBaseDn(baseDn);
anonSearchDnResolver.setSubtreeSearch(subtreeSearch);
anonSearchDnResolver.setConnectionFactory(
- new PooledConnectionFactory(
- createConnectionPool(
+ createPooledConnectionFactory(
"dn-search-pool",
createConnectionConfig(),
- createSearchValidator(validateDn, validateFilter))));
+ createSearchValidator(validateDn, validateFilter)));
authenticator.setDnResolver(anonSearchDnResolver);
}
authenticator.setResolveEntryOnFailure(resolveEntryOnFailure);
@@ -708,28 +681,27 @@ public class LDAPAuthenticationFactoryBean extends AbstractFactoryBean<Authentic
createConnectionConfig(new BindConnectionInitializer(bindDn, new Credential(bindDnCredential)))));
authenticator.setEntryResolver(searchEntryResolver);
} else {
- final PooledSearchEntryResolver searchEntryResolver = new PooledSearchEntryResolver();
+ final SearchEntryResolver searchEntryResolver = new SearchEntryResolver();
searchEntryResolver.setConnectionFactory(
- new PooledConnectionFactory(
- createConnectionPool(
+ createPooledConnectionFactory(
"entry-search-pool",
createConnectionConfig(new BindConnectionInitializer(bindDn, new Credential(bindDnCredential))),
- createSearchValidator(validateDn, validateFilter))));
+ createSearchValidator(validateDn, validateFilter)));
authenticator.setEntryResolver(searchEntryResolver);
}
}
if (usePasswordPolicy) {
- authenticator.setAuthenticationRequestHandlers(new PasswordPolicyAuthenticationRequestHandler());
- authenticator.setAuthenticationResponseHandlers(new PasswordPolicyAuthenticationResponseHandler());
+ authenticator.setRequestHandlers(new PasswordPolicyAuthenticationRequestHandler());
+ authenticator.setResponseHandlers(new PasswordPolicyAuthenticationResponseHandler());
} else if (usePasswordExpiration) {
- authenticator.setAuthenticationResponseHandlers(new PasswordExpirationAuthenticationResponseHandler());
+ authenticator.setResponseHandlers(new PasswordExpirationAuthenticationResponseHandler());
} else if (isActiveDirectory) {
- authenticator.setAuthenticationResponseHandlers(new ActiveDirectoryAuthenticationResponseHandler());
+ authenticator.setResponseHandlers(new ActiveDirectoryAuthenticationResponseHandler());
} else if (isEDirectory) {
- authenticator.setAuthenticationResponseHandlers(new EDirectoryAuthenticationResponseHandler());
+ authenticator.setResponseHandlers(new EDirectoryAuthenticationResponseHandler());
} else if (isFreeIPA) {
- authenticator.setAuthenticationResponseHandlers(new FreeIPAAuthenticationResponseHandler());
+ authenticator.setResponseHandlers(new FreeIPAAuthenticationResponseHandler());
}
return authenticator;
}
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidator.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidator.java
index 51f6c91aa..95b9babb7 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidator.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidator.java
@@ -35,6 +35,7 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
import org.apache.velocity.VelocityContext;
+import org.ldaptive.ConnectException;
import org.ldaptive.Credential;
import org.ldaptive.LdapException;
import org.ldaptive.ResultCode;
@@ -140,71 +141,75 @@ public class LDAPCredentialValidator extends AbstractUsernamePasswordCredentialV
@Nullable final ErrorHandler errorHandler) throws Exception {
final String username = usernamePasswordContext.getTransformedUsername();
-
- String eventToSignal = AuthnEventIds.INVALID_CREDENTIALS;
-
- // The error handling is squonky. We log at info to generically record the failure.
- // Known conditions are not explicitly logged but are wrapped with an exception and
- // reported out to the caller. Last ditch, an exception is logged on warn and then
- // reported out.
-
+
+ log.debug("{} Attempting to authenticate user {}", getLogPrefix(), username);
+ final VelocityContext context = new VelocityContext();
+ context.put("usernamePasswordContext", usernamePasswordContext);
+ final char[] password = passwordLookupStrategy != null ?
+ passwordLookupStrategy.apply(profileRequestContext) :
+ usernamePasswordContext.getPassword().toCharArray();
+ final AuthenticationRequest request = new AuthenticationRequest(
+ new User(username, context), new Credential(password), returnAttributes);
+ final AuthenticationResponse response;
try {
- log.debug("{} Attempting to authenticate user {}", getLogPrefix(), username);
- final VelocityContext context = new VelocityContext();
- context.put("usernamePasswordContext", usernamePasswordContext);
- final char[] password = passwordLookupStrategy != null ?
- passwordLookupStrategy.apply(profileRequestContext) :
- usernamePasswordContext.getPassword().toCharArray();
- final AuthenticationRequest request = new AuthenticationRequest(
- new User(username, context), new Credential(password), returnAttributes);
- final AuthenticationResponse response = authenticator.authenticate(request);
- log.trace("{} Authentication response {}", getLogPrefix(), response);
- if (response.getResult()) {
- log.info("{} Login by '{}' succeeded", getLogPrefix(), username);
- authenticationContext.getSubcontext(
- LDAPResponseContext.class, true).setAuthenticationResponse(response);
- if (response.getAccountState() != null) {
- final AccountState.Error error = response.getAccountState().getError();
- if (warningHandler != null) {
- warningHandler.handleWarning(
- profileRequestContext,
- authenticationContext,
- String.format("%s:%s:%s", error != null ? error : "ACCOUNT_WARNING",
- response.getResultCode(), response.getMessage()),
- AuthnEventIds.ACCOUNT_WARNING);
- }
- }
- return populateSubject(usernamePasswordContext, response);
- }
-
- authenticationContext.getSubcontext(
- LDAPResponseContext.class, true).setAuthenticationResponse(response);
- if (AuthenticationResultCode.DN_RESOLUTION_FAILURE == response.getAuthenticationResultCode()
- || AuthenticationResultCode.INVALID_CREDENTIAL == response.getAuthenticationResultCode()) {
- throw new LdapException(
- String.format("%s:%s", response.getAuthenticationResultCode(), response.getMessage()));
- } else if (response.getAccountState() != null) {
- final AccountState state = response.getAccountState();
- eventToSignal = AuthnEventIds.ACCOUNT_ERROR;
- throw new LdapException(
- String.format("%s:%s:%s", state.getError(), response.getResultCode(), response.getMessage())
- );
- } else if (response.getResultCode() == ResultCode.INVALID_CREDENTIALS) {
- throw new LdapException(String.format("%s:%s", response.getResultCode(), response.getMessage()));
- } else {
- eventToSignal = AuthnEventIds.AUTHN_EXCEPTION;
- final LdapException e =
- new LdapException(response.getMessage(), response.getResultCode(), response.getMatchedDn(),
- response.getControls(), response.getReferralURLs(), response.getMessageId());
- throw e;
- }
+ // authenticator should only throw for communication errors
+ response = authenticator.authenticate(request);
} catch (final LdapException e) {
- log.info("{} Login by '{}' failed", getLogPrefix(), username, e);
+ log.error("{} Error attempting LDAP authentication for '{}'", getLogPrefix(), username, e);
if (errorHandler != null) {
- errorHandler.handleError(profileRequestContext, authenticationContext, e, eventToSignal);
+ errorHandler.handleError(
+ profileRequestContext, authenticationContext, e, AuthnEventIds.AUTHN_EXCEPTION);
}
throw e;
}
+
+ log.trace("{} Authentication response {}", getLogPrefix(), response);
+ if (response.isSuccess()) {
+ log.info("{} Login by '{}' succeeded", getLogPrefix(), username);
+ authenticationContext.getSubcontext(
+ LDAPResponseContext.class, true).setAuthenticationResponse(response);
+ if (response.getAccountState() != null) {
+ final AccountState.Error error = response.getAccountState().getError();
+ if (warningHandler != null) {
+ warningHandler.handleWarning(
+ profileRequestContext,
+ authenticationContext,
+ String.format("%s:%s:%s", error != null ? error : "ACCOUNT_WARNING",
+ response.getResultCode(), response.getDiagnosticMessage()),
+ AuthnEventIds.ACCOUNT_WARNING);
+ }
+ }
+ return populateSubject(usernamePasswordContext, response);
+ }
+
+ String eventToSignal;
+ LdapException authException;
+ authenticationContext.getSubcontext(
+ LDAPResponseContext.class, true).setAuthenticationResponse(response);
+ if (AuthenticationResultCode.DN_RESOLUTION_FAILURE == response.getAuthenticationResultCode()
+ || AuthenticationResultCode.INVALID_CREDENTIAL == response.getAuthenticationResultCode()) {
+ eventToSignal = AuthnEventIds.INVALID_CREDENTIALS;
+ authException = new LdapException(
+ String.format("%s:%s", response.getAuthenticationResultCode(), response.getDiagnosticMessage()));
+ } else if (response.getAccountState() != null) {
+ final AccountState state = response.getAccountState();
+ eventToSignal = AuthnEventIds.ACCOUNT_ERROR;
+ authException = new LdapException(
+ String.format("%s:%s:%s", state.getError(), response.getResultCode(), response.getDiagnosticMessage()));
+ } else if (response.getResultCode() == ResultCode.INVALID_CREDENTIALS) {
+ eventToSignal = AuthnEventIds.INVALID_CREDENTIALS;
+ authException = new LdapException(
+ String.format("%s:%s", response.getResultCode(), response.getDiagnosticMessage()));
+ } else {
+ eventToSignal = AuthnEventIds.AUTHN_EXCEPTION;
+ authException = new LdapException(response);
+ }
+
+ log.info("{} Login by '{}' failed", getLogPrefix(), username, authException);
+ if (errorHandler != null) {
+ errorHandler.handleError(profileRequestContext, authenticationContext, authException, eventToSignal);
+ }
+ throw authException;
}
// Checkstyle: CyclomaticComplexity ON
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/LDAPPrincipalSerializer.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/LDAPPrincipalSerializer.java
index a81ea1d65..c97b159d0 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/LDAPPrincipalSerializer.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/principal/impl/LDAPPrincipalSerializer.java
@@ -135,9 +135,9 @@ public class LDAPPrincipalSerializer extends AbstractPrincipalSerializer<String>
} else {
final LdapAttribute attr = new LdapAttribute(e.getKey());
for (final JsonValue v : (JsonArray) e.getValue()) {
- attr.addStringValue(((JsonString) v).getString());
+ attr.addStringValues(((JsonString) v).getString());
}
- entry.addAttribute(attr);
+ entry.addAttributes(attr);
}
}
}
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java
index db1071f1b..7b174da23 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/DefaultAuthenticationResultSerializerTest.java
@@ -58,7 +58,6 @@ import net.shibboleth.utilities.java.support.test.resource.TestResourceConverter
import org.ldaptive.LdapAttribute;
import org.ldaptive.LdapEntry;
-import org.ldaptive.SortBehavior;
import org.ldaptive.jaas.LdapPrincipal;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.testing.RequestContextBuilder;
@@ -339,17 +338,17 @@ public class DefaultAuthenticationResultSerializerTest {
flowDescriptor.initialize();
final AuthenticationResult result = createResult(flowDescriptor, new Subject());
- final LdapEntry entry = new LdapEntry(SortBehavior.SORTED);
+ final LdapEntry entry = new LdapEntry();
entry.setDn("uid=1234,ou=people,dc=shibboleth,dc=net");
- final LdapAttribute givenName = new LdapAttribute(SortBehavior.SORTED);
+ final LdapAttribute givenName = new LdapAttribute();
givenName.setName("givenName");
- givenName.addStringValue("Bob", "Robert");
- entry.addAttribute(
+ givenName.addStringValues("Bob", "Robert");
+ entry.addAttributes(
new LdapAttribute("cn", "Bob Cobb"),
givenName,
new LdapAttribute("sn", "Cobb"),
new LdapAttribute("mail", "bob at shibboleth.net"));
- result.getSubject().getPrincipals().add(new LdapPrincipal("bob", entry));
+ result.getSubject().getPrincipals().add(new LdapPrincipal("bob", LdapEntry.sort(entry)));
final ProfileRequestContext prc = getProfileRequestContext(Collections.singletonList(flowDescriptor));
assertTrue(result.getReuseCondition().test(prc));
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidatorTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidatorTest.java
index 3aeb6ed72..d134c37b8 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidatorTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/LDAPCredentialValidatorTest.java
@@ -46,7 +46,7 @@ import org.ldaptive.auth.AuthenticationResponse;
import org.ldaptive.auth.AuthenticationResponseHandler;
import org.ldaptive.auth.AuthenticationResultCode;
import org.ldaptive.auth.Authenticator;
-import org.ldaptive.auth.BindAuthenticationHandler;
+import org.ldaptive.auth.SimpleBindAuthenticationHandler;
import org.ldaptive.auth.SearchDnResolver;
import org.ldaptive.auth.ext.PasswordPolicyAccountState;
import org.ldaptive.control.PasswordPolicyControl;
@@ -78,7 +78,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
private TemplateSearchDnResolver dnResolver;
- private BindAuthenticationHandler authHandler;
+ private SimpleBindAuthenticationHandler authHandler;
private Authenticator authenticator;
@@ -106,7 +106,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
VelocityEngine.newVelocityEngine(), "(uid=$usernamePasswordContext.username)");
dnResolver.setBaseDn("ou=people,dc=shibboleth,dc=net");
- authHandler = new BindAuthenticationHandler(new DefaultConnectionFactory("ldap://localhost:10389"));
+ authHandler = new SimpleBindAuthenticationHandler(new DefaultConnectionFactory("ldap://localhost:10389"));
authenticator = new Authenticator(dnResolver, authHandler);
}
@@ -170,6 +170,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
final Event event = action.execute(src);
Assert.assertNull(ac.getAuthenticationResult());
+ Assert.assertNull(ac.getSubcontext(LDAPResponseContext.class));
Assert.assertNull(ac.getSubcontext(AuthenticationErrorContext.class));
ActionTestingSupport.assertEvent(event, AuthnEventIds.NO_CREDENTIALS);
}
@@ -230,7 +231,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
ac.setAttemptedFlow(authenticationFlows.get(0));
validator.setAuthenticator(new Authenticator(dnResolver,
- new BindAuthenticationHandler(new DefaultConnectionFactory("ldap://unknown:389"))));
+ new SimpleBindAuthenticationHandler(new DefaultConnectionFactory("ldap://unknown:389"))));
validator.initialize();
action.initialize();
@@ -240,15 +241,10 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
final Event event = action.execute(src);
Assert.assertNull(ac.getAuthenticationResult());
- LDAPResponseContext lrc = ac.getSubcontext(LDAPResponseContext.class);
- Assert.assertNotNull(lrc.getAuthenticationResponse());
- Assert.assertEquals(lrc.getAuthenticationResponse().getAuthenticationResultCode(),
- AuthenticationResultCode.AUTHENTICATION_HANDLER_FAILURE);
-
+ Assert.assertNull(ac.getSubcontext(LDAPResponseContext.class));
AuthenticationErrorContext aec = ac.getSubcontext(AuthenticationErrorContext.class);
Assert.assertNotNull(aec);
ActionTestingSupport.assertEvent(event, AuthnEventIds.AUTHN_EXCEPTION);
- System.err.println("EXCEPTIONS:: " + aec.getExceptions());
Assert.assertEquals(aec.getExceptions().size(), 1);
Assert.assertEquals(aec.getClassifiedErrors().size(), 0);
}
@@ -297,6 +293,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
final Event event = action.execute(src);
Assert.assertNull(ac.getAuthenticationResult());
+ Assert.assertNull(ac.getSubcontext(LDAPResponseContext.class));
Assert.assertNull(ac.getSubcontext(AuthenticationErrorContext.class));
ActionTestingSupport.assertEvent(event, AuthnEventIds.INVALID_CREDENTIALS);
}
@@ -337,7 +334,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
ac.setAttemptedFlow(authenticationFlows.get(0));
Authenticator errorAuthenticator = new Authenticator(dnResolver, authHandler);
- errorAuthenticator.setAuthenticationResponseHandlers(new AuthenticationResponseHandler() {
+ errorAuthenticator.setResponseHandlers(new AuthenticationResponseHandler() {
public void handle(AuthenticationResponse response) throws LdapException {
response.setAccountState(new PasswordPolicyAccountState(PasswordPolicyControl.Error.PASSWORD_EXPIRED));
}
@@ -372,7 +369,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
ac.setAttemptedFlow(authenticationFlows.get(0));
Authenticator errorAuthenticator = new Authenticator(dnResolver, authHandler);
- errorAuthenticator.setAuthenticationResponseHandlers(new AuthenticationResponseHandler() {
+ errorAuthenticator.setResponseHandlers(new AuthenticationResponseHandler() {
public void handle(AuthenticationResponse response) throws LdapException {
response.setAccountState(
new PasswordPolicyAccountState(PasswordPolicyControl.Error.CHANGE_AFTER_RESET));
@@ -418,7 +415,7 @@ public class LDAPCredentialValidatorTest extends BaseAuthenticationContextTest {
ac.setAttemptedFlow(authenticationFlows.get(0));
Authenticator warningAuthenticator = new Authenticator(dnResolver, authHandler);
- warningAuthenticator.setAuthenticationResponseHandlers(new AuthenticationResponseHandler() {
+ warningAuthenticator.setResponseHandlers(new AuthenticationResponseHandler() {
public void handle(AuthenticationResponse response) throws LdapException {
response.setAccountState(
new AccountState(new AccountState.DefaultWarning(ZonedDateTime.now(), 10)));
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateCredentialsTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateCredentialsTest.java
index d4103cddf..6ee2380e1 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateCredentialsTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/ValidateCredentialsTest.java
@@ -39,7 +39,7 @@ import net.shibboleth.utilities.java.support.velocity.VelocityEngine;
import org.ldaptive.DefaultConnectionFactory;
import org.ldaptive.auth.AuthenticationResultCode;
import org.ldaptive.auth.Authenticator;
-import org.ldaptive.auth.BindAuthenticationHandler;
+import org.ldaptive.auth.SimpleBindAuthenticationHandler;
import org.ldaptive.jaas.LdapPrincipal;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -66,7 +66,7 @@ public class ValidateCredentialsTest extends BaseAuthenticationContextTest {
private TemplateSearchDnResolver dnResolver;
- private BindAuthenticationHandler authHandler;
+ private SimpleBindAuthenticationHandler authHandler;
private Authenticator authenticator;
@@ -94,7 +94,7 @@ public class ValidateCredentialsTest extends BaseAuthenticationContextTest {
VelocityEngine.newVelocityEngine(), "(uid=$usernamePasswordContext.username)");
dnResolver.setBaseDn("ou=people,dc=shibboleth,dc=net");
- authHandler = new BindAuthenticationHandler(new DefaultConnectionFactory("ldap://localhost:10389"));
+ authHandler = new SimpleBindAuthenticationHandler(new DefaultConnectionFactory("ldap://localhost:10389"));
authenticator = new Authenticator(dnResolver, authHandler);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list