diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js index 392e726fd7..251a62f712 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js @@ -925,7 +925,13 @@ module.controller('RealmLDAPSettingsCtrl', function($scope, $location, Notificat console.log("LDAP vendor changed"); $scope.lastVendor = $scope.realm.ldapServer.vendor; - $scope.realm.ldapServer.usernameLDAPAttribute = ($scope.lastVendor === "ad") ? "cn" : "uid"; + if ($scope.lastVendor === "ad") { + $scope.realm.ldapServer.usernameLDAPAttribute = "cn"; + $scope.realm.ldapServer.userObjectClasses = "person, organizationalPerson"; + } else { + $scope.realm.ldapServer.usernameLDAPAttribute = "uid"; + $scope.realm.ldapServer.userObjectClasses = "inetOrgPerson, organizationalPerson"; + } } }, true); diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-ldap.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-ldap.html index 6cbf2692ea..edf8eced93 100644 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-ldap.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-ldap.html @@ -35,6 +35,12 @@ +
+ +
+ +
+
diff --git a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java index 49f61ab61d..3b6ac1c092 100644 --- a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java +++ b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java @@ -11,6 +11,7 @@ public class LDAPConstants { public static final String VENDOR_OTHER = "other"; public static final String USERNAME_LDAP_ATTRIBUTE = "usernameLDAPAttribute"; + public static final String USER_OBJECT_CLASSES = "userObjectClasses"; public static final String CONNECTION_URL = "connectionUrl"; public static final String BASE_DN = "baseDn"; diff --git a/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/realm/PartitionManagerRegistry.java b/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/realm/PartitionManagerRegistry.java index 84a62c225a..a084eb4e12 100644 --- a/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/realm/PartitionManagerRegistry.java +++ b/picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/realm/PartitionManagerRegistry.java @@ -91,6 +91,8 @@ public class PartitionManagerRegistry { String ldapLastNameMapping = getNameOfLDAPAttribute("keycloak.ldap.idm.lastName", SN, SN, activeDirectory); String ldapEmailMapping = getNameOfLDAPAttribute("keycloak.ldap.idm.email", EMAIL, EMAIL, activeDirectory); + String[] userObjectClasses = getUserObjectClasses(ldapConfig); + logger.infof("LDAP Attributes mapping: loginName: %s, firstName: %s, lastName: %s, email: %s", ldapLoginNameMapping, ldapFirstNameMapping, ldapLastNameMapping, ldapEmailMapping); // Use same mapping for User and Agent for now @@ -108,7 +110,7 @@ public class PartitionManagerRegistry { .supportAllFeatures() .mapping(User.class) .baseDN(ldapConfig.get(LDAPConstants.USER_DN_SUFFIX)) - .objectClasses("inetOrgPerson", "organizationalPerson") + .objectClasses(userObjectClasses) .attribute("loginName", ldapLoginNameMapping, true) .attribute("firstName", ldapFirstNameMapping) .attribute("lastName", ldapLastNameMapping) @@ -138,6 +140,21 @@ public class PartitionManagerRegistry { return activeDirectory ? defaultAttrNameInActiveDirectory : defaultAttrName; } + // Parse array of strings like [ "inetOrgPerson", "organizationalPerson" ] from the string like: "inetOrgPerson, organizationalPerson" + private String[] getUserObjectClasses(Map ldapConfig) { + String objClassesCfg = ldapConfig.get(LDAPConstants.USER_OBJECT_CLASSES); + String objClassesStr = (objClassesCfg != null && objClassesCfg.length() > 0) ? objClassesCfg.trim() : "inetOrgPerson, organizationalPerson"; + + String[] objectClasses = objClassesStr.split(","); + + // Trim them + String[] userObjectClasses = new String[objectClasses.length]; + for (int i=0 ; i config, PartitionManager manager) {