Skip to content

Support matching LDAP external groups by full DN, not just bare CN#3982

Draft
duanemay wants to merge 4 commits into
developfrom
roles-ldap-dn
Draft

Support matching LDAP external groups by full DN, not just bare CN#3982
duanemay wants to merge 4 commits into
developfrom
roles-ldap-dn

Conversation

@duanemay

Copy link
Copy Markdown
Member

Summary

UAA only ever reports the bare cn of an LDAP group as a user's "external group" name — used for ldap.externalGroupsWhitelist matching and the /userinfo endpoint's roles field — even though the group's full DN is already available on every LdapAuthority and is silently discarded. This traces back to a hardcoded la.getAttributeValues("cn") call in LdapLoginAuthenticationManager.getAuthoritiesAsNames() that's been unchanged since 2015.

This breaks CF's external-group role-assignment feature when the CF-side role mapping is configured using a group's full DN (e.g. cn=cf_admin,ou=dev,dc=example,dc=com — what an admin gets copy-pasting a group out of Active Directory), since UAA never reports a string that matches it.

Fix

Adds a new opt-in LDAP identity provider config property, includeExternalGroupDn (default false). When enabled, the group's full DN is added as an additional candidate name alongside the existing cn value — never replacing it — so:

  • Default behavior is unchanged for every existing deployment (verified via full LDAP test suite).
  • Admins with existing cn-based whitelist entries can add DN-based entries without breaking the cn-based ones.
  • We intentionally did not default this to true, even though it's purely additive to whitelist matching: externalGroupsWhitelist defaults to "allow everything," so turning it on by default would silently add every LDAP group's DN into /userinfo's roles field and the ID token roles claim for every existing customer on upgrade — a real, externally-visible payload change nobody asked for. This mirrors the existing precedent of uaa.jwt.access.include_external_groups, which is also opt-in for the same reason.

This is scoped entirely to LDAP's whitelist//userinfo-roles pipeline. It does not touch:

  • SAML/OIDC group handling (separate code paths)
  • UAA's internal group-to-scope mapping (external_group_mapping table / LdapGroupMappingAuthorizationManager), which already supports DN-based matching via the unrelated groupRoleAttribute config

Changes

  • LdapIdentityProviderDefinition / LdapUtils: new includeExternalGroupDn field, accessors, and uaa.yml bootstrap wiring
  • LdapLoginAuthenticationManager: getAuthoritiesAsNames() unions in the DN when the flag is enabled
  • Tests added first to demonstrate the gap (see commit history — tests-first, then fix)
  • Docs: UAA-LDAP.md, UAA-APIs.rst, UAA-Configuration-Reference.md, uaa.yml sample, REST Docs field descriptor — also corrected a pre-existing doc inaccuracy that claimed externalGroupsWhitelist already matched on DN values, and backfilled two other undocumented LDAP properties (groupRoleAttribute, externalGroupsWhitelist) found missing from the config reference table

Test plan

  • New unit tests (LdapLoginAuthenticationManagerTests, LdapIdentityProviderDefinitionTest) covering default-off behavior, DN-only matching, and mixed cn+DN whitelists
  • New integration test (AbstractLdapMockMvcTest) against a real embedded LDAP server, covering both the as-scopes and map-to-scopes group profiles
  • Full LDAP test suite run: 117 tests, 0 failures, 24 pre-existing skips unrelated to this change
  • REST Docs snippet generation (IdentityProviderEndpointDocs) verified green after adding the new field descriptor

🤖 Generated with Claude Code

duanemay added 4 commits July 15, 2026 15:19
UAA only ever reports the bare cn of an LDAP group as its "external
group" name (used for the externalGroupsWhitelist and /userinfo's
roles field), never the full DN. This breaks CF's external-group
role-assignment feature when the CF-side mapping is configured with
a group's full DN, since it can never match what UAA reports.

Adds the includeExternalGroupDn plumbing (config field, accessors,
uaa.yml wiring) needed for the fix, plus tests that pin down current
default behavior and demonstrate the gap: enabling the flag should
add the DN as an additional matchable external-group name, but the
extraction logic hasn't been updated yet, so those new assertions
fail. The fix lands in a follow-up commit.
…upDn is enabled

UAA only ever surfaced the bare cn of an LDAP group as its "external
group" name, discarding the full DN even though it's already present
on every LdapAuthority. This broke CF's external-group role
assignment feature when the CF-side mapping was configured using a
group's full DN, since that string could never match.

getAuthoritiesAsNames() now unions the DN in as an additional
candidate name (never replacing cn) when includeExternalGroupDn is
enabled, so existing cn-based whitelist/scope configs are unaffected
by default and admins can opt in to DN-based matching. Makes the
previously-failing tests from the prior commit pass.
Adds the new property to UAA-LDAP.md and UAA-APIs.rst (also
correcting the existing externalGroupsWhitelist description, which
incorrectly claimed DN values were already supported), a commented
uaa.yml sample, and the REST Docs field descriptor for the identity
providers API snippet generator.
…Whitelist, includeExternalGroupDn

UAA-Configuration-Reference.md's LDAP table was missing entries for
groupRoleAttribute and externalGroupsWhitelist even though both are
documented elsewhere (UAA-LDAP.md, UAA-APIs.rst). Backfilling those
alongside the new includeExternalGroupDn property so the table and
its per-property detail sections stay internally consistent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

1 participant