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.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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 {
|
||||
if (customFilter != null) {
|
||||
|
||||
|
|
|
@ -343,28 +343,7 @@ public class GroupLDAPFederationMapper extends AbstractLDAPFederationMapper impl
|
|||
// Send LDAP query to retrieve all groups
|
||||
protected List<LDAPObject> getAllLDAPGroups() {
|
||||
LDAPQuery ldapGroupQuery = createGroupQuery();
|
||||
|
||||
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();
|
||||
}
|
||||
return LDAPUtils.loadAllLDAPObjects(ldapGroupQuery, ldapProvider);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -88,9 +88,9 @@ public class GroupLDAPFederationMapperFactory extends AbstractLDAPFederationMapp
|
|||
for (MembershipType membershipType : MembershipType.values()) {
|
||||
membershipTypes.add(membershipType.toString());
|
||||
}
|
||||
ProviderConfigProperty membershipType = createConfigProperty(RoleMapperConfig.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' . " +
|
||||
"UID means that LDAP role has it's members declared in form of pure user uids. For example 'memberUid: john' .",
|
||||
ProviderConfigProperty membershipType = createConfigProperty(GroupMapperConfig.MEMBERSHIP_ATTRIBUTE_TYPE, "Membership Attribute Type",
|
||||
"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 group has it's members declared in form of pure user uids. For example 'memberUid: john' .",
|
||||
ProviderConfigProperty.LIST_TYPE, membershipTypes);
|
||||
configProperties.add(membershipType);
|
||||
|
||||
|
@ -165,6 +165,7 @@ public class GroupLDAPFederationMapperFactory extends AbstractLDAPFederationMapp
|
|||
|
||||
defaultValues.put(GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "true");
|
||||
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();
|
||||
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());
|
||||
|
||||
// Send LDAP query
|
||||
LDAPQuery ldapQuery = createRoleQuery();
|
||||
List<LDAPObject> ldapRoles = ldapQuery.getResultList();
|
||||
// Send LDAP query to load all roles
|
||||
LDAPQuery ldapRoleQuery = createRoleQuery();
|
||||
List<LDAPObject> ldapRoles = LDAPUtils.loadAllLDAPObjects(ldapRoleQuery, ldapProvider);
|
||||
|
||||
RoleContainerModel roleContainer = getTargetRoleContainer();
|
||||
String rolesRdnAttr = config.getRoleNameLdapAttribute();
|
||||
|
|
Loading…
Reference in a new issue