JBoss Community Archive (Read Only)

RHQ 4.9

LDAP Group Authorization

LDAP Group Authorization

What it is

RHQ will be modified to allow LDAP groups to map to RHQ Roles that will enable LDAP users to inherit role based authorization schemes after authentication is complete.

User Login --> User Auth LDAP -> User also local user? (no) -> create local user in db automatically -> query LDAP groups for user

                                                                                   (yes) -> query LDAP groups to user

LDAP group query --> Query groups for LDAP user based on full user DN -> Sync user LDAP groups

Sync user LDAP groups -> update Subject/Role tables using LDAP Group/Role mapping table

Screenshots

LDAP Configuration Screen
images/author/download/attachments/73139305/ldap1.png

Role Edit Screen images/author/download/attachments/73139305/ldap2.png

Add LDAP group to Role Screen

images/author/download/attachments/73139305/ldap3.png

Modified Role with new LDAP Group

images/author/download/attachments/73139305/ldap4.png

Implementation Details

Database

Modify RHQ_SUBJECT_ROLE_MAP Table

we will need to add a column, named IS_LDAP that will track if the subject to role mapping was created via a ldap group

Add RHQ_ROLE_LDAP_GROUP_MAP Table

this one will be similar to the resource group map table but we will be tracking the mapping between LDAP groups to roles instead of resource groups. Two columns need to be added to track the Role Id and then the LDAP Group name

System Configuration Settings Page

A new field will need to be added to track the LDAP Group Search Query. The source files SystemConfigForm.java, RHQConstants.java, LDAPForm.jsp and ApplicationsResources.properties need to be modified to support the new Group Search Query that will be added to the database as a label, value pair.

LDAP Group Assignment Page

This will be very similar to the Groups (resource) that are added to roles. There will be an extra box underneath the existing Groups Box that is seen on the Role assignment page. The existing groups will be renamed to "Resource Groups" to distinguish itself from the new LDAP Group box. A query will need to occur to grab all the available groups from the LDAP page. Groups added to the role will be stored in the RHQ_ROLE_LDAP_GROUP_MAP Table

Group query logic

The existing LDAPLoginModule.java, SubjectManagerBean.java will either need to be modified or logic will need to be adapted in another java source file to handle the ldap group search queries. Currently we are using JNDI calls based on the LDAP configuration module properties. JNDI will also be used for the group search queries.

Logic needs to be added to determine what groups a user is a member of. Currently three are two approaches due to the way LDAP servers model their group members. AD users a attribute (that other ldap servers apparently use as well) named memberOf that hangs off the user objects and then users a attribute named member that hangs off the group objects. OpenLDAP does things a big differently but we can still query the groups based off the full DN of the user that is logging in but requires two separate queries due to the different approaches.

An example of using ldapsearch for AD:

ldapsearch -h example.ad.redhat.com -x -D "cn=Administrator,cn=Users,dc=2k8domain,dc=gss" -W -b "dc=2k8domain,dc=gss" -x '(&(objectclass=group)(member=CN=Jeremy Agee,CN=Users,DC=2k8domain,DC=gss))'

An example of using ldapsearch for OpenLDAP:

ldapsearch -H ldap://example.open.redhat.com:389 -b dc=open,dc=redhat,dc=com -x '(&(objectclass=groupOfUniqueNames)(uniqueMember=uid=shaggy,ou=People, dc=open, dc=redhat, dc=com))'

Both of the searches above returns a list of group(s) for the users DN.

Login Logic

At user login we need to make sure that we update the RHQ_SUBJECT_ROLE_MAP if the ldap user logging in is part of a group that has a role assigned to it in the new RHQ_ROLE_LDAP_GROUP_MAP table. similar, we need to remove entries that have lost the ldap group to role assignments. this can occur in the ldaploginmodule.java source file

Questions

  • if we know some user is an ldap-based user...do we want to control the role-subject mappings through the sync process ONLY, or do we also want to allow users to manually modify that list? if so, then we should disable removing ldap-based role-subject mappings, right?

  • alternate solution would be to have two mapping tables: the current rhq_subject_role_map and a new rhq_subject_role_ldap_map. then, we have two @ManyToMany sets of mappings, one for ldap-synced mappings, the
    other for regular mappings setup through the RHQ UI.

  • any additions/removals from the ldap-based collection would also add/remove from the regular collection. authorization would still be done through the regular collection.

Question Feedback (from Joseph)

Solution 1 (Solution 2 was implemented)

Short Description
  • new column IS_LDAP on the RHQ_SUBJECT_ROLE_MAP table

Implementation Overview
  • current @ManyToMany mappings will not let you access that metadata column on the linking table, so...

    • need to create new entity called SubjectRoleEntity

    • need OneToMany mapping from Role->SubjectRoleEntity (called 'roleSubjects')

    • need OneToMany mapping from Subject->SubjectRoleEntity (called 'subjectRoles')

  • need to enhance RoleManagerBean methods to handle LDAP logic

    • add new methods for LDAP management (CRUD for 'roleSubjects' collection according to the sync results)

      • add / remove rows as necessary, but only those where IS_LDAP is true

    • modify removeSubjectsFromRole and removeRolesFromSubject methods to disallow removal of rows where IS_LDAP=true (in other words, manual additions/deletions can only affect manually added role/subject mappings)

Pro
  • Does not duplicate data, instead relies on a bit field to denote regular- or ldap-context

  • Can easily extend this design in the future by making IS_LDAP into an enumerated field

    • The values today might be "database" and "ldap", but adding support for a new type is a simple matter of adding a new enumerated value

Con
  • JPQL slightly more complex

    • Get LDAP roles for subject "SELECT sr.role FROM SubjectRole sr WHERE sr.isLdap = true AND sr.subject.id = :someUserId"

    • Get regular roles for subject "SELECT sr.role FROM SubjectRole sr WHERE sr.isLdap = false AND sr.subject.id = :someUserId"

  • Can not easily get the appropriate set at the object layer

    • Might be able to use collection-filtering feature of Hibernate, but it should be discouraged because it's not part of EJB 3 spec (yet)

    • Take a look at PersistenceUtility.createPaginationFilter for how we use Hibernate collection filters in the product today

  • Have two different mapping sets for the same data (the original @ManyToMany set, and the two new @OneToMany mappings)

    • This might be confusing for new members needing to change something in that part of the code, so we would need to document the purpose and intent for each mapping set clearly for maintainability in the future

Solution 2

Short Description
  • new mapping table, to keep LDAP-based mappings completely seperate from manually created ones

Implementation Overview
  • create new linking table called RHQ_SUBJECT_ROLE_LDAP_MAP

    • no new entities needed

    • add ManyToMany mapping from Role->Subject (called 'ldapSubjects')

    • add ManyToMany mapping from Subject->Role (called 'ldapRoles')

  • need to enhance RoleManagerBean methods to handle LDAP logic

    • add new methods for LDAP management (CRUD for 'ldapRoles' collection according to the sync results)

      • as elements are added to / removed from 'ldapRoles', add / remove the same from 'roles'

    • modify removeSubjectsFromRole/removeRolesFromSubject methods to disallow removal of elements from 'roles' if the same element exists in 'ldapRoles'

Con
  • Duplicates data and logic - since the authorization check actually occurs against the original RHQ_SUBJECT_ROLE_MAP table, any row modifications (add / remove) against RHQ_SUBJECT_ROLE_LDAP_MAP also need to be duplicated against RHQ_SUBJECT_ROLE_MAP

  • Design is relatively static

    • In order to extend this to support another type of mapping between a role and a group, you would need to:

      • use the above solution (on either the 'roles/subject' or 'ldapRoles/ldapSubjects' mapping sets)

      • add another set of @ManyToMany mappings to represent the new type of mapping that you want to maintain between subjects and roles

Pro
  • Simple JPQL

    • Get LDAP roles for subject "SELECT r FROM Subject s JOIN s.ldapRoles r WHERE s.id = :someUserId"

    • Get regular roles for subject "SELECT r FROM Subject s JOIN s.roles r WHERE s.id = :someUserId"

  • Can very easily get the appropriate set at the object layer

    • someSubject.getLdapRoles() or someSubject.getRoles()

    • someRole.getLdapSubjects() or someRole.getSubjects()

  • Clear distinction between each set of mappings, since they actually refer to different data collections

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 08:16:29 UTC, last content change 2013-09-18 19:40:53 UTC.