keycloak/keycloak

User LDAP Filter is applied to Group lookups in `getFilterById()`, causing Group Members tab to return empty results

Open

#47,891 建立於 2026年4月9日

在 GitHub 查看
 (3 留言) (1 反應) (0 負責人)Java (8,346 fork)batch import
area/ldaphelp wantedkind/bugpriority/normalstatus/auto-bumpstatus/auto-expireteam/core-iam

倉庫指標

Star
 (34,398 star)
PR 合併指標
 (平均合併 6天 19小時) (30 天內合併 384 個 PR)

描述

Before reporting an issue

  • I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

Area

ldap

Describe the bug

When a User LDAP filter (e.g. (LoginDisabled=false)) is configured in the LDAP federation settings, clicking the Members tab of a Group in the Admin console returns no results. The group cannot be found because the User LDAP filter is incorrectly appended to the LDAP group lookup query.

Version

26.6.0

Regression

  • The issue is a regression

Expected behavior

The Members tab should list all LDAP users that are members of the group. The User LDAP filter should only be applied to user searches, not to group lookups.

Actual behavior

The Members tab shows no results. The LDAP group lookup fails silently because the User LDAP filter is appended to the group search query, and the group object does not have the filtered attribute.

How to Reproduce?

  1. Configure an LDAP User Federation provider
  2. Set a User LDAP filter in the federation settings (e.g. (LoginDisabled=false))
  3. Configure a Group LDAP mapper with membership type DN
  4. Go to the Admin console -> Groups -> select a group -> click the Members tab
  5. Observe that no members are shown

Anything else?

Root Cause

LDAPOperationManager.getFilterById() unconditionally appends config.getCustomUserSearchFilter() to every lookupById call, regardless of whether the target entity is a user, a group, or a role.

https://github.com/keycloak/keycloak/blob/main/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java#L394-L396

public Condition getFilterById(String id) {
    LDAPQueryConditionsBuilder builder = new LDAPQueryConditionsBuilder();
    Condition conditionId;

    if (this.config.isObjectGUID()) {
        byte[] objectGUID = LDAPUtil.encodeObjectGUID(id);
        conditionId = builder.equal(getUuidAttributeName(), objectGUID);
    } else if (this.config.isEdirectoryGUID()) {
        byte[] objectGUID = LDAPUtil.encodeObjectEDirectoryGUID(id);
        conditionId = builder.equal(getUuidAttributeName(), objectGUID);
    } else {
        conditionId = builder.equal(getUuidAttributeName(), id);
    }

    // BUG: This filter is applied unconditionally to ALL lookupById calls,
    // including group and role lookups where it does not belong.
    if (config.getCustomUserSearchFilter() != null) {
        return builder.andCondition(new Condition[]{conditionId, builder.addCustomLDAPFilter(config.getCustomUserSearchFilter())});
    } else {
        return conditionId;
    }
}

LDAP Query Logs

Without User LDAP filter (correct behavior)

Query 1 - Group lookup:

LdapOperation: lookupById
baseDN: ou=groups,o=com
filter: (cn=Group1)
searchScope: 2
returningAttrs: [cn, member]
took: 3 ms

Query 2 - Member lookup using CNs from the group's member attribute:

LdapOperation: search
baseDn: o=com
filter: (&(|(cn=user1)(cn=user2))(objectclass=inetOrgPerson)(objectclass=organizationalPerson))
searchScope: 2
returningAttrs: [krb5PrincipalName, pwdChangedTime, cn, title, givenName, mobile, mail, createTimestamp, sn, fullName]
resultSize: 2
took: 6 ms

With User LDAP filter (LoginDisabled=false) (broken behavior)

Query 1 - Group lookup has the User LDAP filter injected:

LdapOperation: lookupById
baseDN: ou=groups,o=com
filter: (cn=Group1)(LoginDisabled=false))
searchScope: 2
returningAttrs: [cn, member]
took: 3 ms

The group object does not have a LoginDisabled attribute, so the query returns no results. Query 2 (member lookup) never executes.

貢獻者指南