Check RDN attribute for DN membership
Closes https://github.com/keycloak/keycloak/issues/20718
This commit is contained in:
parent
3cbd4eb10a
commit
7336ff07ac
2 changed files with 13 additions and 9 deletions
|
@ -50,18 +50,20 @@ public enum MembershipType {
|
||||||
@Override
|
@Override
|
||||||
public Set<LDAPDn> getLDAPSubgroups(CommonLDAPGroupMapper groupMapper, LDAPObject ldapGroup) {
|
public Set<LDAPDn> getLDAPSubgroups(CommonLDAPGroupMapper groupMapper, LDAPObject ldapGroup) {
|
||||||
CommonLDAPGroupMapperConfig config = groupMapper.getConfig();
|
CommonLDAPGroupMapperConfig config = groupMapper.getConfig();
|
||||||
return getLDAPMembersWithParent(groupMapper.getLdapProvider(), ldapGroup, config.getMembershipLdapAttribute(), LDAPDn.fromString(config.getLDAPGroupsDn()));
|
return getLDAPMembersWithParent(groupMapper.getLdapProvider(), ldapGroup, config.getMembershipLdapAttribute(),
|
||||||
|
LDAPDn.fromString(config.getLDAPGroupsDn()), config.getLDAPGroupNameLdapAttribute());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get just those members of specified group, which are descendants of "requiredParentDn"
|
// Get just those members of specified group, which are descendants of "requiredParentDn"
|
||||||
protected Set<LDAPDn> getLDAPMembersWithParent(LDAPStorageProvider ldapProvider, LDAPObject ldapGroup, String membershipLdapAttribute, LDAPDn requiredParentDn) {
|
protected Set<LDAPDn> getLDAPMembersWithParent(LDAPStorageProvider ldapProvider, LDAPObject ldapGroup,
|
||||||
|
String membershipLdapAttribute, LDAPDn requiredParentDn, String rdnAttr) {
|
||||||
Set<String> allMemberships = LDAPUtils.getExistingMemberships(ldapProvider, membershipLdapAttribute, ldapGroup);
|
Set<String> allMemberships = LDAPUtils.getExistingMemberships(ldapProvider, membershipLdapAttribute, ldapGroup);
|
||||||
|
|
||||||
// Filter and keep just descendants of requiredParentDn
|
// Filter and keep just descendants of requiredParentDn
|
||||||
Set<LDAPDn> result = new HashSet<>();
|
Set<LDAPDn> result = new HashSet<>();
|
||||||
for (String membership : allMemberships) {
|
for (String membership : allMemberships) {
|
||||||
LDAPDn childDn = LDAPDn.fromString(membership);
|
LDAPDn childDn = LDAPDn.fromString(membership);
|
||||||
if (childDn.isDescendantOf(requiredParentDn)) {
|
if (childDn.getFirstRdn().getAttrValue(rdnAttr) != null && childDn.isDescendantOf(requiredParentDn)) {
|
||||||
result.add(childDn);
|
result.add(childDn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,8 +75,9 @@ public enum MembershipType {
|
||||||
LDAPStorageProvider ldapProvider = groupMapper.getLdapProvider();
|
LDAPStorageProvider ldapProvider = groupMapper.getLdapProvider();
|
||||||
CommonLDAPGroupMapperConfig config = groupMapper.getConfig();
|
CommonLDAPGroupMapperConfig config = groupMapper.getConfig();
|
||||||
|
|
||||||
|
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
|
||||||
LDAPDn usersDn = LDAPDn.fromString(ldapProvider.getLdapIdentityStore().getConfig().getUsersDn());
|
LDAPDn usersDn = LDAPDn.fromString(ldapProvider.getLdapIdentityStore().getConfig().getUsersDn());
|
||||||
Set<LDAPDn> userDns = getLDAPMembersWithParent(ldapProvider, ldapGroup, config.getMembershipLdapAttribute(), usersDn);
|
Set<LDAPDn> userDns = getLDAPMembersWithParent(ldapProvider, ldapGroup, config.getMembershipLdapAttribute(), usersDn, ldapConfig.getRdnLdapAttribute());
|
||||||
|
|
||||||
if (userDns == null) {
|
if (userDns == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -90,14 +93,9 @@ public enum MembershipType {
|
||||||
|
|
||||||
// If usernameAttrName is same like DN, we can just retrieve usernames from DNs
|
// If usernameAttrName is same like DN, we can just retrieve usernames from DNs
|
||||||
List<String> usernames = new LinkedList<>();
|
List<String> usernames = new LinkedList<>();
|
||||||
LDAPConfig ldapConfig = ldapProvider.getLdapIdentityStore().getConfig();
|
|
||||||
if (ldapConfig.getUsernameLdapAttribute().equals(ldapConfig.getRdnLdapAttribute())) {
|
if (ldapConfig.getUsernameLdapAttribute().equals(ldapConfig.getRdnLdapAttribute())) {
|
||||||
for (LDAPDn userDn : dns) {
|
for (LDAPDn userDn : dns) {
|
||||||
String username = userDn.getFirstRdn().getAttrValue(ldapConfig.getRdnLdapAttribute());
|
String username = userDn.getFirstRdn().getAttrValue(ldapConfig.getRdnLdapAttribute());
|
||||||
if (username == null) {
|
|
||||||
throw new ModelException("User returned from LDAP has null username! Check configuration of your LDAP mappings. Mapped username LDAP attribute: " +
|
|
||||||
ldapConfig.getRdnLdapAttribute() + ", user DN: " + userDn + ", attributes from LDAP: " + userDn.getFirstRdn().getAllKeys());
|
|
||||||
}
|
|
||||||
usernames.add(username);
|
usernames.add(username);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
import org.keycloak.representations.idm.SynchronizationResultRepresentation;
|
import org.keycloak.representations.idm.SynchronizationResultRepresentation;
|
||||||
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
import org.keycloak.storage.ldap.LDAPStorageProvider;
|
||||||
import org.keycloak.storage.ldap.LDAPUtils;
|
import org.keycloak.storage.ldap.LDAPUtils;
|
||||||
|
import org.keycloak.storage.ldap.idm.model.LDAPDn;
|
||||||
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
import org.keycloak.storage.ldap.idm.model.LDAPObject;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
|
||||||
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
|
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
|
||||||
|
@ -94,6 +95,11 @@ public class LDAPGroupMapperSyncTest extends AbstractLDAPTest {
|
||||||
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11);
|
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11);
|
||||||
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12);
|
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12);
|
||||||
|
|
||||||
|
LDAPObject nonExistentChild = new LDAPObject();
|
||||||
|
LDAPDn nonExistentChildDn = group1.getDn().getParentDn();
|
||||||
|
nonExistentChildDn.addFirst(LDAPConstants.UID, "non-existent-child");
|
||||||
|
nonExistentChild.setDn(nonExistentChildDn);
|
||||||
|
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, nonExistentChild);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue