This document is to describe the scenarios to be covered by WFLY-455 and as those scenarios are implemented will be updated to show the example configuration for each scenario.
Chaining
The authentication process and group loading occur as two distinct steps: -
- Validate the response recieved from the client in response to a challenge previously sent to the client.
- Based on the users confirmed identity perform the required searches to load the users groups.
WFLY-455 is the implementation of step 2 to load the users group information from LDAP, this could occur after step 1 has validated the user against LDAP or a completely different approach.
Where steps 1 and 2 both involve LDAP queries against the same server the connection should be cached to avoid the overhead of establishing a connection twice. Connection pooling may also be applicable.
Where step 1 is against LDAP and some generic query is performed based on the users identity this should be available to step 2 for re-use. A common example would be converting from the users supplied username to their distinguished name, if this conversion has already occurred in step 1 it should not be repeated in step 2.
In step 1 multiple backing stores could have been defined, e.g. a trust store as well as a ldap definition or in the future a SPNEGO definition and a LDAP definition. Need to consider scenarios where one LDAP definition to load groups does not make sense, e.g. where a client certificate was used for authentication we may want to load the roles from a properties file but if SPNEGO or LDAP based PLAIN authentication was used load the groups from LDAP.
Recursion
There are two levels of recursion to be considered when searching for groups: -
- Groups at different levels in the LDAP hierarchy, the search will need to be configured to search below the root distinguished name.
- As each group is loaded the group could also be a member of additional groups so the search process would recursively look for additional groups.
Additional Group Queries
Some LDAP installation allow for a user to be assigned one additional group on top of any groups identified by executing the group loading searches - an example of this is Microsoft Active Directory where a user is assigned a primary group that is referenced using an internal identifier that then needs to be cross referenced with the actual groups to identify the corresponding groups.
Group Mapping
An additional option to consider is allowing an override of the groups actually loaded from LDAP, this would really be a third step in the authentication process so it not being considered at the moment. Where groups are assigned to roles for the purpose of access control the configuration should be flexible enough to cope with multiple groups being mapped to the same role.
LDIF Examples
Example 1 - Active Directory
The following LDIF extract demonstrates a standard Active Directory installation where various directions of group memberships are shown across different locations within the hierarchy and through the primary group association.
dn: CN=Darran A. Lofthouse,CN=Users,DC=darranl,DC=jboss,DC=org memberOf: CN=Support Admin,OU=support,DC=darranl,DC=jboss,DC=org memberOf: CN=Investment Banker,CN=Users,DC=darranl,DC=jboss,DC=org memberOf: CN=Users,CN=Builtin,DC=darranl,DC=jboss,DC=org primaryGroupID: 513 objectSid:: AQUAAAAAAAUVAAAAotmuNBRw7meCijOMTwQAAA== sAMAccountName: darranl userPrincipalName: darranl@darranl.jboss.org dn: CN=Domain Users,CN=Users,DC=darranl,DC=jboss,DC=org objectClass: group cn: Domain Users memberOf: CN=Users,CN=Builtin,DC=darranl,DC=jboss,DC=org memberOf: CN=Support User,OU=support,DC=darranl,DC=jboss,DC=org name: Domain Users objectGUID:: Mwv5vtu82E+FvTtbhUSmzA== objectSid:: AQUAAAAAAAUVAAAAotmuNBRw7meCijOMAQIAAA== sAMAccountName: Domain Users dn: CN=Users,CN=Builtin,DC=darranl,DC=jboss,DC=org objectClass: group cn: Users member: CN=Darran A. Lofthouse,CN=Users,DC=darranl,DC=jboss,DC=org member: CN=Domain Users,CN=Users,DC=darranl,DC=jboss,DC=org distinguishedName: CN=Users,CN=Builtin,DC=darranl,DC=jboss,DC=org name: Users objectGUID:: +OnN7n2DUkqCmpZFjspBdA== objectSid:: AQIAAAAAAAUgAAAAIQIAAA== sAMAccountName: Users dn: CN=Investment Banker,CN=Users,DC=darranl,DC=jboss,DC=org objectClass: group cn: Investment Banker member: CN=Darran A. Lofthouse,CN=Users,DC=darranl,DC=jboss,DC=org memberOf: CN=Banker,CN=Users,DC=darranl,DC=jboss,DC=org name: Investment Banker objectGUID:: eGNw8LlNUUqSdhzs79MX2A== objectSid:: AQUAAAAAAAUVAAAAotmuNBRw7meCijOMUwQAAA== sAMAccountName: Investment Banker dn: CN=Banker,CN=Users,DC=darranl,DC=jboss,DC=org objectClass: group cn: Banker member: CN=Support User,OU=support,DC=darranl,DC=jboss,DC=org member: CN=Investment Banker,CN=Users,DC=darranl,DC=jboss,DC=org name: Banker objectGUID:: NGNZxgGCgkKdl+hbeLfpog== objectSid:: AQUAAAAAAAUVAAAAotmuNBRw7meCijOMUgQAAA== sAMAccountName: Banker dn: CN=Support User,OU=support,DC=darranl,DC=jboss,DC=org objectClass: group cn: Support User member: CN=Domain Users,CN=Users,DC=darranl,DC=jboss,DC=org name: Support User objectGUID:: 8bygyZ0um0GqhxBBOjXikg== objectSid:: AQUAAAAAAAUVAAAAotmuNBRw7meCijOMWgQAAA== sAMAccountName: Support User dn: CN=Support Admin,OU=support,DC=darranl,DC=jboss,DC=org objectClass: group cn: Support Admin member: CN=Darran A. Lofthouse,CN=Users,DC=darranl,DC=jboss,DC=org name: Support Admin objectGUID:: Lm3B93jxqEyCE9efPaeKig== objectSid:: AQUAAAAAAAUVAAAAotmuNBRw7meCijOMWQQAAA== sAMAccountName: Support Admin
The group memberships can be seen as: -
After authentication the user 'darranl' should be seen as being a member of the following groups: -
- Domain User
- Support User
- Users
- Investment Bank
- Banker
- Support Admin
Example 2 - Free IPA
The next example contains similar groups but this time was configured on a Free IPA installation.
dn: uid=darranl,cn=users,cn=accounts,dc=darranl,dc=org displayName: Darran Lofthouse cn: Darran Lofthouse krbPrincipalName: darranl@DARRANL.ORG uid: darranl mepManagedEntry: cn=darranl,cn=groups,cn=accounts,dc=darranl,dc=org dn: cn=darranl,cn=groups,cn=accounts,dc=darranl,dc=org objectClass: posixgroup objectClass: mepManagedEntry cn: darranl mepManagedBy: uid=darranl,cn=users,cn=accounts,dc=darranl,dc=org dn: cn=investment_banker,cn=groups,cn=accounts,dc=darranl,dc=org objectClass: groupofnames objectClass: nestedgroup objectClass: ipausergroup objectClass: posixgroup cn: investment_banker member: uid=darranl,cn=users,cn=accounts,dc=darranl,dc=org dn: cn=banker,cn=groups,cn=accounts,dc=darranl,dc=org objectClass: groupofnames objectClass: nestedgroup objectClass: ipausergroup objectClass: posixgroup cn: banker member: cn=investment_banker,cn=groups,cn=accounts,dc=darranl,dc=org
Like Active Directory there is also a single group assigned, this time it is assigned using the mepManagedEntry attribute. Unlike Active Directory however this is a single static private group which is specific to the user.
The following diagram illustrates the group membership for the user: -
After authentication the user 'darranl' should be seen as being a member of the following groups: -
- darranl
- Investment_Banker
- Banker
Comments
Examples 1 and 2 both show that a group search can be performed by searching for all group objects with a member object referencing the users dn, however as illustrated in example 1 Active Directory has an option to optimise this as the user object also references it's groups so an expensive search can be skipped and instead focus on just loading specified attributes from specific dns.
Comments