3 Using the ArisID API

This chapter describes the architecture and key functionality of the Identity Governance Framework ArisID API (ArisID API). The ArisID API provides enterprise developers and system architects a library for building identity-enabled applications using multiple identity protocols. The ArisID API enables developers to specify requirements for identity attributes, roles, and search filters by using Client Attribute Requirements Markup Language (CARML). This chapter contains the following topics:

3.1 About ArisID API

The Identity Governance Framework ArisID API represents a common core service through which all identity information exchanged should be passed. While not an official name, the ArisID API is often referred to as Identity Beans by developers.

The 11g Release 2 (11.1.2) release of the ArisID API is a subset of the configuration proposed at:

http://www.openliberty.org/wiki/index.php/ArisID_Configuration.

If you have installed Oracle WebLogic Server and Oracle Identity Management, all the necessary jar files for developing applications with this API are already installed on your computer.

See Also:

The Identity Governance Framework open source API jar files are as follows:

The ArisID API jar files are as follows:

The ArisID beans provide the Java APIs required for initialization and accessing CARML interactions. The bean generator generates a set of java files for each entity in the CARML file using Apache Velociy. The CARML file is a declarative document that describes the attribute usage requirements of your application. The ArisID beans are in the jar files idxuserrole.jar and userrole.jar. If the standard ArisID beans do not meet your needs, you can generate new ArisID beans by creating a CARML file and using the bean generator in the Identity Governance Framework ArisID extension to JDeveloper.

The following figure provides a high-level view of the ArisID API architecture.

Figure 3-1 IGF ArisID API Architecture

IGF ArisID API Architecture
Description of "Figure 3-1 IGF ArisID API Architecture"

3.2 Configuring ArisID API

The Identity Governance Framework ArisID extension supports the basic development process Create > Modify > Test > Deploy. Creation requires starting a new JDeveloper project and creating CARML files. Use the CARML editor to modify the CARML XML files to suit your environment. Testing the application can be done in Oracle WebLogic Server embedded LDAP directory server.

This section contains the following topics:

3.2.1 Configuring CARML Files

Determine whether the existing ArisID beans meet your application's needs by examining the CARML files idxuserrole.xml (read-only operations) and userrole.xml (read-only and read/write operations). These files are located in DOMAIN_HOME/config/fmwconfig/carml. If you need additional attributes or other customizations, create a new CARML file and generate beans as described in Section 3.4, "Developing Applications with ArisID API".

3.2.2 Configuring the Identity Repository

The identity repository to be used by the ArisID beans must be available. You can use the Oracle WebLogic Server embedded LDAP-based directory server or any LDAP directory supported by 11g Oracle Virtual Directory. The ArisID API is integrated with Oracle Platform Security Services. It automatically connects to the LDAP-based identity store configured in Oracle Platform Security Services. For more information about the identity stores supported by Oracle Platform Security Services, see "System Requirements and Certification".

For more information about Oracle Platform Security Services, see Oracle Fusion Middleware Application Security Guide.

If you must use a different identity store from the Oracle Platform Security Services identity store, then set the following system property:

igf.ovd.config.dir=DOMAIN_HOME/config/fmwconfig/arisidprovider/conf 

Next, edit the adapters.os_xml file to include the host, port and credentials of the directory to be connected to. The igf.ovd.config.dir property can be set to any other directory containing adapaters.os_xml and other configuration files with the right settings.

For OpenLDAP, Role.MEMBER is a mandatory attribute for the following APIs:

  • createRole(List<PropertyValue> attrVals, Map<String,Object> appCtxMap)

  • createRole(List<PropertyValue> attrVals)

If the Role.MEMBER is not included in the input attrVals list, role creation will fail.

3.2.3 Configuring the Mapping File

When a CARML file is created a corresponding mapping file is created in the same location. The default mapping file has attribute details specific to Oracle WebLogic Server embedded directory server, which is the Oracle Platform Security Services default identity store. If you are using a default CARML file and the Oracle Platform Security Services identity store, you do not need to configure mapping. The configuration parameters in Oracle Platform Security Services override the parameters in the mapping file.

If you are creating your own CARML file with additional attributes, or if you are using a non-Oracle Platform Security Services identity store, you must edit the mapping file. For more information, see Section 3.4, "Developing Applications with ArisID API".

3.3 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 section.

This section contains the following topics:

3.3.1 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)

3.3.2 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")

3.3.3 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.

3.3.4 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)
}

3.3.5 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.

3.3.5.1 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.

Example 3-1 Code Sample: adapters.os_xml

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);

3.3.5.2 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

Example 3-2 Code Sample: adapters.os_xml

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);

3.3.6 Configure the Timeout Interval

The default connect/read timout is configured to be 15 seconds. For example, if the LDAP operation on IdentityStore is taking more than 15 seconds, the operation will timeout and throw the following IGF exception:

org.openliberty.arisid.stack.ConnectionException

If the IdentityStore has a many entries and the applications are using filters with "contains" and search with paging/sorting, those queries may timeout.

The recommendation is to set the timeout value to 0 (no timeout) and increase the pool size to 20. If the preference is for the application has some timeout interval, set the value to greater than 0.

To configure the timeout interval:

  1. Run the following WLST command to list all adapters.

    listAdapters() 
    
  2. Run the following command for each adapter to set timeout and maxpoolsize.

    1. modifyLDAPAdapter('<ADAPTER NAME>', 'OperationTimeout', 0)

    2. modifyLDAPAdapter('<ADAPTER NAME>', 'MaxPoolSize', 20)

  3. Restart WebLogic Server.

3.4 Developing Applications with ArisID API

This section describes how to use Identity Governance Framework ArisID Extension to Oracle JDeveloper to develop applications.

See Also:

Oracle Fusion Middleware Installation Guide for Oracle JDeveloper

This section contains the following topics:

3.4.1 Developing with JDeveloper

When developing an application with the ArisID API you will typically perform the following tasks:

  • Create an ArisID project in Oracle JDeveloper.

  • Create and configure a CARML file.

  • Generate the ArisID beans.

  • (Optional) Edit the mapping file.

The Identity Governance Framework ArisID extension for JDeveloper is organized into several different packages. The packages are separated primarily by functionality. At the top level, the packages are for the CARML Overview Editor, the Relationship Editor, the Mapping Editor, Bean Generation, and Project Creation. Project creation contains all the classes required for creating a project structure, managing project properties, and creating CARML files. Common elements shared between many of these packages are kept in .common. This is primarily abstract classes for common Swing components and Parsing/Modeling XML structures.

3.4.1.1 Creating the Project

The first step in using Identity Governance Framework ArisID is to create a project in Oracle JDeveloper. After the Identity Governance Framework ArisID extension is installed, ArisID/IGF Project is added to the project gallery in JDevelolper. The corresponding project wizard adds the ArisID required libraries, creates a directory structure, and adds the option to test the ArisID configuration. The follow figure shows an example ArisID project and the directory structure as it appears in JDeveloper:

Description of igfdg_jdev_project.gif follows
Description of the illustration igfdg_jdev_project.gif

To create a project:

  1. Choose File then New to open the New Gallery.

  2. In the Categories tree, expand General and select Projects.

  3. Choose IGF/ArisID Project and click OK.

  4. Specify a Project Name and Directory for your project on the Project Name page.

  5. Optionally, move additional technologies from the Available list to the Selected list.

  6. Specify a Default Package, Java Source Path, and Output Directory for your project in the Project Java Settings page.

  7. Specify J2SE or J2EE in the Configure IGF/CARML Setting page.

  8. Click Finish.

3.4.1.2 Creating and Editing the CARML File

You declare the application requirements in terms of attributes and interactions. These are specified using a Client Attribute Requirements Markup Language (CARML) file. The CARML editor is an XML editor that lets you edit the various fields of a CARML file. The following figure shows an example CARML XML file displayed in the CARML Editor with the Data Definitions section:

Description of igfdg_carml_editor.gif follows
Description of the illustration igfdg_carml_editor.gif

To create a new CARML file:

  1. Choose File then choose New to open the New Gallery.

  2. In the Categories tree, expand Business Tier and choose Security.

  3. In the Items list, double click Client Attributes Requirements (CARML) to open the dialog.

  4. In the Create CARML File dialog, specify the name of the file that you would like to create and click OK.

    You can use any of the templates provided. The associated description provides the details about each of the template files.

    The General page of the CARML file editor appears.

  5. Specify the values for the two fields on the General page: CARML Unique Indicator and CARML description.

  6. Specify your application attribute requirements in the Data Definitions page. Add entities and specify data interactions for entities.

  7. Specify the application based interaction requirements in the Data interactions page. During the data interactions step, specify filters for interaction types.

To edit an existing CARML file, double-click the appropriate file in the Projects panel to open it in the overview editor for CARML files.

3.4.1.3 Generating ArisID Beans

When you have finished editing your CARML file, you can generate the ArisID Beans to use in your application. If you have created a relation file according to the schema definitions bundled with the ArisID API, you can use it when generating the beans.

After you have specified your attribute and interaction declarations in the CARML file, you can generate the corresponding bean classes to use in your application. If you have multiple entities defined in the file, and would like to specify the relationship between the entities, you can do so using the relationship file.

To generate the beans:

  1. In the Projects pane, highlight the CARML file you want to use to generate the beans.

  2. Right click to display the Application Navigator context menu for a CARML file.

  3. Choose Generate ArisIDBeans.

    Description of igfdg_generate_beans.gif follows
    Description of the illustration igfdg_generate_beans.gif

  4. In the Generate ArisIDBeans dialog, specify the Package.

    Description of igfdg_dialog_genbeans.gif follows
    Description of the illustration igfdg_dialog_genbeans.gif

  5. If you want to use a relation file, select Use Relations and specify or browse to the Relation File.

  6. Click OK.

    You can now incorporate these beans into your application.

3.4.1.4 How to Use the ArisID Beans in an Application

The Identity Governance Framework ArisID API extension to JDeveloper initially creates the ArisId beans. These beans are from a developer perspective, like any other Java bean. They can be called from any Java application using standard bean semantics. This enables more interesting use cases depending upon the framework a developer wants to use.

For example, if building an ADF (Oracle's Java-based Web application framework), the beans can be converted into a Data Control and dragged into an ADF page. This enables developers to quickly wire applications together that utilize the bean - either for searching, updating or displaying on a page - without having to write a single line of code.

Another use case is a developer who wants to expose identity data as a Web Service from Oracle SOA Suite. In this case, the beans could be accessed using a Java call-out instead of using a DSML query against a directory server, such as Oracle Virtual Directory or Oracle Directory Server Enterprise Edition. This can be easier to construct and more efficient because there is less XML parsing being utilized in the SOA process.

By focusing their efforts on describing objects and attributes and worrying less about specific protocols, developers can be more productive in accessing identity information. Because ArisID has privacy and security built-in, this can be done in a secure, standards compliant way.

3.4.1.5 Editing the Mapping File

The Oracle implementation maps CARML declarations to an LDAP-based server, such as Oracle Virtual Directory. The mapping editor enables you to map CARML attributes to LDAP attributes, objectclasses and search parameters. You can customize your mapping file for the LDAP-based server at your site. LDAP terms are defined by the Internet Engineering Task Force in RFC's 2251 through 2256. For more information, see http://www.ietf.org.

To edit the mapping file:

  1. In the Projects pane, highlight the mapping file.

  2. Double-click to open the file in the mapping file overview editor.

    Description of igfdg_mapping_file.gif follows
    Description of the illustration igfdg_mapping_file.gif

  3. On the Mappings page, highlight an entity that you want to modify.

  4. Highlight a mapping definition you want to modify for that entity.

  5. Edit the RDN Attribute, Search Base, and Create Base if necessary.

  6. To add Objectclasses, Filter Objectclasses, Password Attributes, and Multilanguage Attributes, click the corresponding Add icon.

  7. Repeat Steps 3 - 6 for other entities that you want to modify.

  8. If necessary, change the Paging setting on the Global page.

3.5 Sample Application Using IDX User and Role Beans

The following sample application uses IDX User/Role Beans.

3.5.1 SearchUsers.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="org.openliberty.arisid.*"%>
<%@page import="org.openliberty.arisidbeans.*"%>
<%@page import="oracle.igf.userrole.*"%>
<%@page import="java.util.*"%>
<%@page import="java.net.URI"%>
<%!public static UserManager uMgr = null;
{
        try {
                uMgr = new UserManager(null);
        } catch (Exception e) {
                e.printStackTrace();
        }
 
}
%>
<html>
<head>
<title>Search Users</title>
<%
 
 
String firstname = request.getParameter("firstname");
String lastname = request.getParameter("lastname");
String telephone = request.getParameter("telephone");
 
 
List<PropertyFilterValue> attrFilters = new ArrayList<PropertyFilterValue>();
attrFilters.add(new PropertyFilterValue("firstname", firstname, AttributeFilter.OP_BGNSWITH));
attrFilters.add(new PropertyFilterValue("lastname", lastname, AttributeFilter.OP_BGNSWITH));
attrFilters.add(new PropertyFilterValue("telephone", telephone, AttributeFilter.OP_CONTAINS));
 
List<User> subjs = uMgr.searchUsers(attrFilters);
 
%>
</head>
<body>
 
<a href="SearchUsers.html">Home</a>
<center>List of Users with FirstName starting with "<%=firstname%>", LastName
starting with "<%=lastname%>" and TelephoneNumber containing
"<%=telephone%>"</center>
 
<%
Iterator<User> sIter = subjs.iterator();
while (sIter.hasNext()) {
        User subj = sIter.next();
 
        Map<String, IAttributeValue> vals = subj.getAllAttributes();
        Iterator<IAttributeValue> iter = vals.values().iterator();
%>
<table border="0">
        <tr>
                <th>Item</th>
                <th>Value</th>
        </tr>
        <%
                while (iter.hasNext()) {
                        IAttributeValue val = iter.next();
                        String name = val.getNameIdRef();
                        String value = null;
                        if (val.size() > 0)
                                value = val.get(0);
if (value != null)
{
        %>
        <tr>
                <td><%=name%></td>
                <td><%=value%></td>
        </tr>
        <%
}
                }
        %>
</table>
<%
        }
%>
<br>
<br>
<br>
<a href="SearchUsers.html">Home</a>
</body>
</html>

3.5.2 SearchUsers.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD><TITLE>Search Users</TITLE></HEAD>
<BODY>
<FORM METHOD=POST ACTION="SearchUsers.jsp">
 
First Name Starting with <INPUT TYPE=TEXT NAME=firstname SIZE=30><BR><BR>
Last Name Starting with <INPUT TYPE=TEXT NAME=lastname SIZE=30><BR><BR>
Telephone Number containing <INPUT TYPE=TEXT NAME=telephone SIZE=15><BR><BR>
<P><INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>