KEYCLOAK-2659 Allow sync all roles even if there are more than 1000
This commit is contained in:
parent
2d188068c4
commit
e24ce91e81
4 changed files with 48 additions and 28 deletions
|
@ -19,6 +19,7 @@ package org.keycloak.federation.ldap;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -229,6 +230,45 @@ public class LDAPUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all LDAP objects corresponding to given query. We will load them paginated, so we allow to bypass the limitation of 1000
|
||||||
|
* maximum loaded objects in single query in MSAD
|
||||||
|
*
|
||||||
|
* @param ldapQuery
|
||||||
|
* @param ldapProvider
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<LDAPObject> loadAllLDAPObjects(LDAPQuery ldapQuery, LDAPFederationProvider ldapProvider) {
|
||||||
|
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
|
||||||
|
boolean pagination = ldapConfig.isPagination();
|
||||||
|
if (pagination) {
|
||||||
|
// For now reuse globally configured batch size in LDAP provider page
|
||||||
|
int pageSize = ldapConfig.getBatchSizeForSync();
|
||||||
|
|
||||||
|
List<LDAPObject> result = new LinkedList<>();
|
||||||
|
boolean nextPage = true;
|
||||||
|
|
||||||
|
while (nextPage) {
|
||||||
|
ldapQuery.setLimit(pageSize);
|
||||||
|
final List<LDAPObject> currentPageGroups = ldapQuery.getResultList();
|
||||||
|
result.addAll(currentPageGroups);
|
||||||
|
nextPage = ldapQuery.getPaginationContext() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
// LDAP pagination not available. Do everything in single transaction
|
||||||
|
return ldapQuery.getResultList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate configured customFilter matches the requested format
|
||||||
|
*
|
||||||
|
* @param customFilter
|
||||||
|
* @throws FederationConfigValidationException
|
||||||
|
*/
|
||||||
public static void validateCustomLdapFilter(String customFilter) throws FederationConfigValidationException {
|
public static void validateCustomLdapFilter(String customFilter) throws FederationConfigValidationException {
|
||||||
if (customFilter != null) {
|
if (customFilter != null) {
|
||||||
|
|
||||||
|
|
|
@ -343,28 +343,7 @@ public class GroupLDAPFederationMapper extends AbstractLDAPFederationMapper impl
|
||||||
// Send LDAP query to retrieve all groups
|
// Send LDAP query to retrieve all groups
|
||||||
protected List<LDAPObject> getAllLDAPGroups() {
|
protected List<LDAPObject> getAllLDAPGroups() {
|
||||||
LDAPQuery ldapGroupQuery = createGroupQuery();
|
LDAPQuery ldapGroupQuery = createGroupQuery();
|
||||||
|
return LDAPUtils.loadAllLDAPObjects(ldapGroupQuery, ldapProvider);
|
||||||
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
|
|
||||||
boolean pagination = ldapConfig.isPagination();
|
|
||||||
if (pagination) {
|
|
||||||
// For now reuse globally configured batch size in LDAP provider page
|
|
||||||
int pageSize = ldapConfig.getBatchSizeForSync();
|
|
||||||
|
|
||||||
List<LDAPObject> result = new LinkedList<>();
|
|
||||||
boolean nextPage = true;
|
|
||||||
|
|
||||||
while (nextPage) {
|
|
||||||
ldapGroupQuery.setLimit(pageSize);
|
|
||||||
final List<LDAPObject> currentPageGroups = ldapGroupQuery.getResultList();
|
|
||||||
result.addAll(currentPageGroups);
|
|
||||||
nextPage = ldapGroupQuery.getPaginationContext() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
// LDAP pagination not available. Do everything in single transaction
|
|
||||||
return ldapGroupQuery.getResultList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,9 @@ public class GroupLDAPFederationMapperFactory extends AbstractLDAPFederationMapp
|
||||||
for (MembershipType membershipType : MembershipType.values()) {
|
for (MembershipType membershipType : MembershipType.values()) {
|
||||||
membershipTypes.add(membershipType.toString());
|
membershipTypes.add(membershipType.toString());
|
||||||
}
|
}
|
||||||
ProviderConfigProperty membershipType = createConfigProperty(RoleMapperConfig.MEMBERSHIP_ATTRIBUTE_TYPE, "Membership Attribute Type",
|
ProviderConfigProperty membershipType = createConfigProperty(GroupMapperConfig.MEMBERSHIP_ATTRIBUTE_TYPE, "Membership Attribute Type",
|
||||||
"DN means that LDAP role has it's members declared in form of their full DN. For example 'member: uid=john,ou=users,dc=example,dc=com' . " +
|
"DN means that LDAP group has it's members declared in form of their full DN. For example 'member: uid=john,ou=users,dc=example,dc=com' . " +
|
||||||
"UID means that LDAP role has it's members declared in form of pure user uids. For example 'memberUid: john' .",
|
"UID means that LDAP group has it's members declared in form of pure user uids. For example 'memberUid: john' .",
|
||||||
ProviderConfigProperty.LIST_TYPE, membershipTypes);
|
ProviderConfigProperty.LIST_TYPE, membershipTypes);
|
||||||
configProperties.add(membershipType);
|
configProperties.add(membershipType);
|
||||||
|
|
||||||
|
@ -165,6 +165,7 @@ public class GroupLDAPFederationMapperFactory extends AbstractLDAPFederationMapp
|
||||||
|
|
||||||
defaultValues.put(GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
|
defaultValues.put(GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
|
||||||
defaultValues.put(GroupMapperConfig.MEMBERSHIP_LDAP_ATTRIBUTE, LDAPConstants.MEMBER);
|
defaultValues.put(GroupMapperConfig.MEMBERSHIP_LDAP_ATTRIBUTE, LDAPConstants.MEMBER);
|
||||||
|
defaultValues.put(GroupMapperConfig.MEMBERSHIP_ATTRIBUTE_TYPE, MembershipType.DN.toString());
|
||||||
|
|
||||||
String mode = config.getEditMode() == UserFederationProvider.EditMode.WRITABLE ? LDAPGroupMapperMode.LDAP_ONLY.toString() : LDAPGroupMapperMode.READ_ONLY.toString();
|
String mode = config.getEditMode() == UserFederationProvider.EditMode.WRITABLE ? LDAPGroupMapperMode.LDAP_ONLY.toString() : LDAPGroupMapperMode.READ_ONLY.toString();
|
||||||
defaultValues.put(GroupMapperConfig.MODE, mode);
|
defaultValues.put(GroupMapperConfig.MODE, mode);
|
||||||
|
|
|
@ -122,9 +122,9 @@ public class RoleLDAPFederationMapper extends AbstractLDAPFederationMapper imple
|
||||||
|
|
||||||
logger.debugf("Syncing roles from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getDisplayName());
|
logger.debugf("Syncing roles from LDAP into Keycloak DB. Mapper is [%s], LDAP provider is [%s]", mapperModel.getName(), ldapProvider.getModel().getDisplayName());
|
||||||
|
|
||||||
// Send LDAP query
|
// Send LDAP query to load all roles
|
||||||
LDAPQuery ldapQuery = createRoleQuery();
|
LDAPQuery ldapRoleQuery = createRoleQuery();
|
||||||
List<LDAPObject> ldapRoles = ldapQuery.getResultList();
|
List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapRoleQuery, ldapProvider);
|
||||||
|
|
||||||
RoleContainerModel roleContainer = getTargetRoleContainer();
|
RoleContainerModel roleContainer = getTargetRoleContainer();
|
||||||
String rolesRdnAttr = config.getRoleNameLdapAttribute();
|
String rolesRdnAttr = config.getRoleNameLdapAttribute();
|
||||||
|
|
Loading…
Reference in a new issue