Skip to content

Commit

Permalink
Fix test LDAP connection with multiple ldap connection urls
Browse files Browse the repository at this point in the history
Previously, the given connection string was check with URI.create(..) which
failed when multiple space separated LDAP URLs were given.

Closes keycloak#31267

Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
  • Loading branch information
thomasdarimont authored and stianst committed Jul 25, 2024
1 parent 865d33f commit 4ebf483
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.keycloak.component.ComponentModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.ModelValidationException;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.TestLdapConnectionRepresentation;
Expand Down Expand Up @@ -73,7 +74,7 @@ public static LDAPConfig buildLDAPConfig(TestLdapConnectionRepresentation config
ComponentModel component = realm.getComponent(config.getComponentId());
if (component != null) {
LDAPConfig ldapConfig = new LDAPConfig(component.getConfig());
if (Objects.equals(URI.create(config.getConnectionUrl()), URI.create(ldapConfig.getConnectionUrl()))
if (checkLdapConnectionUrl(config, ldapConfig)
&& config.getBindDn() != null && config.getBindDn().equalsIgnoreCase(ldapConfig.getBindDN())) {
bindCredential = ldapConfig.getBindCredential();
}
Expand All @@ -94,6 +95,28 @@ public static LDAPConfig buildLDAPConfig(TestLdapConnectionRepresentation config
return new LDAPConfig(configMap);
}

/**
* Ensure provided connection URI matches parsed LDAP connection URI.
*
* See: https://docs.oracle.com/javase/jndi/tutorial/ldap/misc/url.html
* @param config
* @param ldapConfig
* @return
*/
private static boolean checkLdapConnectionUrl(TestLdapConnectionRepresentation config, LDAPConfig ldapConfig) {
// There could be multiple connection URIs separated via spaces.
String[] configConnectionUrls = config.getConnectionUrl().trim().split(" ");
String[] ldapConfigConnectionUrls = ldapConfig.getConnectionUrl().trim().split(" ");
if (configConnectionUrls.length != ldapConfigConnectionUrls.length) {
return false;
}
boolean urlsMatch = true;
for (int i = 0; i < configConnectionUrls.length && urlsMatch; i++) {
urlsMatch = Objects.equals(URI.create(configConnectionUrls[i]), URI.create(ldapConfigConnectionUrls[i]));
}
return urlsMatch;
}

public static Set<LDAPCapabilityRepresentation> queryServerCapabilities(TestLdapConnectionRepresentation config, KeycloakSession session,
RealmModel realm) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public void testLdapConnectionsSsl() {

@Test
public void testLdapConnectionMoreServers() {

// Both servers work
Response response = realm.testLDAPConnection(new TestLdapConnectionRepresentation(LDAPServerCapabilitiesManager.TEST_AUTHENTICATION, "ldap://localhost:10389 ldaps://localhost:10636", "uid=admin,ou=system", "secret", "true", null));
assertStatus(response, 204);
Expand All @@ -155,11 +156,23 @@ public void testLdapConnectionMoreServers() {
response = realm.testLDAPConnection(new TestLdapConnectionRepresentation(LDAPServerCapabilitiesManager.TEST_AUTHENTICATION, "ldap://localhostt:10389 ldaps://localhostt:10636", "uid=admin,ou=system", "secret", "true", null));
assertStatus(response, 400);

// create LDAP component model using ldap
Map<String, String> cfg = ldapRule.getConfig();
cfg.put(LDAPConstants.CONNECTION_URL, "ldap://invalid:10389 ldap://localhost:10389");
cfg.put(LDAPConstants.CONNECTION_TIMEOUT, "1000");
String ldapModelId = testingClient.testing().ldap(REALM_NAME).createLDAPProvider(cfg, false);

// Only 2nd server works with stored LDAP federation provider
response = realm.testLDAPConnection(new TestLdapConnectionRepresentation(LDAPServerCapabilitiesManager.TEST_AUTHENTICATION,
cfg.get(LDAPConstants.CONNECTION_URL), cfg.get(LDAPConstants.BIND_DN), ComponentRepresentation.SECRET_VALUE,
cfg.get(LDAPConstants.USE_TRUSTSTORE_SPI), cfg.get(LDAPConstants.CONNECTION_TIMEOUT),cfg.get(LDAPConstants.START_TLS),
cfg.get(LDAPConstants.AUTH_TYPE), ldapModelId));
assertStatus(response, 204);
}

@Test
public void testLdapConnectionComponentAlreadyCreated() {
// create ldap componnet model using ldaps
// create ldap component model using ldaps
Map<String, String> cfg = ldapRule.getConfig();
cfg.put(LDAPConstants.CONNECTION_URL, "ldaps://localhost:10636");
cfg.put(LDAPConstants.START_TLS, "false");
Expand Down

0 comments on commit 4ebf483

Please sign in to comment.