I am using SonarQube Developer edition Version 9.3 (build 51899) deployed from the zip file running on an RHEL 8 server. For identity management I use IdM (which utilizes directory schema similar to FreeIPA and 389DS, you shall find the supported specifications here). Current LDAP group mapping configuration looks like this (in file conf/sonar.properties):
sonar.security.realm=LDAP
ldap.url=ldap://freeipa.example.com
ldap.bindDn=uid=sonarservice,cn=users,cn=accounts,dc=example,dc=com
ldap.bindPassword=REDACTED
ldap.authentication=simple
ldap.user.baseDn=cn=users,cn=accounts,dc=example,dc=com
ldap.user.request=(&(objectClass=inetOrgPerson)(uid={login}))
ldap.user.realNameAttribute=cn
ldap.user.emailAttribute=mail
ldap.group.baseDn=ou=Groups,dc=example,dc=com
ldap.group.request=(&(objectClass=posixGroup)(memberUid={uid}))
ldap.group.idAttribute=cn
sonar.log.level=DEBUG
With this configuration Sonarqube fails to retrieve group membership from IdM which results in the removal of the configured group assignments for the user logging in, nevertheless authentication works as expected and the user is able to login successfully. The default group request value (&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))
doesn’t work either.
Here are related entries from the SonarQube weblog:
2023.05.25 15:36:57 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapUsersProvider] Requesting details for user exampleuser
2023.05.25 15:36:57 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=cn=users,cn=accounts,dc=example,dc=com, scope=subtree, request=(&(objectClass=inetOrgPerson)(uid={0})), parameters=[exampleuser], attributes=[mail, cn]}
2023.05.25 15:36:57 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=sonarservice,cn=users,cn=accounts,dc=example,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldap://freeipa.example.com, java.naming.security.authentication=simple}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=cn=users,cn=accounts,dc=example,dc=com, scope=subtree, request=(&(objectClass=inetOrgPerson)(uid={0})), parameters=[exampleuser], attributes=null}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=sonarservice,cn=users,cn=accounts,dc=example,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldap://freeipa.example.com, java.naming.security.authentication=simple}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=exampleuser,cn=users,cn=accounts,dc=example,dc=com, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldap://freeipa.example.com, java.naming.security.authentication=simple}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapGroupsProvider] Requesting groups for user exampleuser
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=cn=users,cn=accounts,dc=example,dc=com, scope=subtree, request=(&(objectClass=inetOrgPerson)(uid={0})), parameters=[exampleuser], attributes=[uid]}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=sonarservice,cn=users,cn=accounts,dc=example,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldap://freeipa.example.com, java.naming.security.authentication=simple}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapSearch] Search: LdapSearch{baseDn=ou=Groups,dc=example,dc=com, scope=subtree, request=(&(objectClass=posixGroup)(memberUid={0})), parameters=[exampleuser], attributes=[cn]}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.a.l.LdapContextFactory] Initializing LDAP context {java.naming.referral=follow, java.naming.security.principal=uid=sonarservice,cn=users,cn=accounts,dc=example,dc=com, com.sun.jndi.ldap.connect.pool=true, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, java.naming.provider.url=ldap://freeipa.example.com, java.naming.security.authentication=simple}
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.s.a.UserRegistrarImpl] List of groups returned by the identity provider '[]'
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][o.s.s.a.UserRegistrarImpl] Removing group 'sonar-administrators' from user 'exampleuser'
2023.05.25 15:36:58 DEBUG web[AYeT9B6/a2guaIxFAWlP][auth.event] login success [method|FORM][provider|REALM|LDAP][IP|10.0.0.1|][login|exampleuser]
From the commandline if I execute the following LDAP query I can see whether a user has membership to the sonar-administrators group on my identity management system (if any entries are returned that means that the user is member of the sonar-administrators group):
ldapsearch -H ldap://freeipa.example.com -D 'uid=sonarservice,cn=users,cn=accounts,dc=example,dc=com' -x -W -b 'uid=exampleuser,cn=users,cn=accounts,dc=example,dc=com' '(memberOf=cn=sonar-administrators,cn=groups,cn=accounts,dc=example,dc=com)'
Without the LDAP filter I can view all group memberships for the user as memberOf entries.
I want to configure SonarQube so that it can discover group memberships from my identity management system (IdM) so that it does not remove group memberships as soon as a user logs in.
I am aware that SonarQube has not been tested with IdM.
My questions:
Does SonarQube support memberOf attributes?
How should the group lookup response look like from the IdM so that SonarQube discovers group memberships?
Thanks in advance!