Write for OTN
Earn money and promote your technical skills by writing a technical article for Oracle Technology Network.
Learn more
Stay Connected
OTN Architect Community
OTN ArchBeat Blog Facebook Twitter YouTube Podcast Icon

Oracle Identity Manager: Implementing Additional Request Information

by Nitin Patel

Step-by-step technical instructions for implementing the Additional Request Information feature in Oracle Identity Manager

April 2013

Downloads
download-icon13-1Oracle Identity Manager
download-icon13-1SampleAdditionalReqInfoApp
download-icon13-1sandbox-AdditionalRequestInformat

Introduction

The Additional Request Information feature was made available in Oracle Identity Manager (OIM) as part of version 11.1.2.2.0 (R2PS2 release). The documentation related to this feature is available here. This feature is not available in the OIM UI by default (out of the box), and must be implemented by the customer. Implementation involves some amount of UI customization, which includes (but is not limited to) creating a sandbox for UI customizations, developing custom Application Development Framework (ADF) taskflows, and establishing the link between the two.

The aim of this article is to help OIM customers, consultants and anyone else who wants implement this feature, by focusing on the overall implementation approach, and developing a step-by-step sample implementation of this feature. The samples provided by this article include the sample sandbox zip, the Jdeveloper ADF application with source code, and the ADF library jar containing custom taskflow and managed beans (mBeans).

Note: This article assumes that the reader has good understanding of OIM, is comfortable with development using ADF, and is aware of all the aspects of OIM UI customization documented here.

Understanding the Additional Request Information feature implementation

At a high level, this feature provides the ability to specify additional information pertaining to a request (user operation), through UI customization. The additional information can be useful for request approval decisions or compliance. Please refer to the sample use cases that are documented as part of the "Use Cases" section towards the end of this document.

To implement this feature you must:

  1. Create a sandbox and perform UI customizations using Oracle Web Composer (OWC), to add custom components (command links or buttons) in the cart submission page.
     
  2. Develop and deploy a custom ADF bounded taskflow, which contains additional information to be collected during cart submission.
     
  3. Associate the custom taskflow created in B, above, with the custom components (command links) added as part of A, above.
     

Once the feature has been implemented, requesters can see the custom UI component (command link/button) in the cart submission page added in step A. Upon clicking the link/button, the custom ADF bounded taskflow deployed in step B is launched. Requesters can both specify the additional information displayed as UI input components in the taskflow as well as save the information. This information is saved as part of Request, and can be viewed by the requester (or other users who can view the request) by tracking the request. Approvers can view and edit the information entered by the requester, and take appropriate action on the corresponding approval task assigned to them.

A. Create a sandbox

Create a sandbox (as per the documentation) and perform UI customizations using Oracle Web Composer, to add custom components (command links or buttons) in the cart submission page. The steps are:

  1. Log in to the OIM self-service console as xelsysadm user.
     
  2. Create a role (e.g., role1), which will be published to the Top organization by default.
     
  3. Create and activate a sandbox (e.g., AdditionalRequestInformation).
     
  4. Navigate to Catalog, search role1 created above, add it to the cart, and click Checkout to proceed to the cart submission page.
     
  5. Click Customize to customize the cart submission page.
     
  6. Click the View dropdown under Editing Page: Identity Self Service and select Source.
     
  7. Edit Cart Details panelHeader, and add a commandLink component (for Additional Cart Information), as shown in Figures 1 and 2.
    patel-oim-request-info-fig01
    Figure 1
    patel-oim-request-info-fig02
    Figure 2

     
  8. Similarly, add another commandLink (for Additional Cart Item Information) inside the cart items table, as shown in Figure 3.
    patel-oim-request-info-fig03
    Figure 3


    Click the Remove button within the Display Name column of the Cart Items table, to quickly navigate to source in the composer, as shown in Figure 4.
    patel-oim-request-info-fig04
    Figure 4

     
  9. Click the Submit button on the cart submission UI to locate the corresponding source component in the composer. You will see commandToolbarButton: Update, which is already configured along with the Submit button, and is disabled by default, as shown in Figure 5.
    patel-oim-request-info-fig05
    Figure 5

     
  10. Select the disabled Update button and click Edit to open the pop-up showing the properties of the Update button. Within this pop-up, edit the show component property, which will show another pop-up with the default value as: #{backingBeanScope.cartReqBean.updateEnbled} (See Figure 6).
    patel-oim-request-info-fig06
    Figure 6

     
  11. Replace the Expression Language (EL) expression (highlighted in Figure 6) with True, so that this customization for the Update button is added in the sandbox. With this customization (show component = true), the Update button is also visible in the cart submission page; ensure that the value is modified to render the Update button based on a custom EL expression.

    Note: Take care while customizing the Update button; modifications will affect its default behavior, in terms of when the button is rendered. Skip this customization unless approvers are required to update Additional request information.
     
  12. Export the sandbox. We will be modifying the sandbox later (in the "Customize the sandbox" section, below).
     

B. Develop and deploy custom ADF taskflow

Develop a custom ADF bounded taskflow, and deploy it as part of oracle.iam.ui.custom-dev-starter-pack.war. This taskflow is supposed to contain all the additional Information to be collected during cart submission. Additionally, you can also develop and deploy any custom managed beans (see Developing Managed Beans and Task Flows) to contain custom logic for achieving such use cases as selectively displaying/hiding the link based on the cart items.

The steps below show you how to develop custom ADF artifacts required for achieving customization related to the "Additional Request information" feature, and how to deploy them as part of oracle.iam.ui.custom-dev-starter-pack.war. These instructions supplement the official documentation for this feature.

Develop an ADF View Controller project by following section 30.10.1 of the documentation . Refer to the steps/screenshots below if you get stuck.

  1. Create a Generic Application.
    patel-oim-request-info-fig07
    Figure 7

     
  2. Add a new ADF View Controller project to the application. Note: this sample uses the Default package oracle.iam.ui.custom.
    patel-oim-request-info-fig08
    Figure 8
    patel-oim-request-info-fig09
    Figure 9

     
  3. Add OIM libraries (OIM Client library, OIM Model shared library, OIM View shared library) and the ADF Model Runtime library to the project classpath.
    patel-oim-request-info-fig10
    Figure 10

     
  4. Define the deployment profile for the newly created ViewController project, with archive type as ADF Library JAR File, and a name (e.g., adflibAdditionalReqInfoPrj1).
    patel-oim-request-info-fig11
    Figure 11

     

So far, the steps we've performed are the same as those in 30.10.1 of the documentation.

The next set of steps show how to create a bounded ADF taskflow, which will contain the Additional information to be collected during cart submission. As part of this exercise we will:

  1. Create a sample bounded taskflow named "addnl-entitlement-info.xml".
     
  2. Create a page fragment called "additionalEntitlementInfo.jsff", part of this taskflow.
     
  3. Include the Additional Information to be collected during cart submission as part of the page fragment above. We will include Start Date and End Date fields to the page fragment for the sake of this sample, as well as Save and Cancel buttons, in order to save the Additional information entered by the user or to cancel/close the taskflow.
     
  4. Create two managed beans to be configured in the taskflow: AddnlEntitlementInfoStateBean and AddnlEntitlementInfoRequestBean. AddnlEntitlementInfoStateBean is configured at pageFlowScope, which holds the state of the jsff (Start Date and End Date fields). AddnlEntitlementInfoRequestBean is configured at BackingBean scope, and it holds action listener methods onSave and onCancel corresponding to the Save and Cancel buttons in the jsff.
     
  5. Create a Java class called Util.java, for defining any utility methods, and a HelperBean.java managed bean, for custom logic. The project structure looks like this:
     
patel-oim-request-info-fig12
Figure 12

The next set of steps show how to create each artifact that is part of the ADF View Controller project.

  1. Create a new ADF taskflow by right clicking Project, New > ADF Taskflow under <Project_dir>/public_html/WEB-INF. In the screenshot below, the taskflow addnl-entitlement-info.xml is created under the <Project_dir>/public_html/WEB-INF/oracle/iam/ui/custom/additionalInfo directory.
     
  2. patel-oim-request-info-fig13
    Figure 13
  3. Create two Java classes (Project > New > Java Class), which will be configured as taskflow managed beans in step 7 below. In addition, create another java class, Util, which has utility methods.
    1. The screenshot below shows an managed bean named AddnlEntitlementInfoStateBean, which is used to represent the state of the taskflow. That is, it contains the taskflow fields startDate and EndDate. Note that this class must implement the Serializable interface.

      This class also has a few other instance variables: requestFormContext and additionalRequestInfo, corresponding to the taskflow input parameters discussed in step 8, below. readOnly is a Boolean variable that determines whether the start date and end date fields in the jsff have to be read-only or editable. cartItemId is used as an index on the additionalRequestInfo object, to fetch additional information corresponding to the selected cart item (refer to the interface).

      This class has accessor methods generated for all instance variables. It also has a public initialize method, which determines and initializes the readOnly and cartItemId fields by using the requestFormContext object, and startDate and endDate fields using the additionalRequestInfo object.

      The public method called store updates the additionalRequestInfo object with the new/updated values for startDate and endDate fields. This method should be invoked when the Save button is clicked on the additionalEntitlementInfo.jsff page.
       
    2. patel-oim-request-info-fig14
      Figure 14
    3. Figure 15 corresponds to the AddnlEntitlementInfoRequestBean. This has a member variable called stateBean of type AddnlEntitlementInfoStateBean, which is injected due to the managed bean property configured in the taskflow (in step 7 below). Note that accessor methods are generated for this variable, using JDeveloper. The action listener method onSave invokes the store method defined in the state bean above, to save the state of the taskflow/jsff. It then hides the pop-up using the Util class described below. The action listener method onCancel hides the pop-up without saving the state.
       
    4. patel-oim-request-info-fig15
      Figure 15
    5. Figure 16 shows the Util class, whose utility method findParentComponent is used in the request bean above.
       

     
  4. patel-oim-request-info-fig16
    Figure 16
  5. Configure the state and request beans created above as managed beans in the addnl-entitlement-info.xml taskflow, as shown in the screenshot below. Note that stateBean is configured at pageFlow scope, and requestBean is configured at backingBean scope. Select requestBean and configure a managed property with the name stateBean, of type oracle.iam.ui.custom.AdditionalRequestInfo.AddnlEntitlementInfoStateBean and value '#{pageFlowScope.stateBean}'. This is in order to inject the stateBean into the requestBean.
     
  6. patel-oim-request-info-fig17
    Figure 17
  7. Define the mandatory taskflow input parameters additionalRequestInfo (class: oracle.iam.ui.common.model.catalog.requestdetails.AdditionalRequestInfo) and requestFormContext (class: oracle.iam.ui.platform.view.RequestFormContext), as shown in Figure 18. Store these input parameters within the corresponding member variables in the AddnlEntitlementInfoStateBean created above. This can be done using EL expressions #{pageFlowScope.stateBean.additionalRequestInfo} and #{pageFlowScope.stateBean.requestFormContext}. Note that stateBean used in the EL expression corresponds to the managed bean configured above.
     
  8. patel-oim-request-info-fig18
    Figure 18
  9. Open the addnl-entitlement-info.xml taskflow in design mode, drag and drop a Method call activity, and give it a name (e.g., initialize.) To mark it as default activity, right click Mark Activity > Default Activity. Double click on it and associate it with the initialize method present in the stateBean.

    Drag and drop a View component, and name it additionalEntitlementInfo. Double click on it to create a page fragment called additionalEntitlementInfo.jsff.

    Add a Control Flow Case between initialize and additionalEntitlementInfo activities, as shown in the design and source of addnl-entitlement-info.xml below:
     
  10. patel-oim-request-info-fig19
    Figure 19
    patel-oim-request-info-fig20
    Figure 20
  11. Double click to open the view/jsff, and include all the UI components (Start Date, End Date, Save, Cancel) as shown in the design and source of the jsff screenshot below:
     
patel-oim-request-info-fig21
Figure 21
patel-oim-request-info-fig22
Figure 22

Note: For the Start Date inputDate component, the readOnly property is set as #{pageFlowScope.stateBean.readOnly} and the value property is set as #{pageFlowScope.stateBean.startDate}. This binds this component and its properties to the variables in stateBean (AddnlEntitlementInfoStateBean). The same applies to the End Date component. Also note that the action listener property of the Save button is set to #{backingBeanScope.requestBean.onSave}, which binds it to the onSave method of requestBean.

Save all changes.

  1. Create a new Java class (e.g., HelperBean.java) that extends oracle.iam.ui.platform.view.backing.BaseMB. This class is used to achieve the use cases discussed in sections 30.11.5 and 30.11.6 of the documentation -- that is, to dynamically determine the following in the cart submission page:
    1. Whether to render the custom Additional Information link at the request/cart level.
       
    2. Whether to render the custom Additional Information link at the cart item level.
       
    3. Whether to render the Update button on the Approval details page, for the approver to update the Additional Information in the request and then approve the task.
       
    4. Determine which custom taskflow to launch as a pop-up at runtime, when the request/cart level link is clicked.
       
    5. Determine which custom taskflow to launch as a pop-up at runtime, when the custom link against a specific cart item (in the cart items table) is clicked.
       
    To achieve use cases like these, a custom managed bean can be developed, as shown in the screenshot below. A few key methods of this class include:
    1. initialize: This method initializes the requestFormContext instance variable of type oracle.iam.ui.platform.view.RequestFormContext, using the following code:

      requestFormContext = RequestFormContext.newInstance(null).getCurrentContext();

      All the other helper methods can call this method to initialize the requestFormContext, which can then be used to get the context related to the current cart/request.
       
    2. isRenderAdditionalDetailsForRequest: This method can be used to determine if the Additional Information link must be shown at the request/cart level.
       
    3. isRenderAdditionalDetailsForCartItem: This method can be used to determine if the Additional Information link must be rendered for the current cart item.
       
    4. isRenderUpdateButton: This method can be used to determine if the Update button must be shown on the approval details page.
       

     
patel-oim-request-info-fig23
Figure 23

Figure 24 captures the code for a few methods. Note that data available to achieve the required customization is already covered in sections 30.11.5 and 30.11.6 of the product documentation. cartItemDataMap, pageFlowScope, etc., are covered there as well.

patel-oim-request-info-fig24
Figure 24
  1. Configure the HelperBean class created above as an managed bean (at backingBean scope) inside the project's adfc-config.xml, as shown in Figure 25.
     
patel-oim-request-info-fig25
Figure 25

Note that this bean (and any of its public methods) can be referred within any EL expression using the name additionalInfoHelperBean. For example: #{backingBeanScope.additionalInfoHelperBean.renderUpdateButton}

  1. Save all the changes and then deploy by right clicking Project > Deploy and selecting adflibAdditionalReqInfoPrj1. Click Finish to complete the deployment. Upon successful compilation and deployment, a jar like this is created: <JDEV_WORKSPACE>/AdditionalReqInfoApp/AdditionalReqInfoPrj/deploy/adflibAdditionalReqInfoPrj1.jar
     
  2. Once the ADF library jar is built, deploy it as part of oracle.iam.ui.custom-dev-starter-pack.war, as documented in section 30.10.4 of the documentation.
     

Secure the Custom Taskflow

Follow section 30.5.1 of the documentation to add permissions to the custom taskflow(s) using Authorization Policy Manager (APM).

Note that the sample taskflow built as part of the exercise so far is: /WEB-INF/oracle/iam/ui/custom/additionalInfo/addnl-entitlement-info.xml#addnl-entitlement-info

oracle.adf.controller.security.TaskFlowPermission to customize or view the resource name /WEB-INF/oracle/iam/ui/custom/.* is already seeded out-of-the-box, so there is no need to add any new permissions to the sample taskflow.

C. Customize the Sandbox

In this step, we'll customize the sandbox created and exported as part of Step A, above. This step is required to establish a link between the custom UI components and the custom taskflows deployed as part of Step B.

  1. After completing the steps in A, you should have exported a sandbox zip file. Let's call this a "base sandbox," which captures just the customizations performed through the UI composer. If you extract the zip and look at the cart-details.jsff.xml file, it should have mds:insert and mds:modify tags similar to this:
     
<mds:insert parent="ph1" position="last">
  <af:commandLink xmlns:af="http://xmlns.oracle.com/adf/faces/rich" id="e9847224848"
   shortDesc="Additional Cart Information" text="Additional Cart Information"/>
</mds:insert>
<mds:insert parent="pgl4" position="first">
  <af:commandLink xmlns:af="http://xmlns.oracle.com/adf/faces/rich" id="e2712655339"
   text="Additional Cart Item Information" shortDesc="Additional Cart Item Information"/>
</mds:insert>
<mds:modify element="ctb2">
  <mds:attribute name="rendered" value="true"/>
</mds:modify> 

Ensure that the file contains all three customizations: the addition of two new commandLinks, and the modification of the Update button.

  1. Using the documentation, edit this base sandbox to associate the custom UI components to the custom taskflows developed in step B. Make the following changes to the cart-details.jsff.xml file in the base sandbox zip:
    • Set the actionlistener property for both the commandLinks to this exact value:
      actionListener="#{catalogRequestBean.launchAdditionalRequestInfoTaskFlow}"
       
    • Set the clientAttribute for both the commandLinks. The value for the taskFlowId attribute should be a fully qualified taskflow name. In this sample, we set the taskflowId attribute to an EL expression:
      #{backingBeanScope.additionalInfoHelperBean.additionalInfoTaskFlowIdForCartItem}

      This EL expression invokes the getAdditionalInfoTaskFlowIdForCartItem method of HelperBean class developed and deployed as part of the ADF library jar. This method returns the following as the taskflowId: /WEB-INF/oracle/iam/ui/custom/additionalInfo/addnl-entitlement-info.xml#addnl-entitlement-info
       
    • Modify the value of the rendered attribute for the Update button (under ). Note that a value of "true" means that this button would be seen during request creation/details and approval details taskflows. To avoid this, you should add an EL similar to one in the sample sandbox:
      #{backingBeanScope.additionalInfoHelperBean.renderUpdateButton}

      This EL expression invokes the isRenderUpdateButton method of HelperBean class developed and deployed as part of the ADF library jar. This method returns "true" only for the approval update flow, so that the button is not rendered for other flows.

       

     
  2. As a result, the sample cart-details.jsff.xml file looks like this:
     
<?xml version='1.0' encoding='UTF-8'?>
<mds:customization version="11.1.1.64.93" xmlns:mds="http://xmlns.oracle.com/mds" 
motype_local_name="root" motype_nsuri="http://java.sun.com/JSP/Page">
   <mds:insert parent="ph1" position="last">
      <af:commandLink xmlns:af="http://xmlns.oracle.com/adf/faces/rich" id="e81172800" 
	  text="Additional Cart Information" 
	  actionListener="#{catalogRequestBean.launchAdditionalRequestInfoTaskFlow}" 
	  rendered="false"/>
   </mds:insert>
   <mds:insert parent="pgl4" position="first">
   	<af:commandLink xmlns:af="http://xmlns.oracle.com/adf/faces/rich" id="e5139681203" 
	text="Additional Cart Item Information" 
	actionListener="#{catalogRequestBean.launchAdditionalRequestInfoTaskFlow}" 
rendered="#{backingBeanScope.additionalInfoHelperBean.renderAdditionalDetailsForCartItem}">
	   <af:clientAttribute xmlns:af="http://xmlns.oracle.com/adf/faces/rich" 
name="taskFlowId" 
value="#{backingBeanScope.additionalInfoHelperBean.additionalInfoTaskFlowIdForCartItem}"/>
           <af:clientAttribute xmlns:af="http://xmlns.oracle.com/adf/faces/rich" 
name="dialogTitleIcon" value="/images/request_ena.png"/>
           <af:clientAttribute xmlns:af="http://xmlns.oracle.com/adf/faces/rich" 
name="headerText" value="Additional Cart item Information"/>
	   <af:clientAttribute xmlns:af="http://xmlns.oracle.com/adf/faces/rich" 
name="dialogTitle" value="#{backingBeanScope.additionalInfoHelperBean.popupTitle}"/>
	</af:commandLink>
   </mds:insert>
   <mds:modify element="ctb2">
      <mds:attribute name="rendered" 
	  value="#{backingBeanScope.additionalInfoHelperBean.renderUpdateButton}"/>
   </mds:modify>
</mds:customization>
Notes:
  • The rendered property of the 'Additional Cart Item Information' link is set to an EL expression as follows:
    rendered=""#{backingBeanScope.additionalInfoHelperBean.renderAdditionalDetailsForCartItem}

    This EL expression invokes the isRenderAdditionalDetailsForCartItem method of HelperBean class developed and deployed as part of the ADF library jar. This method holds the logic to return "true" only if the role name is role1.
     
  • The rendered property of Additional Cart Information link is set to "false". This means that the link would never be displayed at the request/cart level. Use an EL expression, as above, to dynamically determine whether to render the link.
     
  • Use similar EL expressions for other properties, provided the corresponding methods are implemented in the HelperBean class, or any other backingBean scoped custom managed bean.
     
  1. Re-create the modified base sandbox zip, import it in OIM, and activate it.
     

Use Cases

Try out the following use cases by logging in as xelsysadm user:

  1. Add access to roles (e.g., role1 and role2), and see that the Additional Cart Item Information link is visible in the cart submission page, for role1 alone.
     
  2. Click the Additional Cart Item Information link in the cart items table to see that the custom taskflow is launched as a pop-up. Provide values for start date and end date fields in the form (Figure 26).
     
patel-oim-request-info-fig26
Figure 26
  1. Submit the cart successfully.
     
  2. In the request summary page, click on the links and ensure that the values provided during request creation are visible (Figure 27).
     
patel-oim-request-info-fig27
Figure 27
  1. Open Inbox, and click the approval task created for the above request.
     
  2. Claim it, and see that the additional information provided at cart item level (for role1) are visible and editable (Figure 28).
     
patel-oim-request-info-fig28
Figure 28
  1. Ensure the Update button is visible. Edit some of the values, and click on the Update button. Approve the task.
     
  2. Open Request Details and ensure that it reflects the updated values for additional attributes updated by the approver.
     
  3. The same sample taskflow would be launched for other use cases, such as Provision/Revoke entitlement.
     
  4. Try a use case that involves adding access to heterogeneous entities (roles, entitlements). Ensure the additional request details are stored at the bulk request level, and are propagated to child requests later on, after approvals.
     
  5. Access Request Web Service (/reqsvc/reqsvc), and invoke the getRequestDetails operation to get the request details for any of the requests created above. Ensure that the additional information is returned by the web service method.
     

Conclusion

This article demonstrates how the Additional Request information feature can be implemented in OIM (11.1.2.2.0). As part of this exercise, we developed a single custom bounded taskflow, and used the same taskflow to specify additional information for role- and entitlement-related requests. A similar approach can be used to develop and deploy multiple custom taskflows, based on the requirement, to achieve customizations mentioned in sections 30.11.5 and 30.11.6 of the documentation.

References

  1. This article refers to the Oracle Identity Manager documentation for UI customization.
     

About the Author

Nitin Patel is a member of the Oracle Identity Manager development team, contributing to areas like Application server security and integration with Single sign-on solutions, apart from OIM server and UI development. He earned his B.Tech. from BITS Pilani.