2 Design Recommendations

The default CARML and mapping files make certain assumptions about the deployment scenario. You may need to modify these details depending on your deployment requirements. The configuration parameters that can be modified are discussed in this chapter.

This chapter contains the following topics:

Choose a LoginID

In the default configuration, email is used as a unique identifier for identifying user entries. When you are searching for a user, the default attribute expected for search is email. For example:

SearchUser( String uniqueid,  Map<String, Object>)

For performance reasons, the attribute used as a unique identifier must be a searchable attribute in the backend. The mapping between the application's choice of uniquekey and the backend attribute is handled at configuration time. This is a configuration in Oracle Virtual Directory mapping. The HashMap is used to provide the optional context information to be used while performing the operation. In the current release it supports the following options:

  • The Principal user that performs the search - (ArisIdConstants.APP_CTX_AUTHUSER, (Principal)user)

  • The language constraint if any - (ArisIdConstants.APP_CTX_LOCALE, "fr")

  • Pagination support if any - (ArisIdConstants.APP_CTX_PAGESIZE, 10)

Choose a UniqueKey

An application occasionally stores the entries accessed from the identity repository's backend in their own application-specific repository. In such cases, you must carefully consider which attribute should be persisted. For instance, if the backend is an LDAP-based repository, you should use the GUID attribute as the persisting attribute because this is the only unique key on the LDAP-based backend. All other LDAP attributes are modifiable.

If the backend is a relational database, choose an attribute on which uniqueness constraint is enforced as the unique key. You can specify this in the ArisID mapping property file. The method to search for a user based on the unique key is:

searchUserOnUniqueKey(String UniqueKey, Map<String,Object>)

The HashMap is used to provide the optional context information to be used while performing the operation. In the current release it supports the following options:

  • The Principal user that performs the search - (ArisIdConstants.APP_CTX_AUTHUSER, (Principal)user)

  • The language constraint if any - (ArisIdConstants.APP_CTX_LOCALE, "fr")

  • Pagination support if any - (ArisIdConstants.APP_CTX_PAGESIZE, "10")

Specify Multiple Language Support

Multiple Language Support (MLS) is provided for applications that need locale-specific results. The attributes and the appropriate MLS code are stored in the ArisID properties file in the multiLanguageAttributes element.

<multiLanguageAttributes>…</multiLanguageAttribute>

Because displayname is the most commonly used multiple language attribute, it is configured by default as a multi-language attribute. Other attributes can be added as needed in the ArisID mapping file.

Restrictions

Any API to which locale is specified as an argument will return the locale-specific values for all the attributes listed in the ArisID properties file as <multiLanguageAttributes> that have locale-specific values. For all other attributes it returns the default values stored.

In the backend system, the data is returned in a form conforming to ISO-3166. For example, if there is a French locale (in addition to English), it is stored as cn,:fr for the cn attribute. The locale for the client applications should be specified in the properties HashMap as ArisIdConstants.APP_CTX_LOCALE, "fr" and the ArisID properties file should contain cn as multiLanguageAttribute and map this attribute.

Handle Large Results

When applications access identity data, the result set for a search is frequently too large to be handled by the application. In such cases you have the option of dividing the result into manageable sized pages. You do this by defining the number of objects to be returned in the page.

The following example shows a typical usage pattern:

RoleManager rm = new RoleManager(env); 
  List<PropertyFilterValue> attrFilters = new  ArrayList<PropertyFilterValue>(); 
  attrFilters.add(new PropertyFilterValue(Role.NAME, "admin", AttributeFilter.OP_CONTAINS)); 

  HashMap<String,Object> map = new HashMap<String,Object>(); 
  map.put("ArisIdConstants.APP_CTX_PAGESIZE","2"); 
  SearchResults<Role> sr = rm.searchRolesbyPage(attrFilters, map); 

  while(sr.hasMore()) 
  { 
     List<Role> roles = sr.getNextSet(); 

     for (int i=0; i<roles.size(); i++) 
       //do the operations with roles.get(i)
}

Secure the Application

Two security scenarios are available for executing create, read, update, and delete (CRUD) operations on the target system. They are:

  • Domain level credentials

  • Application level credentials

Proxy authentication is not supported in this release.

Domain Level Credentials

In this scenario, all applications in a domain use common credentials to connect to the target system and perform operations with those credentials. The application does not maintain a footprint in the target system.

The LDAP Adapter's configuration file, adapters.os_xml, contains credentials to connect to the backend directory, along with the host and port details. If you do not provide any other credentials during initialization, the application connects to the target system using the credentials in the LDAP Adapter's configuration file.

If proxy user (logged in user id) is not specified in the API's application context, ArisID operation will be executed with the credentials that are in LDAP Adapter's configuration file.

If your application connects using common credentials, you must build security into the application itself so that it displays or modifies data only for an authorized user.

Code Sample

The LDAP Adapter's configuration file adapters.os_xml is configured with domain level userid and encrypted password to connect to backend directory. The following is a snippet of adapters.os_xml.

    <binddn>cn=admin</binddn>
    <bindpass>{OMASK}C2QXW1Nmf+s=</bindpass>

While initializing the ArisID API do not provide any credentials.

Map env = new HashMap();
// Do not set UserManager.SECURITY_PRINCIPAL & SECURITY_CREDENTIALS
UserManager uMgr  = new UserManager(env);
…
…
// Search Operation (with no proxy user in app context)
List<PropertyFilterValue> attrFilters = new ArrayList<PropertyFilterValue>();
attrFilters.add(new PropertyFilterValue("User.FIRSTNAME", "app1", AttributeFilter.OP_CONTAINS));
attrFilters.add(new PropertyFilterValue("User.LASTNAME", "user1", AttributeFilter.OP_BGNSWITH));
Map<String, Object> appCtx = null;
users = um.searchUsers(attrFilters, appCtx);

Application Level Credentials

In this scenario, each application uses application level credentials to connect to the target system and performs CRUD operations with those credentials.

In this case you provide the application's user id and password while initializing the ArisID API. When you do that, the application connects to the target system using those credentials.

If no proxy user is specified in the API's application context then ArisID operation will be executed with the application's credentials.

This scenario has the following features:

  • Each application has different privileges to view and update the data in the target system

  • You can audit the modifications performed by each application in the target system

Code Sample

The LDAP Adapter's configuration file adapters.os_xml is configured with domain level userid and encrypted password to connect to backend directory. The following is a snippet of adapters.os_xml.

    <binddn>cn=admin</binddn>
    <bindpass>{OMASK}C2QXW1Nmf+s=</bindpass>

While initializing the ArisID API, provide the application user credentials.

Map env = new HashMap();
env.put(UserManager.SECURITY_PRINCIPAL, "cn=app1_user,cn=users,dc=oracle,dc=com");
env.put(UserManager.SECURITY_CREDENTIALS, "mypassword");
UserManager uMgr  = new UserManager(env);
…
// Search Operation (with no proxy user in app context)
List<PropertyFilterValue> attrFilters = new ArrayList<PropertyFilterValue>();
attrFilters.add(new PropertyFilterValue("User.FIRSTNAME", "app1", AttributeFilter.OP_CONTAINS));
attrFilters.add(new PropertyFilterValue("User.LASTNAME", "user1", AttributeFilter.OP_BGNSWITH));Map<String, Object> appCtx = null;
users = um.searchUsers(attrFilters, appCtx);