Federation of user registries

User registry federation is used when user and group information is spread across multiple registries. For example, the information might be in two different LDAPs, in two subtrees of the same LDAP, in a file, or the users are of a system. The information might even be in a custom user data repository. With registries federated, you can search and use this distributed user information in a unified manner with continuous store of information. Using federated registry, you can use the unified view for authentication and authorization of users in Liberty.

Note: Quick start security (quickStartSecurity) cannot be federated with other user registries such as the LDAP, basic, SAF, and custom registries.

How are user registries federated?

LDAP registries are federated by default. If more than one LDAP registry is configured in the server.xml file, then the registries are automatically federated and no additional configuration is needed. You can have two separate LDAPs or two subtrees in the same LDAP.

If one or more LDAP registries are configured with one or more of basic, SAF, or custom registries, those registries are also federated without any additional configuration.

With federated repositories, all user registries and repositories are searched for users and groups. This process creates a single security realm. A user must be unique in the realm. If the user is not unique and more than one occurrence of a user is found, an exception is returned indicating that multiple principles were found.

Though federation happens automatically, You can use configuration options for the federated repository. The best practice is to add a federatedRepository configuration. Some important configuration options to consider with federation include the name of the federated realm, the behavior when a registry is down, as well as entry and groups mapping. See federatedRepository - User Registry Federation (federatedRepository) for configuration options.

Note: Only one security realm is supported. If you do not specify a primary realm name, the realm name from one of the existing registries is used. There is no guarantee that the same realm name is returned. Adding a federatedRepository configuration with a primaryRealm defined is recommended.

The following example shows a basic registry federated with an LDAP:

<server description="Federation">
    <featureManager>
        <feature>appSecurity-2.0</feature>
        <feature>servlet-3.0</feature>
	 <feature>ldapRegistry-3.0</feature>
    </featureManager>

    <basicRegistry id="basic" realm="SampleBasicRealm">
        <user name="admin" password="password" />
        <user name="user1" password="password" />
            <user name="user2" password="password" />
        <group name="memberlessGroup" />
        <group name="adminGroup">
            <member name="admin"/>
        </group>
        <group name="users">
            <member name="user1"/>
            <member name="user2"/>
        </group>
    </basicRegistry>

    <ldapRegistry id="LDAP1" realm="SampleLdapIDSRealm" host="LDAPHOST1.ibm.com" port="389" ignoreCase="true"
	baseDN="o=ibm,c=us"
	ldapType="IBM Tivoli Directory Server"
	searchTimeout="8m"
	recursiveSearch="true">
    </ldapRegistry>

    <federatedRepository>
        <primaryRealm name="PrimaryRealm" allowOpIfRepoDown="true">
            <participatingBaseEntry name="o=SampleBasicRealm"/>
            <participatingBaseEntry name="o=ibm,c=us"/>
        </primaryRealm>
   </federatedRepository> 
</server>
If you want to federate two basic registries or a basic registry with a SAF or custom registry, you can do so by including the federatedRegistry-1.0 in addition to the appSecurity-2.0 feature as shown in the following example:
    <feature>appSecurity-2.0</feature>
    <feature>federatedRegistry-1.0</feature>
The following example shows the federation of two basic registries:
<server description="Federation">
    <featureManager>
        <feature>appSecurity-2.0</feature>
        <feature>federatedRegistry-1.0</feature>
    </featureManager>

    <basicRegistry id="basic1" realm="SampleBasicRealm1">
        <user name="admin" password="password" />
        <user name="user1" password="password" />
            <user name="user2" password="password" />
        <group name="memberlessGroup" />
        <group name="adminGroup">
            <member name="admin"/>
        </group>
        <group name="users">
            <member name="user1"/>
            <member name="user2"/>
        </group>
    </basicRegistry>

    <basicRegistry id="basic2" realm="SampleBasicRealm2">
        <user name="user3" password="password123" />
        <user name="user4" password="password123" />
        <group name="memberlessGroup2" />
        <group name="users2">
            <member name="user3"/>
            <member name="user4"/>
        </group>
    </basicRegistry>
</server>
Basic registries can be added to a customized federated repository. A basic registry is added by defining the participatingBaseEntry name field in the federatedRepository element. The participating base entry for a basic registry is the organization attribute set to the realm name of the basic registry. The following example shows a customized federation of two basic registries:
<federatedRepository>
    <primaryRealm name="PrimaryRealm">
        <participatingBaseEntry name="o=SampleBasicRealm1"/>
        <participatingBaseEntry name="o=SampleBasicRealm2"/>
    </primaryRealm>
</federatedRepository>
Custom registries can also be added to a customized federated repository. A custom registry is added by defining the participatingBaseEntry name field in the federatedRepository element. The participating base entry for a custom registry is the organization attribute set to the realm name of the custom registry. The following example shows the federation of a customized entry:
<federatedRepository>
    <primaryRealm name="PrimaryRealm">
        <participatingBaseEntry name="o=customRegistryRealm1"/>
    </primaryRealm>
</federatedRepository>

To federate a SAF registry with one or more non-SAF registries and with SAF authorization enabled, you must configure distributed identity filters to map any non-SAF users to a SAF user ID. The following example illustrates a SAF registry that is federated with an LDAP registry and with distributed identity mapping enabled. The primaryRealm name is specified on the federatedReposity element so that any RACMAP profiles that are defined to map the LDAP users to the SAF user ID must specify REGISTRY(NAME('FEDREALM').

<server description="Federated SAF and LDAP">
  <featureManager>        
    <feature>appSecurity-2.0</feature>        
    <feature>federatedRegistry-1.0</feature>        
    <feature>zosSecurity-1.0</feature>  
    <feature>ldapRegistry-3.0</feature>
  </featureManager>
  <federatedRepository>   
     <primaryRealm name="FEDREALM">
        <participatingBaseEntry name="o=ibm,c=us"/>
        <participatingBaseEntry name="o=SAFREALM"/>
     </primaryRealm>
  </federatedRepository>

 <!-- SAF user registry -->    
 <safRegistry id="saf" realm="SAFREALM" /> 
 <safAuthorization id="saf" racRouteLog="ASIS" /> 
 <safCredentials unauthenticatedUser="WSGUEST"
      profilePrefix="BBGZDFLT"
      mapDistributedIdentities="true" />    
 <safRoleMapper profilePattern="%profilePrefix%.%resource%.%role%"
      toUpperCase="false" />

  <ldapRegistry id="LDAP1" realm="LDAPREALM" 
      ldapType="IBM Tivoli Directory Server"
      host="LDAP1HOST.ibm.com" port="389"        
      baseDN="o=ibm,c=us"  
      searchTimeout="8m"
      ignoreCase="true"        
      bindDN="uid=ldapadm,cn=users,o=ibm,c=us"        
      bindPassword="ldapadmpw"  
      sslEnabled="false">        
      <idsFilters            
          userFilter="(&amp;(uid=%v)(objectclass=inetOrgPerson))"            
          groupFilter="(&amp;(cn=%v)(objectclass=groupOfUniqueNames))"
          userIdMap="*:uid"            
          groupIdMap="*:cn"            
          groupMemberIdMap="groupOfUniqueNames:uniquemember">         
      </idsFilters>  
   </ldapRegistry>
</server>