Search code examples
javaspringspring-bootldaprbac

LDAP-based RBAC using newer versions of spring-security


Goal

Given a /secure endpoint that requires an LDAP user to be in the admin group, how do I check their granted authorities using more current versions of spring security?

Background

Here's a github repo with a reproducible example of LDAP authentication with an openLDAP container. At tag pre-upgrade, you can authenticate as unauthorized but cannot view the /secure endpoint. At the current commit on main, unauthorized can authenticate and view /secure, which it not desired.

In the upgrade, changes to the ldapAuthoritiesPopulator() probably cause the issue. You can view the diff between main and pre-upgrade here, take a look at SecurityConfig.java.

An internal method (getGroupMembershipRoles()) for ldapAuthoritiesPopulator() did the roles check, but after upgrading it looks like that function was removed. Where should the logic for securing endpoints based upon LDAP group membership go instead?

Related Resources

Authentication Log Output

  • Pre-Upgrade - authorized user logs in, followed by unauthorized user
10:22:07.156 [http-nio-8080-exec-3] WARN  org.example.LoggerListener - Authentication event AuthenticationSuccessEvent: authorized; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=A978FE05724BD750548AD8148347D665]
10:22:07.157 [http-nio-8080-exec-3] WARN  org.example.LoggerListener - Authentication event SessionFixationProtectionEvent: authorized; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=A978FE05724BD750548AD8148347D665]
10:22:07.157 [http-nio-8080-exec-3] WARN  org.example.LoggerListener - Authentication event InteractiveAuthenticationSuccessEvent: authorized; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=A978FE05724BD750548AD8148347D665]
10:23:43.668 [http-nio-8080-exec-8] WARN  org.example.LoggerListener - Authentication event AuthenticationFailureBadCredentialsEvent: unauthorized; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=65900F1284AA62D158BCA96A22D3744A]; exception: User must be a member of ROLE_ADMIN
  • Post-Upgrade - authorized user logs in, followed by unauthorized user
10:15:24.101 [http-nio-8080-exec-4] WARN  org.example.LoggerListener - Authentication event SessionFixationProtectionEvent: authorized; authorities: []; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=E3CDB4A1CF9B3766A5DB70F9D7C50586]
10:15:24.102 [http-nio-8080-exec-4] WARN  org.example.LoggerListener - Authentication event InteractiveAuthenticationSuccessEvent: authorized; authorities: []; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=E3CDB4A1CF9B3766A5DB70F9D7C50586]
10:25:38.098 [http-nio-8080-exec-3] WARN  org.example.LoggerListener - Authentication event SessionFixationProtectionEvent: unauthorized; authorities: []; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=10D2AD100DDFF5CB15FDE5526BE85722]
10:25:38.098 [http-nio-8080-exec-3] WARN  org.example.LoggerListener - Authentication event InteractiveAuthenticationSuccessEvent: unauthorized; authorities: []; details: WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=10D2AD100DDFF5CB15FDE5526BE85722]

Solution

  • Turns out all I needed to do was call factory.setLdapAuthoritiesPopulator(ldapAuthoritiesPopulator(contextSource)); within authenticationManager().

    The POC repo has been updated with these changes, you can clone and run that to see the desired outcome.