Add migration for the useTruststoreSpi config property in LDAP user storage provider
- legacy `ldapsOnly` value now migrated to `always`. Closes #25912 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
This commit is contained in:
parent
eac43822c3
commit
2161e72872
6 changed files with 81 additions and 6 deletions
|
@ -65,8 +65,7 @@ public class LDAPConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUseTruststoreSpi() {
|
public String getUseTruststoreSpi() {
|
||||||
String value = config.getFirst(LDAPConstants.USE_TRUSTSTORE_SPI);
|
return config.getFirst(LDAPConstants.USE_TRUSTSTORE_SPI);
|
||||||
return LDAPConstants.USE_TRUSTSTORE_LDAPS_ONLY.equals(value) ? LDAPConstants.USE_TRUSTSTORE_ALWAYS : value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsersDn() {
|
public String getUsersDn() {
|
||||||
|
|
|
@ -23,10 +23,12 @@ import org.jboss.logging.Logger;
|
||||||
import org.keycloak.migration.ModelVersion;
|
import org.keycloak.migration.ModelVersion;
|
||||||
import org.keycloak.models.KeycloakContext;
|
import org.keycloak.models.KeycloakContext;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.userprofile.config.UPConfig;
|
import org.keycloak.representations.userprofile.config.UPConfig;
|
||||||
import org.keycloak.representations.userprofile.config.UPConfig.UnmanagedAttributePolicy;
|
import org.keycloak.representations.userprofile.config.UPConfig.UnmanagedAttributePolicy;
|
||||||
|
import org.keycloak.storage.UserStorageProvider;
|
||||||
import org.keycloak.userprofile.UserProfileProvider;
|
import org.keycloak.userprofile.UserProfileProvider;
|
||||||
|
|
||||||
public class MigrateTo24_0_0 implements Migration {
|
public class MigrateTo24_0_0 implements Migration {
|
||||||
|
@ -55,6 +57,7 @@ public class MigrateTo24_0_0 implements Migration {
|
||||||
try {
|
try {
|
||||||
context.setRealm(realm);
|
context.setRealm(realm);
|
||||||
updateUserProfileSettings(session);
|
updateUserProfileSettings(session);
|
||||||
|
updateLdapProviderConfig(session);
|
||||||
} finally {
|
} finally {
|
||||||
context.setRealm(null);
|
context.setRealm(null);
|
||||||
}
|
}
|
||||||
|
@ -82,4 +85,15 @@ public class MigrateTo24_0_0 implements Migration {
|
||||||
|
|
||||||
LOG.debugf("Enabled the declarative user profile to realm %s with support for unmanaged attributes", realm.getName());
|
LOG.debugf("Enabled the declarative user profile to realm %s with support for unmanaged attributes", realm.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateLdapProviderConfig(final KeycloakSession session) {
|
||||||
|
RealmModel realm = session.getContext().getRealm();
|
||||||
|
// ensure `ldapsOnly` value for `useTruststoreSpi` in LDAP providers is migrated to `always`.
|
||||||
|
realm.getComponentsStream(realm.getId(), UserStorageProvider.class.getName())
|
||||||
|
.filter(c -> LDAPConstants.USE_TRUSTSTORE_LDAPS_ONLY.equals(c.getConfig().getFirst(LDAPConstants.USE_TRUSTSTORE_SPI)))
|
||||||
|
.forEach(c -> {
|
||||||
|
c.getConfig().putSingle(LDAPConstants.USE_TRUSTSTORE_SPI, LDAPConstants.USE_TRUSTSTORE_ALWAYS);
|
||||||
|
realm.updateComponent(c);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.keycloak.authentication.authenticators.browser.OTPFormAuthenticatorFa
|
||||||
import org.keycloak.authentication.authenticators.conditional.ConditionalUserConfiguredAuthenticatorFactory;
|
import org.keycloak.authentication.authenticators.conditional.ConditionalUserConfiguredAuthenticatorFactory;
|
||||||
import org.keycloak.broker.provider.util.SimpleHttp;
|
import org.keycloak.broker.provider.util.SimpleHttp;
|
||||||
import org.keycloak.common.constants.KerberosConstants;
|
import org.keycloak.common.constants.KerberosConstants;
|
||||||
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
import org.keycloak.component.PrioritizedComponentModel;
|
import org.keycloak.component.PrioritizedComponentModel;
|
||||||
import org.keycloak.keys.KeyProvider;
|
import org.keycloak.keys.KeyProvider;
|
||||||
import org.keycloak.models.AccountRoles;
|
import org.keycloak.models.AccountRoles;
|
||||||
|
@ -398,13 +399,16 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
testRegistrationProfileFormActionRemoved(migrationRealm2);
|
testRegistrationProfileFormActionRemoved(migrationRealm2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigrationTo24_0_0(boolean testUserProfileMigration) {
|
protected void testMigrationTo24_0_0(boolean testUserProfileMigration, boolean testLdapUseTruststoreSpiMigration) {
|
||||||
if (testUserProfileMigration) {
|
if (testUserProfileMigration) {
|
||||||
testUserProfileEnabledByDefault(migrationRealm);
|
testUserProfileEnabledByDefault(migrationRealm);
|
||||||
testUnmanagedAttributePolicySet(migrationRealm, UnmanagedAttributePolicy.ENABLED);
|
testUnmanagedAttributePolicySet(migrationRealm, UnmanagedAttributePolicy.ENABLED);
|
||||||
testUserProfileEnabledByDefault(migrationRealm2);
|
testUserProfileEnabledByDefault(migrationRealm2);
|
||||||
testUnmanagedAttributePolicySet(migrationRealm2, null);
|
testUnmanagedAttributePolicySet(migrationRealm2, null);
|
||||||
}
|
}
|
||||||
|
if (testLdapUseTruststoreSpiMigration) {
|
||||||
|
testLdapUseTruststoreSpiMigration(migrationRealm2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testDeleteAccount(RealmResource realm) {
|
protected void testDeleteAccount(RealmResource realm) {
|
||||||
|
@ -1092,7 +1096,11 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigrationTo24_x(boolean testUserProfileMigration) {
|
protected void testMigrationTo24_x(boolean testUserProfileMigration) {
|
||||||
testMigrationTo24_0_0(testUserProfileMigration);
|
testMigrationTo24_0_0(testUserProfileMigration, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testMigrationTo24_x(boolean testUserProfileMigration, boolean testLdapUseTruststoreSpiMigration) {
|
||||||
|
testMigrationTo24_0_0(testUserProfileMigration, testLdapUseTruststoreSpiMigration);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testMigrationTo7_x(boolean supportedAuthzServices) {
|
protected void testMigrationTo7_x(boolean supportedAuthzServices) {
|
||||||
|
@ -1211,4 +1219,22 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
UPConfig upConfig = realm.users().userProfile().getConfiguration();
|
UPConfig upConfig = realm.users().userProfile().getConfiguration();
|
||||||
assertEquals(policy, upConfig.getUnmanagedAttributePolicy());
|
assertEquals(policy, upConfig.getUnmanagedAttributePolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the {@code useTruststoreSpi} flag in the LDAP federation provider present in realm {@code Migration2}
|
||||||
|
* was properly migrated from the old value {@code ldapsOnly} to {@code always}.
|
||||||
|
* </p>
|
||||||
|
* This provider was added to the file migration-realm-19.0.3.json as a disabled provider, so it doesn't get involved
|
||||||
|
* in actual user searches and is there just to test the migration of the {@code useTruststoreSpi} config attribute.
|
||||||
|
*
|
||||||
|
* @param realm the migrated realm resource.
|
||||||
|
*/
|
||||||
|
private void testLdapUseTruststoreSpiMigration(final RealmResource realm) {
|
||||||
|
RealmRepresentation rep = realm.toRepresentation();
|
||||||
|
List<ComponentRepresentation> componentsRep = realm.components().query(rep.getId(), UserStorageProvider.class.getName());
|
||||||
|
assertThat(componentsRep.size(), equalTo(1));
|
||||||
|
MultivaluedHashMap<String, String> config = componentsRep.get(0).getConfig();
|
||||||
|
assertNotNull(config);
|
||||||
|
assertThat(config.getFirst(LDAPConstants.USE_TRUSTSTORE_SPI), equalTo(LDAPConstants.USE_TRUSTSTORE_ALWAYS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class JsonFileImport1903MigrationTest extends AbstractJsonFileImportMigra
|
||||||
testMigrationTo21_x();
|
testMigrationTo21_x();
|
||||||
testMigrationTo22_x();
|
testMigrationTo22_x();
|
||||||
testMigrationTo23_x(true);
|
testMigrationTo23_x(true);
|
||||||
testMigrationTo24_x(true);
|
testMigrationTo24_x(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -69,6 +69,6 @@ public class MigrationTest extends AbstractMigrationTest {
|
||||||
testMigrationTo21_x();
|
testMigrationTo21_x();
|
||||||
testMigrationTo22_x();
|
testMigrationTo22_x();
|
||||||
testMigrationTo23_x(true);
|
testMigrationTo23_x(true);
|
||||||
testMigrationTo24_x(true);
|
testMigrationTo24_x(true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2912,6 +2912,42 @@
|
||||||
"identityProviders" : [ ],
|
"identityProviders" : [ ],
|
||||||
"identityProviderMappers" : [ ],
|
"identityProviderMappers" : [ ],
|
||||||
"components" : {
|
"components" : {
|
||||||
|
"org.keycloak.storage.UserStorageProvider": [
|
||||||
|
{
|
||||||
|
"id": "307bba27-f8da-4c4d-a1b9-3c1bf49f824e",
|
||||||
|
"name": "ldap",
|
||||||
|
"providerId": "ldap",
|
||||||
|
"subComponents": {},
|
||||||
|
"config": {
|
||||||
|
"pagination": [ "false" ],
|
||||||
|
"fullSyncPeriod": [ "-1" ],
|
||||||
|
"startTls": [ "false" ],
|
||||||
|
"usersDn": [ "ou=People,dc=keycloak,dc=org" ],
|
||||||
|
"connectionPooling": [ "false" ],
|
||||||
|
"cachePolicy": [ "DEFAULT" ],
|
||||||
|
"useKerberosForPasswordAuthentication": [ "false" ],
|
||||||
|
"importEnabled": [ "true" ],
|
||||||
|
"enabled": [ "false" ],
|
||||||
|
"bindCredential": [ "anything" ],
|
||||||
|
"changedSyncPeriod": [ "-1" ],
|
||||||
|
"bindDn": [ "uid=admin,ou=system" ],
|
||||||
|
"usernameLDAPAttribute": [ "uid" ],
|
||||||
|
"vendor": [ "other" ],
|
||||||
|
"uuidLDAPAttribute": [ "entryUUID" ],
|
||||||
|
"connectionUrl": [ "ldap://localhost:10389" ],
|
||||||
|
"allowKerberosAuthentication": [ "false" ],
|
||||||
|
"syncRegistrations": [ "true" ],
|
||||||
|
"authType": [ "simple" ],
|
||||||
|
"useTruststoreSpi": [ "ldapsOnly" ],
|
||||||
|
"usePasswordModifyExtendedOp": [ "false" ],
|
||||||
|
"trustEmail": [ "false" ],
|
||||||
|
"userObjectClasses": [ "inetOrgPerson, organizationalPerson" ],
|
||||||
|
"rdnLDAPAttribute": [ "uid" ],
|
||||||
|
"editMode": [ "WRITABLE" ],
|
||||||
|
"validatePasswordPolicy": [ "false" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"org.keycloak.userprofile.UserProfileProvider": [
|
"org.keycloak.userprofile.UserProfileProvider": [
|
||||||
{
|
{
|
||||||
"id": "88cef18c-bcd8-40d2-9e7d-d257298317f2",
|
"id": "88cef18c-bcd8-40d2-9e7d-d257298317f2",
|
||||||
|
|
Loading…
Reference in a new issue