Quantcast
Channel: oim – ATeam Chronicles
Viewing all 54 articles
Browse latest View live

Simplifying OIM 11g Series (Chapter One)

$
0
0

Introduction

This is the first one in a series of posts dedicated to the design of tools that have the common goal of simplifying or enhancing the functionality provided by OIM 11g. As more and more customers implement OIM 11g, new challenges arise and new issues are uncovered. OIM 11g is a very powerful platform but given the complexity of the problems OIM tries to solve, we have to admit that the product itself is sometimes not the easiest to implement by customers. The tools described in this series of articles have the purpose of facilitating the implementation of advanced capabilities of OIM or enhance some of the features of OIM making them capable of fulfilling certain use cases that have been traditionally complex to implement (but nevertheless, always possible).

In this article we will cover the design of a framework that allows business users to define provisioning processes that include approvals, sophisticated approval request routing and advanced user interface customization capabilities. A reference implementation of this framework will be presented in subsequent posts along the series.

Main Article

OIM 11g defines two types of processes: Provisioning and Approval Processes. Provisioning processes are defined in OIM’s Design Console, whereas the Approval Processes are implemented in Oracle’s SOA Suite via SOA Composites and BPEL. As you can imagine, customers now have to deal with the intricacies of BPEL and the corresponding tools set. In some cases, the customers don’t have the necessary skills set to be able to customize Approval processes to fulfill complex use cases. This tends to produce less than desired results because – if best practices are not followed properly – there is a strong chance that the end solution won’t perform as expected. Now, due to the fact that Approval processes are defined using SOA Suite artifacts, only experienced developers that understand JDeveloper will be able to implement any required customizations to the processes. Moreover, Approval Processes are the ones that are mostly associated to the business, so Business Users should be able to define the proper approval flows that make sense to their business.

So the idea here is to design a set of tools that can be run on top the OIM 11g’s engine that will allow business users to define provisioning processes and approval flows. In order to achieve this, the tool kit needs to have the following:

A set of components that will perform tasks required by the framework including:

  • The GUI that Administrators and/or Business Users can use to define provisioning processes.
  • A Pre-Populate adapter that supports multi-value attributes.
  • A SOA Composite that will execute provisioning tasks and request application roles used to provision resources (this will be explained in detail later on).
  • An XML Schema to represent provisioning process definitions in XML.

A set of hooks where developers can implement extensibility interfaces to extend the functionality of the framework and can be deployed through the interface mentioned above.

Framework Components

The first thing to be addressed is the definition of the components in the framework. So the best way I know to start defining such components is to make a list of the tasks that are part of a provisioning operation, here they are:
  • Capture User Data
  • Route Approval Requests
  • Provision Approved Resources

Capture User Data

In this case the method used to capture data is via forms. Whereas OIM allows for the definition of input forms these apply to resource objects that are to be provisioned. OIM has the following process to configure request based provisioning:
  • Connectors define a Data Set which could potentially be customized. A data set is an XML file that contains the definition of the fields displayed in an input form including the UI element used to capture the value for the field and other metadata that indicates to whom the field is visible, the type of value it accepts and whether it is mandatory or not.
  • The Data Set has to be imported into MDS to be usable for Request Based Provisioning. This is not done at the time the connector is installed, it is done afterwards. The reason for this is that Data Sets can be customized to fulfill particular requirements so it would not make sense to import a dataset by default until customers are certain that the out of the box Data Set will address their needs.
  • A provisioning form is still required for entering the data for the request. This is the input form that OIM allows administrators to design and it is used for the actual resource provisioning. This form can be pre-populated with information coming from a variety of sources, including OIM’s user profile attributes. This is one of the capabilities we intend to leverage in our solution with a few tweaks.
  • If the provisioning of a resource is subject to approval, then a request template configured with the proper approval process is necessary. This is also dependent on the data sets for the resources being imported to MDS.
As made evident by the description above, OIM has a bit of a complex setup when it comes to self-service request based provisioning. Even though the complexity is sort of justified for the sake of flexibility and feature richness, it can easily get out of hand. So the approach I am going to follow to simplify this configuration is the following:
  • In order to prevent administrators from having to import datasets to MDS just to be able to request a resource object I am going to use access policies in combination with out of the box roles and a customization used to manage multi-value attributes in OIM’s User profile.
  • There are already out of the box request templates to self-request role assignment which don’t need importing a data set. So I intend to leverage those templates for my implementation.
  • A specialized composite will be written to execute my version of a provisioning process which internally will generate requests for roles associated to each requested resource.  An approval process that can be easily defined by business users through a provided user interface will be executed by a customized SOA Composite generated using OIM 11g’s command line tools (I call this composite OIM’s Composite). OIM’s Composite invokes a Web Service that generates a representation of an approval routing in XML which is read by the configuration of the participants of the composite’s Human Task. This representation is generated based on the specification of the approval process defined by the business users.

Route Approval Request

As part of any provisioning process, approvals may be and are often required. An approval process that can be easily defined by business users through a provided user interface will be executed by a customized SOA Composite generated using OIM 11g’s command line tools (I call this composite OIM’s Composite).
OIM’s Composite invokes a Web Service that generates a representation of an approval routing in XML which is read by the configuration of the participants of the composite’s Human Task. This representation is generated based on the specification of the approval process defined by the business users.
In this manner Business Users don’t need to be experts in JDeveloper or even need a developer to implement approval flows because these can be defined using an intuitive user interface. These descriptors are stored on the file system so if working with a cluster of OIM Servers they need to be available on all servers, but this requires only copying the files and that’s it; no server restarts are necessary.

Provision Approved Resources

Since all we are doing is leveraging OIM’s advanced capabilities for automatic provisioning this is taken care of by the access policies and potentially a pre-populate adapter to support multi-value attributes.
The idea is to have a role associated to each Resource Object/IT Resource combination so a policy can easily be defined for the automatic provisioning of a resource object instance connected to an IT Resource target. If child forms need to be populated the custom pre-populate adapter will take that information from a special table (part of this framework) that extends the user profile of OIM to support multi value attributes.

Summary

This first article describes a framework that has the goal of simplifying the use of OIM 11g’s features in customer implementations. The article only covers the design of such framework, while subsequent posts will cover a reference implementation of the components described here that customers and partners can leverage to build a tool kit targeted to make OIM 11g implementations simpler.
 

Simplifying OIM 11g (Chapter Two)

$
0
0

 

Introduction

This is the second article in a series of posts with the common goal of providing customers with ideas and techniques that can be used to simplify the use of advanced features of OIM 11g. In Chapter One of this series, we described the components of a framework that would allow users at all levels to configure OIM 11g features like Provisioning and Approval Processes, Approval Routing Functions and Custom User Input Forms. In this second article I will start talking about a reference implementation of the components of the framework described in Chapter One.

Main Article

The components that will be covered in this article are:

  •          User Input Forms for OIM user creation and resource request.
  •          Approval Flow Design Interface
  •          Approval Flow Execution Agent Service

The above mentioned components comprise the part of the framework that takes care of Provisioning including the specification of approval flows that will be executed by the custom composite application described in chapter one, which will be the approval process for the Self Assign Roles request template which is out of the box and doesn’t need additional dataset configuration and importing to MDS.

Foundation Components

Before delving into details about the implementation of the higher level components, there are some elements that we need to put in place to support the implementation of the higher layer components. So, we will start by defining the infrastructure elements needed as a foundation for the implementation:

·        

Database Tables:

o    Multi-valued User Profile Attributes: OIM_EXT_MV_UPATTR

o    Approval Flow Definitions: OIM_EXT_APPR_FLOW_DEF

o    Custom User Input Forms: OIM_EXT_CUSTOM_FORMS_DEF

Web Services:

o    Approval Flow Execution Service

o    Database Persistence Services

OIM Custom Adapters

o    OIM Multi Valued Pre-Populate Adapters

Once these components are created, and we will discuss the structure of each one of them, then the higher level components can be implemented. These include the following:

  •         Approval Flow Design UI
  •         Custom User Input Form Design UI
  •         Custom User Input Form Rendering and Execution engine

While the goal here is to describe a reference implementation of the framework, it is just that, a high level description of the architecture and the elements that need to be built and the responsibilities of each element/component. The audience can take these descriptions and come up with their own actual implementation. Since this is a framework, once it is built, it can be reused and evolved over time to meet more specialized requirements.

Foundation Components Specification

Now I will start discussing the design and specification of the Foundation Components listed in the previous section.

Database Tables

This section describes the schema of the tables that will support the functionality of the provisioning components of the framework.
Table OIM_EXT_MV_UPATTR
Description: This table stores the values of multi-valued attributes of OIM user profiles. This table extends the USR table to support user defined attributes as multi-valued.
Structure:
Name
Type – Length
Description
USR_LOGIN
VARCHAR(20)
This field contains the login id of the user whose profile contains the multi-value attribute.
USR_LINK_KEY
VARCHAR (6)
This field links the values of an attribute to the specific user profile.
USR_LINK_FLD_NAME
VARCHAR(30)
The name of the Field. This is the same value as the FIELD_ID column of table OIM_EXT_CUSTOM_FORMS_DEF described later.
USR_LINK_VALUE_ID
INT
This field contains the index of the values. This is also part of the primary key.
USR_LINK_FLD_VALUE
CLOB
Stores individual values in a sequence of values for the multi-value attribute.
USR_LINK_FLD_SIZE
INT
The amount of characters allowed in the field values.
USR_RO_NAME
VARCHAR(30)
The name of the Resource Object whose process form contains a child table that holds the values for this multi-value attribute. This field may be NULL if the multi-value attribute is not associated to any Resource Object.
USR_RO_CHD_TABLE
VARCHAR(30)
The name of the Child Table where the attribute values will be contained.
Table OIM_EXT_APPR_FLOW_DEF

Description: This table stores the definitions of approval flows. Basically the required data for these processes is merely the login IDs of users that should receive requests for approval. The structure of the table supports sequential approvals, parallel approvals and escalations.

Structure:
Name
Type – Length
Description
PROCESS_KEY
VARCHAR (6)
This is a unique ID for the process.
PATH_ID
INT
This field stores the sequence number of approval routes in an approval flow.
APPROVAL_SLIP
VARCHAR(500)
The field contains either a single Login ID or a comma separated list of login IDs which represents the list of approvers that will receive the request in the way determined by the ROUTING_TYPE.
ROUTING_TYPE
VARCHAR(20)
The type of Routing for the request. Valid values are: SEQUENTIAL or PARALLEL.
ESCALATION_TIME
VARCHAR(20)
This is the time it will take for the approver to process the request before it gets escalated. The value is formatted according to the W3C notation for durations. Example: P1D (means after one day or no response for the task). If NO-LIMIT is specified then the escalation policy will be set P365D (1 year).
ESCALATION_USER
VARCHAR(20)
The Login ID of the user this will be escalated to.
TERMINAL_APPROVER
VARCHAR(3)
This value indicates if this approver’s response terminates the approval flow immediately. Legal values are ‘Yes’ and ‘No’.
Table OIM_EXT_CUSTOM_FORMS_DEF
Description: This table contains the definitions of custom user input forms that are customizable via XSL style sheets. The contents of this table will be generated through a GUI created for this purpose.
Structure:
Name
Type – Length
Description
FORM_ID
VARCHAR (30)
This is a unique ID for the FORM.
FIELD_ID
VARCHAR(30)
This is a unique ID for a FORM Field.
FIELD_TYPE
VARCHAR(30)
The value of this field represents the HTML control that will be used to input the value of the field.
FIELD_IS_MV
VARCHAR(3)
Flag that indicates whether the field is Multi-Valued or Single Valued. Allowed values for this field are ‘Yes’ and ‘No’.

Web Services

In this section I describe the functionality provided by a couple of web services part of the framework’s implementation. Let me start by explaining the reason why web services are included in the picture. In OIM 11g, all operations associated to Approvals are carried out through Oracle’s SOA Suite. Some of the components that can be most naturally included in SOA Composite applications which represent Approval Processes in OIM 11g are Web Services. So not having Web Services would not make any sense at all. Also, the main purpose of emphasizing this point is to discourage the use of embedded Java in SOA composites specially when the implementation assumes that requests may not be approved for weeks at a time; I have come across some customers that have used OIM APIs in Embedded Java Tasks and have experienced PERM Gen issues on the SOA Server.

Approval Flow Execution Web Service

This web service provides the functionality of executing approval flows. Basically all it does is returning the next approver in line for a multi-approver request flow. The web service output includes the following:
  •          Single Approver in turn
  •          List of Approvers in a parallel flow
  •          Approver for escalated request
The nextApprover value returned by this web service call is placed in the owner field of the human task for the next approval. The web service also returns the status of the approval flow to determine whether further routing must take place or the end of the approval flow has been reached. The composite will evaluate all these values to determine the appropriate flow.

Database Persistence Service

This web service will be generated out of entities associated to the above mentioned database tables. JPA entities will be created and a Session Bean will act as the session façade for the entity beans generated out of the database tables. The persistence service will be invoked from the various GUIs used to define Approval Flows, Input Forms and other framework configuration elements.

OIM Custom Adapters

We have several options for the implementation of adapters that will deal with the multi-value attributes in a user profile. So the easiest way in my view to implement this is to have a post-insert entity adapter that will do the following:
  • Extract the names of the attributes associated to the user in question by querying the OIM_EXT_MV_UPATTR table for the User Login Name of the user in question. The reason why we do this search if because at a given time a user may not have all the attributes populated, so only the attributes that have been populated are processed.
  • Extract the key of each custom multi-value attribute from the user profile. The value is used to link the user profile with the OIM_EXT_MV_UPATTR extension table containing the values for each multi-value attribute of each user.
  • Extract the values of each multi-value attribute that is populated for the user in question using the key obtained above.
  • Populate the corresponding child tables potentially linked to each attribute. The information required to call these API’s is stored in table OIM_EXT_MV_UPATTR for each user.

Summary

I intended to present a potential implementation of multi-value attribute support and a mechanism to simplify the request process and potentially provide a more flexible customization mechanism. In the next chapter of the series we will discuss the implementation of the configuration GUI’s and the design of the customization mechanism for the input forms based on XML/XSLT transformations.

OIM 11g R2 & X.509 authentication

$
0
0

Introduction

OIM 11g R2 is out! This release brings a lot of new features and also improvements to existing features.

OIM authentication providers are among the ones that were improved. The improvements make easier to integrate OIM with SSO solutions (for both SSO products and custom SSO solutions).

The integration with OpenSSO is documented here. The integration with OAM is still a powerful solution for SSO and password management and it is documented here.

The improvements also bring the support to X.509 based user authentication. In previous 11g release, one would need to leverage a SSO solution like OAM to do such authentication. In R2, X.509 authentication can be directly configured in WebLogic. This post describes how to configure this authentication.

Main Article

But before starting, as a disclaimer, it is important to mention that this post does not give any recommendation or best practices, it just describes how one can configure X.509 authentication using WebLogic/OIM. The decision on what authentication mechanism shall be used and how such authentication will be achieved depends on business requirements like SLA, security and others.

The post also does not dive into the concepts around X.509 certificates and how they are used for end user authentication.

In order to achieve this authentication, the OIM WebLogic managed server must be configured with SSL. Another requirement is to have the OIM user login as the ‘CN’ field in the certificates issued to the end users.

The first step to achieve X.509 authentication is to import into the WebLogic trusted store the certificate chain that will be used. The root CA certificate must be imported as well as the intermediate certificates if any. This example uses a root certificate only (no intermediate certificates) and the default WebLogic keystore. The screenshot below depicts the use of ‘keytool’ command line to import the CA root certificate:

importing_cert

The next step is to configure WebLogic server to request certificate on SSL connections. This configuration is done directly in the OIM managed server through the WebLogic administration console. On the left menu click on ‘Environment > Servers’, then on the main page click on ‘oim_server1′, then click on ‘SSL’ tab and on the ‘Advacend’ link that shows up in the SSL configuration page. The screenshot below shows the section that must be configured.

ssl_1

With the configurations above, whenever a request reaches the SSL port in the managed server, a certificate will be request. Keep in mind that, depending on how it is configured, it may break the SOA-OIM communication, so when configuring this make sure that OIM managed server is also listening on non-SSL port and that SOA is using this port to communicate to OIM.

The next step is to configure the WebLogic authentication providers to understand that there is a certificate in the request and that the user information must be extracted from this certificate. On the left menu, click on ‘Security Realms’ and then ‘myrealm’. Click on ‘Providers’ tab and then in the ‘Reorder’  button. Reorder the authentication providers to the order shown in the picture below.

ssl_2

Now the ‘DefaultIdentityAsserter’ needs to be configured to assert the username from the X.509 certificate. Click on ‘DefaultIdentityAsserter’ and then on ‘Active Types’ section, move the ‘X.509′ from the  ‘Available’ list to the ‘Chosen’ list and save it. The screenshot below depicts this action.

ssl_3

And as last step, some details need to be configured in the ‘DefaultIdentityAsserter’. Click on ‘Provider Specific’ tab. The following fields must be configured:

  • ‘Default User Name Mapper Attribute Delimiter': in this example this must be blank as there is no delimiter in the username field (CN).
  • ‘Default User Name Mapper Attribute Type': this example uses CN as username attribute
  • ‘Use Default User Name Mapper': this must be checked as this example uses the mappers shipped along with WebLogic.

The picture below shows this configuration:

ssl_4

The certificate used in this example was issued to ‘xelsysadm. The picture below shows the subject details:

ssl_5

With the configurations above, one should be able to access OIM using X.509 certificate.

Of course there is a lot of different configurations that can be done to achieve the same result. It is possible, by using custom username mappers, to extract the username from different certificate fields. it is possible to configure WebLogic managed server to allow SSL connections without certificates, in this case the request will fallback to the standard OIM authentication.

Patch Management of an Oracle Identity Management Deployment

$
0
0

Introduction

Today I’d like to discuss a very important topic which is patch management in an Oracle IDM/IAM deployment.  Patching seems like a pretty basic topic.  It is often taken for granted.  However, experience has shown me that patching is a frequent source of confusion for many enterprise software customers including those deploying the Oracle Identity Management  stack.

So, I thought I’d address some common questions / topics related to patching so that people have a better understanding of what patches to apply to their environments and when to apply them.

This post is a part of both the OAM 11g academy and OIM 11g academy series.

Main Article


Patches, Bundle Patches, Patch Sets and New Releases

The first thing I’d like to do is clear up some terminology that is frequently a source of confusion for Oracle Middleware customers.  There are four delivery mechanisms for updating Oracle Fusion Middleware software.

New Releases:

New releases are major updates to software.  New releases always include major feature enhancements and can often include new ways of doing existing functionality and even complete new code basis.  Moving to a new release can sometimes be characterized as an upgrade but other times should be considered a migration where the old and new versions of software coexist side-by-side and certain applications, users, or functionality move from the old version of the software to the new release over time.

Patch Sets:

The topic of what exactly a patch set constitutes in Fusion Middleware land is somewhat controversial but I’d like to throw out some practical guidelines based on my experience.

For starters, patch sets are applied at the package level.  To review, there are two major packages in the IDM stack today: 1) the IDM package containing OVD, OID, and OIF and 2) the IAM package containing OAM, OIM, and OAAM.

Patch sets can be packaged as full installs, upgrades using the Oracle installer, or both.
To me, patch sets constitute minor new releases.  They may contain new functionality and may require some “post application” steps to complete the upgrade.

Patch sets should be fully tested in the context of a customer specific deployment before being moved into production.

Bundle Patches:

Bundle patches are sets of patches that fix multiple issues that are applied primarily through the OPatch utility.  Bundle patches usually do not contain new features and require few if any manual post application steps.

Bundle patches should also be tested in the context of a customer specific deployment before being applied to production systems but should be considered lower risk than patch sets.

One-Off Patches:

One-off patches are patches for individual issues or very small sets of issues.  They are often issued to individual customers only.

What patches should I apply?

Now that we’ve cleared up terminology I’ll give some guidance on what patches one should be looking to apply.

In terms of patch sets.  I recommend that you apply the latest patch set for the release you are installing when doing a new deployment with the caveat that all the software being installed into one Fusion Middleware Home (or WebLogic domain) must be running compatible versions.  I discuss the issue of compatible versions extensively in my articles on domain architecture.

Beyond that, I strongly recommend that customers apply the latest bundle patches for every Oracle Identity Management product they are installing unless they have an explicit reason not to.

OAM, OIM, OIA, OAAM, and OES, have official bundle patches.  There are good support articles detailing the bundle patch histories of each product with links to the bundle patches available.  I wrote about these support articles here.  The link given to the OAM article is still valid.  The link given to the OIM article is for 11.1.1.3 only.  There is a separate article (1360009.1) for OIM 11.1.1.5.

The situation is a little trickier for OID, OVD, and their management application ODSM.  Traditionally these components have only been patches through one-off patches.  However, recently (what I like to call) pseudo bundle patches for these components have emerged for Fusion Apps build outs.

Even though these pseudo bundle patches are listed as Fusion Apps only, the earliest version of these patches was also recommended for non-FA deployments in the IDM Enterprise Deployment Guide.  Based on this fact and the content of the patches, I recommend that customers seriously consider applying the latest OID, OVD, and ODSM pseudo bundle patch.

You can find the specific IDs for these patches in the Fusion Application release notes (1355561.1).  Early versions of these patches were also mentioned in the 11.1.1.5 IDM EDG.

At the time of this article, the current versions of these patches seem to be:

12937765 for OID 11.1.1.5.   This is the same patch recommended in the 11.1.1.5 EDG.

13031079 for ODSM 11.1.1.5.  This is a more updated version of the ODSM patch recommended in the EDG.

13031196 for OVD 11.1.1.5.  This is a more updated version of the OVD patch recommended in the EDG.

If you are doing an FA install or EDG style build out with OAM/OIM integration.  It is also important that you apply the IDM Tools patch for the ‘IDM Config Tool’.  The idmConfigTool is a command line utility used to automate portions of an OAM/OIM deployment.  It is very important that you apply the recommended patch for this tool before trying to use it.

Unfortunately, the guidance on what patch ID to apply for the IDM Tools for non-FA installs is a little weak.  My current recommendation is to apply the most recent patch available for the version of OAM/OIM that you are installing (11.1.1.5 or 11.1.2).  If you have trouble identifying the right patch then I encourage you to reach out to support.

When should I apply patches in a new deployment?

In general, you should apply patches in a new build out after you have installed the software components you are deploying but before you create, extend, and configure the WLS domains.  Likewise, you should apply patches before creating instances for OID, OVD, and OHS.  It should be noted that my recommendation is in line with the sequence of events documented in the IDM EDG and more updated IDM EDG for FA.

Now, I’m not saying that you have to re-install if you don’t follow this order.  However, installing the patches this early is a good idea for a few reasons:

1) There could be fixes to the configuration wizard or other configuration tools that are present in the patch.  Applying the patch up front lets you take advantage of these fixes.  Again, this is especially important with the ‘IDM Config Tool’ patch.

2) It’s easier to apply the patches up front as you don’t have any services running that require starting and stopping.

3) If you apply the patches up front then you don’t have to worry about never getting around to it.  Too often I have seen customers continue to delay applying patching during their build outs to the point they go into production without patches that are strongly recommended.

How often should I apply new patches?

The short but obvious answer is as often as possible.  I will say that all too often I see customers struggle with issues that have already been fixed in available bundle patches.  All software includes bugs and as good as Oracle Middleware software is, it is no exception.  Applying regular bundle patches should be considered part of the cost of doing business for your business and the apps that leverage the Oracle IDM stack.

I’d love to see customers apply every bundle patch but I know that many won’t be able to meet that goal.  So, for those that can’t or won’t apply every bundle patch I’d ask you to consider a policy of applying every other patch.  This should put you in the ball park of applying bundle patches every 6-9 months.  I think that is a reasonable thing to suggest.

How to tell what patches have been applied to an environment?

The answer is run ‘opatch lsinventory -all’.  You can read my full blog post on this subject here.

OAM and OIM 11g Academies

$
0
0

Introduction

As many of you know, last year we created indexes of posts on OAM and OIM 11g R2 that we call OAM 11g Academy and OIM 11g Academy.

These indexes contain the articles we’ve written that we believe provide long lasting guidance on OAM and OIM.  Posts covered in these series include articles on key aspects of OAM and OIM 11g, best practice architectural guidance, integrations, and customizations.

Main Article

It is our hope that these series will prove valuable to new and experience architects, implementers, and administrators of OAM and OIM.

Over the last few months, we haven’t been the best about updating these series to include new articles we’ve written.  That being said, we have gone back and brought the indexes up to date.  This is especially true on the OIM side where we have added many articles including some specifically on the new R2 release and have organized the index of articles into categories.

Going forward, it is our intent to continue to add to both the OAM and OIM series with lots of new content.

One thing to note, articles that apply specifically to R2 (and future releases) will explicitly say so in the index.  Likewise, any article that does not apply to the current release will be edited to note that.  Any other article in the indexes should be viewed as applying to all versions of 11g.
The links for the academy series are:

OAM 11g Academy

OIM 11g Academy

OIM 11g R2 UI Customization Tips and Tricks

$
0
0

Introduction

OIM 11g R2 provides OIM Developers with the means to implement very sophisticated and functional rich customization to the Out-of-the-Box User Interface. These customizations are capable of surviving the installation of patches, which means that when the OIM installation is patched, the UI customizations don’t have to be re-applied. The customizations are stored as metatada in MDS (Meta Data Store), and it is applied on top of the standard user interface at run-time. This article presents a few techniques to implement customizations that go a little beyond the capabilities of Web Composer; but still are within the scope of OIM’s MDS.

On a recent post by Daniel Gralewski, a customization for the Catalog was presented. The purpose of such customization was to filter the resources already provisioned to a user from the results of a catalog search. In a follow up question, one of our readers asked if the search screen could be customized to add a drop down box that can be used to trigger a predefined search in the catalog. This post describes the way in which this could be accomplished.

Main Article

The customization will provide the functionality to accomplish the following:

Allow users to select one item from a drop down list of level 1 categories, and based on that selection a second drop-down list is populated.The items in the first drop-down box represent Applications.The items in the second drop-down box represent Application Modules of the selected Application.Once an Application Module is selected from the second drop-down list, the catalog search is performed to retrieve the Application Roles associated to the selected Application Module.

The configuration

As described above, there is a relationship between the items in the first drop-down box and the items from the second drop-down. This relationship is created using user-defined tags configured for each catalog item. The relationship between all the elements in this sample implementation are as follows:
  • Application Customer Channel (CCH)
    • Application Modules
      • Online Billing (OLB)
        • Admin Agent Role (AAR)
        • Audit Agent Role (AUAR)
        • Promotion Agent Role (PAR)
      • Customer Support (CSUPP)
        • Support Agent Role (SAR)
        • Support Manager Role (SMR)
      • Products and Services (PANDS)
        • User Role (USRR)
        • Admin Role (ADMR)
      • Marketing (MKT)
        • Campaign Manager Role (CMGR)
        • Product Manager Role (PMGR)
Applications are categorized as:
  • Enterprise Application (Tagged as: EnterpriseApp)
  • Organization Application (Tagged as: OrgApplication).
  • Application Modules are tagged as AppModule.
  • Application Roles are tagged as AppRole.
The following table shows the Resource Hierarchy for the Application shown above:
Resource Name
Category
Tags
Customer Channel
ApplicationInstance
OrgApplication
Online Billing
ApplicationInstance
AppModule, CCH, OLB
Customer Support
ApplicationInstance
AppModule, CCH, CSUPP
Products and Services
ApplicationInstance
AppModule, CCH, PANDS
Marketing
ApplicationInstance
AppModule, CCH, MKT
Admin Agent Role
Role
AppRole, OLB
Audit Agent Role
Role
AppRole, OLB
Promotion Agent Role
Role
AppRole, OLB
User Role
Role
AppRole, PANDS
Admin Role
Role
AppRole, PANDS
Support Agent Role
Role
AppRole, CSUPP
Support Manager Role
Role
AppRole, CSUPP
Campaign Manager Role
Role
AppRole, MKT
Product Manager Role
Role
AppRole, MKT

Based on the Tagging and Categorization shown above the following search can be used to retrieve the Organization Applications available to the logged in user’s organization:

Java code for Catalog Search on OrgApplication tag

The results are placed in a List variable called orgApplications. Now in order to display them in the first drop down box the following code creates the list of SelectItem elements for the drop down box.

 

Catalog Search Results parsing code

Then I will show you how to connect that to the actual drop down box on the screen. As you can see in the code fragment above, the SelectItem instances are built with the Catalog Entity Display Name as the SelectItem’s label and the EntityName as the value. The following table lists the entity names of the ApplicationInstances defined in this example:

 

Entity Name
Entity Display Name
Category
CCH
Customer Channel
ApplicationInstance (OrgApplication)
OLB
On Line Billing
ApplicationInstance (AppModule)
CSUPP
Customer Support
ApplicationInstance (AppModule)
PANDS
Products and Services
ApplicationInstance (AppModule)
MKT
Marketing
ApplicationInstance (AppModule)
Follow the steps below to populate the drop-down boxes according to the hierarchy above:
  • Log-in to the Identity Self Service console
  • Create a Sandbox and activate it.
  • Open the Catalog screen
  • Click Customize and select ‘Source’ view.
  • Add the Drop Down box to the screen, see example below:
Adding a Drop Down list for Available Applications

The text box where catalog search criteria used to be typed in has been made invisible.

After adding the drop-down list to the screen, open the properties for the Group Layout Container and switch to the Child Components tab. Re-order the components as needed. See the picture below:

fig1-5OIMUICustomizationTipsNTricks

Add an element ‘UISelectItems’ to the Drop-Down box component, by selecting the drop down box and pressing the Add Content button.

Unfortunately, the Web Composer does not allow manipulating the UISelectItems properties, so in order to attach the list of items displayed by the drop-down box, an export of the sand box is required. Once exported, edit the metadata file for the catalogSearch page as shown next:

Attach the list of items to the SelectOneChoice component

 

Set the ‘value’ property of the selectItems tag to #{CatalogTFManager.filterBox1List}. This is a property of the managed been CatalogTFManager part of the custom code required for this customization, as shown in the following picture:

Declaration of MBean Property filterBox1List

 

The drop-down box displays Organization Published and Global Scoped Applications. The ‘filterBox1List’ property will contain an aggregated list of Applications (Organization and Global Scope). The code presented in the listing below performs these operations:

Constructor of Managed Bean for Catalog screen customization

Set the ‘valueChangeListener’ property of the selectOneChoice tag to ‘#{CatalogTFManager.selectedApplicationChanged}’. This method is invoked when users make a selection on the drop-down box. Inside this method, the list of associated application modules is calculated and attached to the second drop-down list. It creates the ‘filterBox2List’ list of SelectItems which is attached to the second drop-down box using the ‘value’ property of the ‘selectItems’ tag of the second ‘selectOneChoice’ tag.


Set the value of ‘valueChangedListener’ property of the second ‘selectOneChoice’ tag to ‘#{CatalogTFManager.selectedAppModuleChanged}’. This will detect when a selection is made on the second drop-down box. The selecteAppModuleChanged method populates the value of the Search Expression input box that was hidden from the UI. When the user presses the button to start the search, the value in the Search Expression input is evaluated by the internal managed beans to extract the application roles associated to the selected Application Module.

 

The same customizations performed on searchCatalog.jsff.xml file need to be added to the catalogResult.jsff.xml file shown in the following listing:


Listing of catalogResults.jsff.xml file

Summary

Here is the list of steps to implement this customization:
  • Create a Sandbox and activate it.
  • Open the Catalog page and do the following:
    • Add two SelectOneChoice components to the page with their corresponding SelectItems subcomponent.
    • Remove the Visible flag from the InputText field for the search expression (this is part of the out of the box interface)
    • Create the Managed Beans for the logic of the Catalog screen and deploy your library. These beans will be responsible for:
      • Execute the required Catalog Searches.
      • Creating Lists of Values (Initially or based on selections from other list boxes).
      • Respond to UI events like selection changes or button clicks.
    • After the library has been successfully deployed, add bindings to the UI components (via composer) to tie the UI components on both pages of the Catalog Task Flow to member variables in the Managed Beans. This is required to control how UI components will be rendered according to the application’s state (like enabling/disabling buttons or links, or extracting the current multiple selections from the search results table).
    • Publish your Sandbox and test.
This article is part of the OIM 11g Academy Series.

Authenticating OIM APIs without end user’s password

$
0
0

Introduction

A common requirement in an OIM implementation is to not expose OIM user interface to all types of end users. To address this requirement, usually a custom application using OIM APIs is developed and deployed. Such application will expose specific OIM functionalities to end users. In most of the cases, customers want the custom application/OIM APIs to act as the end user, and not as a service account; this approach leverages OIM security model, and the actions will be correctly audited in OIM. Usually this custom application will be protected by a SSO solution, and asking the end user to provide his/her password is not an option. So the big question is: how to authenticate the OIM APIs against OIM server and make them act as the end user? This is another post in the OIM Academy series. To view the entire OIM 11g Academy series click here

Main Article

In OIM 9.x, the APIs provide two different ways of authentication: through OIM user’s credentials (username and password) and through the so called digital signature authentication. The digital signature authentication process allows authentication without a password, and because of that it is a largely used approach in custom OIM APIs based applications. With the introduction of OIM 11g, the digital signature APIs are being deprecated. They will still work when correctly configured, but they may be discontinued in future OIM releases. In R2 there is an easier way of using OIM APIs without the need of end’s user password. This post shows how this can be done. OIM uses standard J2EE/JAAS based authentication. Such authentication, in WebLogic world, is provided by the domain-level authentication providers. In an environment where OAM is providing SSO, such authenticators are integrated with OAM. In a situation where the user has already been authenticated and a valid Subject (along with the correct Principals) is set in the J2EE session, the OIM APIs can be used without further authentication. Of course the authenticated Subject must be a valid one for OIM. Some technical details:

  • This application runs in a separate WebLogic managed server created in the OIM domain
  • In this example OIM is protected by and integrated with OAM
  • The custom application is also protected by OAM
  • Both OIM and the custom application are accessed through OHS with a WebGate deployed on it
  • The custom application is a Java Servlet that uses the OIM APIs to get user’s detailed information based on the logged in user

The detailed configuration steps are:

1. Managed server creation and configuration

The custom application will be deployed to a managed server created in the OIM WebLogic domain. In this example, the server is called ‘myapp_server1′. The managed server was created by using the WebLogic administration console. There are two details that must be observed:

  • Configure the new server as a target for the ‘opss-DBDS’ JDBC data source. This will prevent the server from failing at start up time
  • Make sure that the server is configured to listen in a free port. In this example the port 9001 was used.

2. OHS server configuration

Create a custom file called ‘myCustomApp.conf’ in the $ORACLE_INSTANCE/config/OHS/ohs1/moduleconf folder. The file contents:

<Location /myCustomOIMApp>
    SetHandler weblogic-handler
    WebLogicHost [WL_HOST]
    WebLogicPort [WL_PORT]
    WLLogFile "${ORACLE_INSTANCE}/diagnostics/logs/mod_wl/oim_component.log"
</Location>

[WL_HOST]  and [WL_PORT] must be replaced by their respective values.

3. OAM resource creation

The custom application must be protected by OAM. This will guarantee that when the browser request hits the application, it has already been authenticated and the J2EE Subject information is already set. In this example, the OAM resource is created under the ‘IAM Suite’ application domain. The custom application URI is ‘/myCustomOIMApp’. A new resource of type ‘HTTP’ is created, the resource URL is set to ‘/myCustomOIMApp/**’, and the resource is configured with ‘Protect‘ protection level, ‘Protected HigerLevel Policy‘ as authentication policy and ‘Protected Resource Policy‘ as authorization policy. The images below shows the configured resource:

policy_1 policy_2

4. Custom application details and deployment

The custom application is a simple Java Servlet that leverage OIM APIs to get detailed user information and print such information to the Servlet output. It also prints the available HTTP headers.It is deployed to the managed server created in step ‘1’ as an application. In order to this application be accessible through the OHS/WebGate, the application URI must match the URI configured in steps 2 and 3:  ‘/myCustomOIMApp’. In this example this is defined in the ‘weblogic.xml’ descriptor. The Java Servlet method below is the one that connects to OIM and gets the logged in user information:

public void printMyOIMInfo(PrintWriter out) throws IOException, ServletException {

  try {
    Hashtable hm = new Hashtable();
    hm.put(OIMClient.JAVA_NAMING_PROVIDER_URL, "t3://<oim_server_address>:14000");

    OIMClient client = new OIMClient(hm); 
    AuthenticatedSelfService selfsvc = client.getService(AuthenticatedSelfService.class);

    Set retAttr = new HashSet();
    retAttr.add(AttributeName.USER_LOGIN.getId());
    retAttr.add(AttributeName.FIRSTNAME.getId());
    retAttr.add(AttributeName.LASTNAME.getId());

    User user = selfsvc.getProfileDetails(retAttr);
    Set attrNames = user.getAttributeNames();
    Iterator iter = attrNames.iterator();

    out.println("<TABLE ALIGN=CENTER BORDER=1>");
    out.println("<tr><th> Attribute Name </th><th> Attribute Value </th>");

    while (iter.hasNext()) {

      String attrName = (String)iter.next();
      out.println("<tr><td align=center><b>" + attrName + "</td>");
      out.println("<td align=center>" + user.getAttribute(attrName).toString()+ "</td></tr>");
    }

    out.println("</TABLE><>");

  } 
  catch (Exception e) {
    e.printStackTrace();
  } 
}

Note how the OIMClient instance is acquired: all the information needed is the OIM t3 location (t3://<oim_server_address>:14000). There is no need to provide credentials because the session is already authenticated by the container. This approach provides a very simple way of acquiring OIM API instances from an external application. It is important to mention that the oimclient.jar library must be deployed in the application. In this example, it was deployed under WEB-INF/lib folder in the WAR file. The XML below is the J2EE web.xml descriptor:

<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
  <servlet>
    <servlet-name>MyCustomOIMServlet</servlet-name>
    <servlet-class>com.oracle.demo.iam.MyCustomOIMServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>MyCustomOIMServlet</servlet-name>
    <url-pattern>/myInfo</url-pattern>
  </servlet-mapping>
  <login-config>
    <auth-method>CLIENT-CERT</auth-method>
  </login-config>
</web-app>

It is important to notice the ‘login-config’ section and the ‘CLIENT-CERT’ authentication method. This method tells WebLogic to trigger the container based authentication. Since the application is protected by OAM and the OAM authenticator is deployed to WebLogic, the J2EE Subject will be created based on the username that got externally authenticated by OAM. The picture below shows the Servlet output for the logged in user ‘bob.dylan':

info

The result of invoking ‘request.getUserPrincipal().getName()‘ is highlighted in yellow . The information retrieved from OIM by the OIM APIs is highlighted in green. The available HTTP request headers are highlighted in red.

The JDeveloper workspace created for this post can be found here, file name is ‘MyCustomOIMApp.zip’. You will need to have OIM client jar defined as a JDeveloper library in order to get the project compiled.

OIM 11g R2 Requests Lifecycle Management API’s

$
0
0

Introduction

OIM 11g R2 being such a comprehensive provisioning solution, it provides API’s for almost every aspect of functionality available in the product. This makes it a little difficult to decide which examples are needed the most in the documentation. Fortunately, the documentation does supply samples that can definitely serve as a foundation for more complex pieces of code. Some of the API’s I found developers using more often than others are the ones related to the operations associated with users’ requests for resources. Amongst those the following API’s are mostly required:

  • Request Creation/Submission
  • Request History Data Access
  • Child Table Data Manipulation
  • Approval Information Data Access
This blog post will include a few samples on how to accomplish each one of the above mentioned operations within the context of a use case described shortly. The intent is to provide some useful API’s code samples that customers and partners can use to write their own custom code that requires such functionality.

Main Article

As a starting point for this article, I figured that the best way to describe a series of API code samples is by using a use case. Here is ours:

A Home Building Company requires their Engineers and Site Managers to carry handheld devices (Smart Phones, Tablets, Radios) to keep information about their projects and also maintain communication with the corporate office. These devices are provisioned to their users along with a specific list of services enabled on the device. The users are provisioned these resources through the following process:
When the user is on boarded, it gets assigned to an Organization according to their role (Engineer, Architect, Site Manager, Designer, Sales Associate, etc). Depending on the organization the users belong to a certain type of device with specific capabilities can be requested. Users submit their requests for a device and a set of capabilities through OIM. Now, the request for provisioning of the resource is not supposed to reach the administrator that will setup the contract for the device until all the individual services that will be enabled in the contract are approved. The fact that a device service is requested doesn’t mean it will be granted to the requester. Each individual service requires a different set of approvals. Once all the requested services have been processed (approved or denied) then the request arrives in the administrator’s queue.

The Design

According to the Use Case described previously, the design of a solution that addresses the requirements needs to leverage the concept of Disconnected Application Instance.  In this case in particular, the Disconnected Application Instance will have a Child Form used to store the Services that will be enabled on the device’s contract once it is provisioned.
As described above, the services go through approval individually. In order to accomplish this in a simple way we will represent the device contract services as roles, which can be assigned their own approval process and can be tracked individually. Now, suppose the HBC has a new requirement that expresses the need to provision application entitlements to a Portal that allows users to manage their own contract’s services and the access is controlled through AD group membership. Having the design already described allows for the use of access policies to provision such access automatically once the role for the individual service is approved, and the evaluation of access policies has been executed.
In summary, the code samples we provide in this section will focus on how to create the requests for the disconnected application instances and the roles representing the services available on the contract for the device. Then, the focus will be shifted to the API’s used to retrieve the data for a given request and read it. The user interface that allows the users to request such devices and services can be implemented as a customization to the catalog screens in OIM 11g R2. The screens will contain a drop down list of devices that are available to the users according to their organization. When a device is selected, a second catalog search will bring back the services that are tied to the selected device (For an example of cascading searches customization please refer to the following blog post OIM 11g R2 UI Customization Tips and Tricks).

The Implementation

Now to the fun part, how do we make this happen? As I stated before, the main focus will be the Request Lifecycle Management API’s so we will not show the Catalog Search API’s samples neither how to customize the UI to input the data (a potential implementation of such logic is also discussed in the post mentioned earlier. Also, for all kinds of samples of UI customizations and other commonly used OIM API’s make sure to refer to the OIM 11g Academy). So assuming the user has the means to select a device and a set of services for the selected device the requests for each one will be created as follows:
The code will traverse the list of services that were added to the cart first, and then create requests for them and obtain the request ids by submitting those requests. Then create the request for the actual device and populate the child table with the requested services. The child table will have three columns (fields): Service Name, Request ID for the role representing the service and the status of the Role (Pending/Approved/Rejected).
The first sample presented creates a request for a Role to be granted to the user. Consider the code in the following listing:
buildRoleAssignmentRequest-method-img
Two parameters are passed: the item of type Catalog and the userLogin of type String. The userLogin is necessary to extract the user Key which will be inserted in the request. The item parameter contains the information that describes the role as a Catalog Item. The Catalog class provides the details that can be used to populate the request for the actual entity. In case of roles as shown in the listing above, there is no need to populate a form, just create a RequestBeneficiaryEntity and set a couple of attributes in it. Things get more interesting when creating the request for the Application Instance. Here is how:
buildApplicationInstanceRequest-method
 
Same two parameters are passed but this time there is an additional call to build the list of attributes for the Application Instance Form. Below is the listing for the method buildAppInstanceAttributeList:
buildAppInstanceAttributeList-method
 
As presented in the listing below, in order to set the values of fields in the “process form”, what is being used is the field label not the field name. The reason why is because we are not really populating the form, we are populating the request data set, which in turn will serve as the source to populate the actual process form. This gives the ability to determine what information the requesters may see when submitting requests for resources, which may not be the entire set of fields in the actual process form. The other interesting thing is how to populate the Child Table, see below (this is a fragment from the method listing above):

buildAppInstanceAttributeList-buildEntitlements-method-detail

 
In typical examples of how to accomplish child table record insertion that I have come across, all they show is how to insert one value into the child table; but what about inserting multiple rows in the child table and each row has multiple attributes. Well this example shows you how to accomplish insertion of child table records when you need to insert multiple rows that in turn have multiple columns. As shown in the code above, what needs to be done is to create an instance of RequestBeneficiaryEntityAttribute that represents the child table itself. Then you create an instance of RequestBeneficiaryEntityAttribute for each column in the child table. You set the values of each individual column and add those attributes to a list (see childAttributesList1). Then you call the addChildAttributes method on the attribute that represents the Child Form (see appRolesAttr) and pass the list containing the values of all the Child Attributes of the row. To insert multiple rows, you create multiple instances of the RequestBeneficiaryEntityAttribute that represents the Child Table itself and build the row as already explained. In the listing above the creation of appRolesAttris placed within a loop that in our case traverses the list of Services (Entitlements) that a device is supposed to have and then creates a child table row for each service.
That’s it for the request creation, now the requirements for the use case as designed need the means to monitor the requests for the individual services (roles) and determines when to resume the Device Provisioning process flow. For those of you that are new to Disconnected Application Instances and how they are provisioned, here is a little background: Disconnected Application Instances are configured just as regular connected applications that have a Target System (IT Resource/Resource Object combination), the only difference is that as disconnected Applications the IT Resource, Resource Object, provisioning process, process form, request data sets, etc are created by OIM behind the scenes. You can customize these artifacts after they are created, which in fact is what we need to do to add the services to the requested device. The process form will be customized to add the child table that will hold the contract services for the device. The code to populate the child form has been presented above.
In order to monitor the status of the Requests for Device Contract Services, we need to read that data and keep a count of Services that have already been processed versus those that haven’t. As a solution to this problem we decided to implement an asynchronous Web Service which is implemented as an Asynchronous BPEL process that invokes a Synchronous Web Service that monitors all the associated Role requests (contract service requests) mapped to the device’s request. The asynchronous BPEL process is presented in the figure below:

AsynchronousBPELProcessWebService

 
This BPEL process contains a loop task that will break the loop when the count of pending role requests reaches ‘Zero’.  Every invocation of the OIMPendingRequestsCounterService results in a new count representing the number of requests for Contract Services (Roles) that are still awaiting approval. This is an easy way to create an asynchronous Web Service using JDeveloper’s features to create Asynchronous BPEL processes that can be invoked as asynchronous Web Services. The implementation of the OIMPendingRequestsCounterService is described next. Consider the listing presented below:
getPendingEntitlementsCount-method 
The most important components in this implementation are:
  •  OIMClient oimClient: This is used to obtain instances of OIM’s API’s.
  • RequestService reqSvc: The Service used to obtain information about a request and to update the request’s data when appropriate.
  • UserManager usrMgr: Used to obtain the User’s Key of the request’s beneficiary along with other information that might be needed.
Notice another new service introduced in OIM 11g R2, the ApplicationInstanceService. This is used to obtain the names of process and child forms plus their values. According to the listing above, the process is actually simple: Obtain the requested Entity from the request data. Find the Application Instance that is associated with the request by checking the entity sub type. Once the Application Instance has been found, now we can obtain the child form that contains the entitlements (contract services). Each row is represented by an occurrence of an attribute named after the child form’s table. So if multiple entries are present in the child table, they will be accounted for as separate instances of the attribute named after the child form’s table.
These attributes are added to a list that will be traversed to extract the individual rows one by one. Each row has child attributes (columns) which contain the value of the corresponding column within the row. All these information comes from the populated data set not the actual process form. In order to retrieve the data from the process form, the resources need to have already been provisioned. That is not the case in this situation because the Application Instance representing the device can’t be provisioned until all the services have gone through their approval processes. The following method is also important for the implementation:

isEntitlementRequestPending-method

 
This is the method that reads the child request data to determine if the Approval has been granted or denied; in other words, whether or not the child request has been already processed. So, to complete the implementation all you need to do is to modify the Composite that gets invoked when a Disconnected Application Instance is provisioned. The following picture shows this modification:
disconnectedApplicationProvisioning-bpel
As shown in the previous picture, an Invoke activity along with a Receive activity are employed to call the asynchronous BPEL process that internally call the synchronous Web Service to monitor the Approval/Rejection of the requests for the Contract Services (Roles). This mechanism is fairly simple, but has room for optimization of course. For instance, you might want to implement an event generation mechanism to send a JMS Message to unblock the process flow of the Disconnected Application Provisioning SOA Composite and then process the Human task that will be sent to the Administrator of the Contract, who will manually carry out the processing for the provisioning of the device.

Summary

In this article, we have presented the audience with samples of how to use OIM API’s to programmatically implement a use case that involves the following Request Lifecycle Management operations:
  • Create complex structure requests for Disconnected Application Instances.
  • Create requests for Role Assignment.
  • Implement Data Retrieval from Child Tables directly from the request data set.
I hope the samples presented in this article are helpful to your own implementations.
For this and many other useful OIM 11g R2 articles make sure to visit our OIM 11g Academy series.

Synchronization of Roles in Catalog OIM 11g R2

$
0
0

Introduction

The Catalog is one of the most fundamental features of OIM 11g R2 request based provisioning. All requests for Resources/Accounts, Entitlements and Roles are accomplished through the Catalog. Roles in OIM 11g R2 can be defined within a given category. There are two main out-of-the-box categories: OIM Roles and Default. The category affects the visibility of the Role in the Catalog.

Sometimes, customers may require to change the category of an existing Role in order to make it possible to request the Role through the Catalog. If the Role was initially created within the OIM Roles category,  it will not be visible in the Catalog because there is no entry in the Catalog’s table for the Role.

Main Article

A Role is available in the Catalog when its category is set to ‘Default’. This can be ensured by modifying the Role’s attributes in the Self-Service User Interface and selecting the ‘Default’ category from the List of Values. The picture that follows shows where this is done and provides an example:

Role attributes screen

 

In the example above, the role MASSACHUSETTS ORG MEMBER was originally created with OIM Roles as the selected category. As a result, this role can’t be requested through the Catalog. The role’s category will need to be updated to ‘Default’. The images below demonstrate the change:

Selecting Default as the new category for the Role.

Category changed to Default

Roles are published immediately after they are created; however, if a Role is updated after creation like in the previous example, the Catalog Synchronization Job has to be executed to reflect the changes in the Catalog.

To invoke the Catalog Synchronization Job, an Administrator needs to log in to the System Administration Console of OIM and open the Scheduler Window; then navigate to the Catalog Synchronization Job as shown in the following picture:

Catalog Synchronization Job

The Job must be executed with the following values in the Job’s attributes:

  • Mode = full
  • Process Roles set to Yes
  • Updated Date must be blank

After the execution of the Catalog Synchronization Job, searching for the Role in the Catalog should now display the role in the results as shown below:

Catalog search results showing the updated role

Summary

The Catalog is one of the main components of OIM 11g R2. The Request-Based provisioning functionality revolves around it. Any entity in OIM that can be requested by users needs to be visible in the Catalog. Roles that have OIM Roles as their category, are not visible in the Catalog; only the ones in the ‘Default’ category will be displayed in Catalog Search Results.

If a Role was initially created with OIM Roles as its category and then is updated to the Default category will not be displayed in the results of a Catalog search unless the Role is added to the CATALOG table in OIM’s Database. This is accomplished by running the Catalog Synchronization Job through OIM’s Scheduler. The job must be executed in Full mode, the ‘Process Roles’ option must be set to ‘Yes’ and the ‘Updated Date’ value must be blank.

OIM 11g R2 Self Registration with CAPTCHA

$
0
0

This post walks you through the fun of customizing OIM and adding a CAPTCHA solution to the self-registration page. Captcha solutions are largely used in web sites to try to prevent automated robots from registering, filling forms, sending messages and many other things.

The captcha solution used is Simple Captcha and it is available here. It is easy to use and easy to hook into applications.

This is another post of the Oracle Identity Manager Academy. To check other tricks, tips and examples you can find the academy post here.

Deploying the captcha solution

Unfortunately, a usually non-recommended step is required to hook the captcha solution into OIM: the capctha servlet must be deployed to the OIM self-service console web application. To do so, you have to:

  • Make a backup of $OIM_ORACLE_HOME/server/apps/oracle.iam.console.identity.self-service.ear
  • Copy the file oracle.iam.console.identity.self-service.ear to a temporary location
  • Using a ZIP tool like 7zip, open the oracle.iam.console.identity.self-service.ear
  • Then open oracle.iam.console.identity.self-service.war
  • Then navigate to WEB-INF folder and add the following to the web.xml file:
    <servlet-name>CaptchaServlet</servlet-name>
    <servlet-class>nl.captcha.servlet.SimpleCaptchaServlet</servlet-class>
    <init-param>
            <param-name>width</param-name>
            <param-value>250</param-value>
    </init-param>
    <init-param>
       <param-name>height</param-name>
       <param-value>75</param-value>
    </init-param>
  </servlet>

You also need to add the captcha jar file (simplecaptcha-1.2.1.jar) into the oracle.iam.console.identity.self-service.warlib‘ folder (if the folder does not exist, just create it).

Then copy the file oracle.iam.console.identity.self-service.ear over the original one and restart WebLogic (you may need to re-deploy the oracle.iam.ui.self-service application in the WebLobig console).

Customizing OIM self registration page

Before starting this section, it is important to mention that the post assumes you have some knowledge of OIM UI customization features. If you don’t, you may want to spend some time in the following posts:

There are a couple of tricks to use to customize the self registration page:

  • To direct access the self registration page you can type in the browser url: http://<OIM_HOST>:<OIM_PORT>:/identity/faces/register. This URL works with and without authentication, but OIM will prevent you from submitting a request for self registration if you are authenticated.
  • When on the page, make sure you provide values to the mandatory fields before trying to customize it.

1. The managed bean

There is a need to create and deploy a managed bean. This managed bean must be deployed into the oracle.iam.ui.custom-dev-starter-pack.war placeholder library. In this example, the managed bean is  called ‘captchaBean’. The managed bean code:

package com.oracle.demo.iam.captcha.view;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.validator.ValidatorException;

import nl.captcha.Captcha;

import oracle.adf.view.rich.component.rich.output.RichImage;

public class CaptchaBean {

    private UIComponent rootPanel;
    private UIComponent captchaImage;

    public CaptchaBean() {
        super();
    }

    public void refreshCaptchaActionListener(ActionEvent e) {

        RichImage image = (RichImage)captchaImage;
        String randomString= String.valueOf(Math.random());
        image.setSource("/captcha?rand="+randomString);           

        FacesUtils.partialRender(rootPanel);
    }

    public void verifyCaptchaValue(FacesContext facesContext, UIComponent uiComponent, Object compValue) {

        FacesContext fctx = FacesContext.getCurrentInstance();

        ExternalContext ectx = fctx.getExternalContext();

        Captcha captcha = (Captcha)ectx.getSessionMap().get(Captcha.NAME);
        String answer = (String)compValue;

        if (!captcha.isCorrect(answer)) {
            throw new ValidatorException(this.getFacesMessage("Please provide a correct answer"));
        }
    }

    private FacesMessage getFacesMessage(String msg) {

        FacesMessage message = new FacesMessage();
        message.setDetail(msg);
        message.setSummary(msg);
        message.setSeverity(FacesMessage.SEVERITY_ERROR);

        return message;
    }

    public void setRootPanel(UIComponent rootPanel) {
        this.rootPanel = rootPanel;
    }

    public UIComponent getRootPanel() {
        return rootPanel;
    }

    public void setCaptchaImage(UIComponent captchaImage) {
        this.captchaImage = captchaImage;
    }

    public UIComponent getCaptchaImage() {
        return captchaImage;
    }
}

A few comments about the code:

  • The method ‘verifyCaptchaValue‘ will be invoked by ADF when the self-registration form is submitted. The property ‘validator‘ in an input text filed indicates which method ADF will invoked. If the method raises the ‘ValidatorException‘, ADF will catch it and show the ‘Please provide a correct answer” message on the page.
  • The method ‘refreshCaptchaActionListener’ will be invoked when the user clicks on a button to refresh the captcha image. It actually changes the image URL by adding a random string to the end, this is required to make sure that the image gets refreshed.
  • This code uses the class ‘FacesUtils‘, such class can be found here

The managed bean declaration is done in the adfc-config.xml file:

<?xml version="1.0" encoding="windows-1252" ?>
<adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2">
  <managed-bean id="__222">
    <managed-bean-name id="__4">captchaBean</managed-bean-name>
    <managed-bean-class id="__1">com.oracle.demo.iam.captcha.view.CaptchaBean</managed-bean-class>
    <managed-bean-scope id="__3">backingBean</managed-bean-scope>
  </managed-bean>
</adfc-config>

The managed bean must be deployed before proceeding with the UI customizations because the methods will be referenced from the custom UI components.

2. Adding the UI components

There are two main UI components to be added through UI customization using the composer: a texfield where end users will enter the captch value, and a button to refresh the captcha image. There is also a need for a couple of layout components to organize the button and the textfield in the self registration page.

2.1 The first step is to create and activate a sandbox that will hold the UI customizations.

2.2 With the sandbox created and actived, hit the customize OIM link on the top right. Then on your browser enter the self registration URL mentioned above.

2.3 Customize the page by adding the following elements under the ‘panelHeader: User Registration‘ component

  • Web Components‘ – ‘Show Detail Header
  • Web Components‘ – ‘Spacer

2.4  Edit the ‘Spacer’ and set ‘Height’ to 10 and clean up the ‘Width‘ value

2.5 Edit the ‘showDetailHeader:Header‘ component and set the ‘Text‘ property to ‘Are you Human?’

2.6 Edit the ‘panelHeader: User Registration‘ and re-order the child components, the order should be as the one shown in the picture below:

captcha3-ordering

2.7 Click on ”showDetailHeader:Header” and add a ‘Web Components’ – ‘Panel Form Layout’ to it

2.8 Edit the ‘panelFormLayout‘ and set the ‘Binding‘ property to ‘#{backingBeanScope.captchaBean.rootPanel}‘.

2.9 Still with the ‘panelFormLayout’ selected, add a ‘Web Components’ – ‘Input Text‘ and a ‘Web Components’ – ‘Command Toolbar Button

2.10 Edit the ‘inputText: Label‘, set the ‘Label’ to ‘Enter the code above’, and click on the ‘Required‘ checkbox. The ‘Required‘ flag tells ADF to validate the field before the form is submitted.

2.11 Edit the ‘commandToolbarButton‘, set the ‘Text‘ to ‘Cannot see? Refresh Image‘ and click on the ‘Immediate’ checkbox. The ‘Immediate’ flag tells that a partial form submit is allowed.

At this point, the page should be like the one below:

captcha4-half-way

2.12 Close the customization by clicking on the link on the top right and navigate back to the identity self service console

3. Manually customizing UI components

OIM UI customization features does not expose all ADF components attributes, so there is a need to do some manual intervention to get the components configured.

3.1 De-activate the sandbox and export it

3.2 Open the sandbox zip file and locate the following file: oracle\iam\ui\unauthenticated\selfregistration\pages\mdssys\cust\site\site\user-self-registration.jsff.xml. Open it in a text editor, it should show similar to the one below:

sandbox-1-1

3.3 The first thing to be added to the file above, is the actual captcha image. You can do this by adding the following under the ‘af:panelFormLayout‘ component:

<af:image xmlns:af="http://xmlns.oracle.com/adf/faces/rich" 
             source="/captcha" 
             id="icaptcha1" 
             inlineStyle="width:250px; height:75.0px;"
             binding="#{backingBeanScope.captchaBean.captchaImage}"/>

3.4 Add the action listener property to the ‘af:commandToolbarButton‘: actionListener=”#{backingBeanScope.captchaBean.refreshCaptchaActionListener}”

3.5 Add the ‘validator‘ property to the ‘af:inputText‘: validator=”#{backingBeanScope.captchaBean.verifyCaptchaValue}

3.6 Add the ‘disclosed’ property to ‘af:showDetailHeader’: disclosed=”true”

At this point the file should be similar to the image below:

sandbox-2-2

3.7 Repack the sandox zip file and import it back to OIM

4. Testing

Once the managed bean is deployed and the sandbox published (or active), OIM self registration page should like the one below:

final-page

Have fun!

OIM 11g R2 Performance Patch

$
0
0

Oracle has released a set of patches to address some performance issues in OIM 11g R2 self-service interface. Information about these patches is available in the following Oracle support note:

  • Document 1557879.1 OIM 11gR2: Patches for Performance Issues Related to Self-service UI

The note contains the details for each specific R2 release.

Any customer who is running OIM or implementing OIM at this point should plan to apply the patches.

Just a reminder, the recommendation is always to start applying patches in lower environments: from DEV to PROD. Don’t forget to validate the patches in one environment before proceeding to the next.

Loading unique passwords with OIM bulk load

$
0
0

Introduction

Using Oracle Identity Manager’s bulk load tool is a great way to load large numbers of user records into OIM in an efficient and performant way. The standard and documented usage of the tool does not make provision for the loading of unique user passwords, though. This article describes an approach that can be used to achieve that requirement. This post is also part of the OIM 11g Academy Series.

How does OIM bulk load work?

The tool uses the SQL Loader functionality of the underlying Oracle Database to “pump” records into OIM’s tables, rather than working through the Java API layer. Those familiar with OIM’s architecture and functionality will know that there is typically a large amount of processing associated with adding a user record via the user interface (or the API layer underneath) – processing necessary for data integrity and validity checking, username and password generation, role assignment, policy-based provisioning and so on. While the reconciliation engine provides a more efficient way to create users, by allowing costly operations to be run in batch via the API layer, no approach to user loading that works through the API layer could ever perform as well as one that goes directly to the database. That’s probably just an interpretation of Occam’s razor, if you think about it. The direct database approach used by bulk load does, of course, impose some restrictions, one of these being the inability to perform encryption of user attributes during the load process. Since the user password is always stored in an encrypted form (along with other attributes if required), this limitation makes it impossible to load a unique password for each user, since the SQL Loader tool doesn’t have access to the encryption routines (and keys) necessary to encrypt these (plain-text) password values at the time of loading. 

What is the use case?

There are two major scenarios in which we might want to load a unique password value for users (and, I’m sure, hundreds of minor ones). The first is where we are migrating users in bulk from some other repository and wish to migrate their existing passwords with their accounts. The assumption here is that the password values are available in plain-text at the time of loading, which admittedly is not often the case. The second is where we would like to do a bulk take-on of new users and would like to generate and load a random initial password for each user, which would then be shared with the users out of band.We could, of course, perform this activity post load using the API layer although this approach would be significantly less performant.

The approach

The approach used to enable direct database loading of unique passwords is relatively straightforward; it involves running the plain-text passwords via a pre-encryption utility in order to generate the appropriate encrypted values (or cipher-text values, to be correct) using OIM’s encryption key. These cipher-text values can then be loaded directly into the database using the existing OIM bulk load tool. The specifics of the pre-encryption utility, as well as the process to be followed, will be discussed below, but we do need to mention a caveat at this point:

 After running bulk load, there is a “bulk load post process” scheduled task which needs to be run. By default, this task will attempt to generate a random password for each user. Be sure to disable this option via the scheduled task options, if you are loading unique passwords via bulk load.

Pre-encryption

The pre-encryption utility can be a simple piece of Java code that encrypts plain-text values using the OIM encryption key. The sample below should demonstrate the concept.

import com.thortech.xl.crypto.tcCryptoException;
import com.thortech.xl.crypto.tcCryptoUtil;

public class EncryptionUtil {

	public static void main(String[] args) {
		if (args.length != 1 ) {
			System.out.println("Usage: PINEncryptionUtil  ");
			System.exit(1);
		}
		if (System.getProperty("DOMAIN_HOME") == null) {
			System.out.println("Please set DOMAIN_HOME system property");
			System.exit(1);
		}
		if (System.getProperty("OIM_HOME") == null) {
			System.out.println("Please set OIM_HOME system property");
			System.exit(1);
		}
		if (System.getProperty("oracle.security.jps.config") == null) {
			System.out.println("Please set oracle.security.jps.config system property");
			System.exit(1);
		}
		if (System.getProperty("XL.HomeDir") == null) {
			System.out.println("Please set XL.HomeDir system property");
			System.exit(1);
		}
		try {
			String plainText = args[0];
			String cipherText = tcCryptoUtil.encrypt(plainText, "DBSecretKey");
			System.out.println(cipherText); 
		} catch (Exception e) {
			System.out.println("Error encrypting value");
		}
	}
}

Ultimately, the code above is not very exciting in itself. All that it does is take a plain-text value as input and print the cipher-text value as output. Line 29 is where the magic happens, but as you can probably tell from all the environment checking that we do beforehand, we need to do quite a bit of set-up in order to make this code work. Once we have our encryption utility class complied, we can use a run script similar to the below to ensure that we are setting the correct classpath, as well as the correct JVM options, to run the utility.

#Environment variable setup.... modify this section for your environment.

export JAVA_HOME=/opt/oracle/java
export PATH=$JAVA_HOME/bin:$PATH
export MW_HOME=/opt/oracle/Middleware
export WL_HOME=$MW_HOME/wlserver_10.3
export ORACLE_HOME=$MW_HOME/Oracle_IDM1
export DOMAIN_HOME=/opt/oracle/Middleware/user_projects/domains/oim_domain

#Do not modify below

. $ORACLE_HOME/server/bin/setEnv.sh
export CLASSPATH=./classes:$ORACLE_HOME/server/platform/iam-platform-utils.jar:$ORACLE_HOME/server/platform/iam-platform-auth-server.jar:$ORACLE_HOME/server/apps/oim.ear/APP-INF/lib/csv.jar:$MW_HOME/oracle_common/modules/oracle.jrf_11.1.1/jrf-api.jar:$MW_HOME/oracle_common/modules/oracle.jmx_11.1.1/jmxframework.jar:$MW_HOME/oracle_common/modules/oracle.jmx_11.1.1/jmxspi.jar:$MW_HOME/Oracle_IDM/modules/oracle.oes_11.1.1/thirdparty/identitystore.jar:$MW_HOME/oracle_common/modules/oracle.pki_11.1.1/oraclepki.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-manifest.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jacc-spi.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-common.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-internal.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-wls-trustprovider.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-api.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-platform.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-wls.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-unsupported-api.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-az-common.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-az-api.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-az-sspi.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-az-management.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-ee.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-mbeans.jar:$MW_HOME/oracle_common/modules/oracle.jps_11.1.1/jps-az-rt.jar:$MW_HOME/modules/javax.management.j2ee_1.0.jar:$MW_HOME/modules/javax.servlet_1.0.0.0_2-5.jar:$CLASSPATH

java -DDOMAIN_HOME=$DOMAIN_HOME -DOIM_HOME=$ORACLE_HOME/server/ -Doracle.security.jps.config=$DOMAIN_HOME/config/fmwconfig/jps-config-jse.xml -DXL.HomeDir=/$DOMAIN_HOME/config/fmwconfig/ -DJAVA_HOME=$JAVA_HOME -DkeyStoreFileName=.xldatabasekey com.oracle.ateam.custom.EncryptionUtil $1

All the usual warnings about plain-text passwords obviously still apply here. Please be extra careful not to leave a text file full of plain-text passwords lying around on the file system, or anything like that.

The bulk load process

Now that we have a utility that we can use to pre-encrypt a plain text value, we can generate a bulk load CSV file containing encrypted password values, to load as normal. Below is a very stripped down sample of what such a file could look like.

USR_LOGIN,USR_FIRST_NAME,USR_LAST_NAME,USR_PASSWORD
testuser1,Test,User1,"6726:A2ZLndw90HzYrEtOhkl6HQ=="
testuser2,Test,User2,"3090:tEZQiear2ilc+HSZeq7Bcw=="

Be sure to enclose your encrypted values in quotes, or else they won’t load correctly.

During the execution of the bulk load process, OIM’s tool will ask you to specify the name of an existing user, whose password will be copied to all the user records being loaded. If you are providing a value for USR_PASSWORD in the file, your unique value will override the default, so you can enter any valid user name for this step.

You can use the same approach to pre-encrypt values for other database columns as well, not just the user’s password

A final (but important) word

Please be sure to read the official product documentation related to the OIM bulk load utility and ensure that you are comfortable with its usage before attempting this approach. Bear in mind, also, that this is far from a silver bullet, or “one-size-fits-all” solution; rather, it is a technique that has been found useful in certain scenarios and may prove effective in your own environment too.

A checklist for OIM go live

$
0
0

This post presents a list of configuration points in OIM. Such list definitely must be taken into account whenever a customer is planning an OIM go-live. This list is not intended to replace the OIM documentation, instead, the idea is to complement it. It provides tips on a few topics that are not part of the documentation.

Let’s go for them:

  • A visit to the OIM Performance Tuning guide is mandatory step before a go-live. The guide for the 11.1.2.1.0 release can be found here, whereas the one for 11.1.2.0.0 is available here:
    • JVM memory parameters
    • OIM cache
    • MDBs
    • Connection pool sizes
    • Database parameters
    • Database tables location
    • LDAP Synch
    • Deployment mode: cluster or simple? If deploying OIM in cluster mode, the deployment mode must be configured appropriately. The oim-config.xml excerpt below shows the specific configuration:
          <deploymentConfig>  
              <appServerName>weblogic</appServerName>  
              <initialContextFactory>weblogic.jndi.WLInitialContextFactory</initialContextFactory>  
              <dataBaseType>oracle</dataBaseType>  
              <deploymentMode>cluster</deploymentMode>  
          </deploymentConfig>
    • If deploying OIM in cluster mode, the OIM internal cache must be configured for that. The oim-config.xml excerpt below shows the specific configuration:
      <cacheConfig clustered="true" 
                 enabled="true" 
                 expirationTime="144000" 
                 provider="oracle.iam.platform.utils.cache.OSCacheProvider" 
                 threadLocalCacheEnabled="false">
    • If deploying OIM in cluster mode, the OIM scheduler must be configured for that. The oim-config.xml excerpt below shows the specific configuration:
      <schedulerConfig DSJndiURL="jdbc/operationsDB" 
                 nonTxnDSJndiURL="jdbc/oimJMSStoreDS" 
                 clustered="true"   .../>
    • If deploying OIM behind a LoadBalancer and or Web Server, OIM front end URL and SOA SOAP URL must be configured with the Load Balancer/WebServer URL. The oim-config.xml excerpt below shows the specific configuration:
      <oimFrontEndURL>http(s)://hostname:port</oimFrontEndURL>

      and

      <soapurl>http(s)://hostname:port</soapurl>
    • OIM R2 PS2 (11.1.2.2.0) release introduced a new URL related configuration parameter called oimExternalFrontEndURL. The objective is to have more flexibility when it comes to URLs used to access OIM application: the SOA-OIM traffic (oimFrontEndURL) can be separated from OIM UI traffic (oimExternalFrontEndUrl):
  • <oimExternalFrontEndURL>http(s)://hostname:port</oimExternalFrontEndURL>
    • If OIM WebLogic domain is configured with an LDAP security provider, make sure to review the number of connections to the LDAP Server. This number can have impact on OIM performance, especially in deployments with a high number of users. A very common situation where this configuration should be reviewed is when OIM is integrated with OAM.

 

  • Multicasting check: OIM internals have a dependeny on multicasting in clustered deployments. It is important to make sure that multicasting is enabled and that the NIC/IP used by OIM can multicast massages. This configuration is independent of the chosen WebLogic cluster approach (Unicast or Multicast)

As stated above, oim-config.xml is the configuration file that holds OIM internal configurations. This file can be exported from MDS, changed and then imported back. OIM needs to be bounced to take the changes. Be careful when changing this file, if it contains errors OIM will not start correctly.

OIM 11g R2 Delegated Administration Model – Sample implementation (Part I)

$
0
0

Introduction

It is a very common requirement from customers to have a delegated administration model that is not tied to the organizations where the administrators are placed.

Historically, OIM only supports a one-to-one relationship between Users and Organizations. However, starting with OIM 11g R2 and the introduction of the Catalog, it is possible to publish resources to one or more Organizations.

This allows to limit the visibility of the resources to only the users who need them. However, OIM 11g R2 also provides the mechanisms to delegate the administration of Users, Organizations and Resources to specific users regardless of the Organization to which those users belong.

This article describes an approach that can be used to implement a Provisioning Solution powered by OIM 11g R2 that is not necessarily tied to an organization-centric model. The intent of this design is to show our readers how to leverage the advanced features of OIM 11g R2 to implement Delegated Administration Models that are resource-centric and not organization-centric.

Main Article

In order to implement a model that is not centered on the relationships between users and organizations, which is quite restrictive, we need to leverage OIM’s flexibility for publishing resources to multiple organizations. By doing that, the limitation of having users constrained by the organization to which they belong is overcome. In addition, this model allows users to get access to the resources they need regardless of their placement within the Organizational Structure. The mechanism that makes this possible is called Scoped Administrative Roles (SARs).

Scoped Administrative Roles (SARs) are based on Policies that define the privileges of a user upon Entities associated to Organizations. For example: If a user is a member of the Scoped Administrative Role OrclOIMUserAdmin for the North America Organization, this person can View, Modify, Create, Enable and Disable users in the North America Organization regardless of whether the administrative user belongs to the North America Organization or not.

The functionality provided by the SARs is the foundation of this implementation. For more details about SARs and OIM’s Security Model please refer to the documentation for Oracle Security Architecture for 11.1.2 platform which is accessible here.

Delegated Administration Access Requests

By default, the only users authorized to place people in SARs are the members of the SYSTEM ADMINISTRATORS role in OIM, which is an administrative role that applies to all organizations defined in OIM.

If the number of Organizations in the company is considerably large, it may become impractical to manually assign users to Administrative Roles within each Organization. In addition, the assignment can not be subjected to an approval workflow.

A solution to this problem could be to somehow associate the assignment into SARs to an entity that can be requested in OIM via the Catalog. A good candidate would be a Role. Roles can definitely be requested through the Catalog and their visibility can also be controlled by publishing them to certain Organizations. Requests for Roles can also be subjected to an approval workflow.

In order to request inclusion in a SAR, users may submit petitions for one or more OIM Roles. These Roles are associated with one or more Access Policies that will assign Users to one or more SARs. In order to do this, the design includes the definition of a Disconnected Application Instance that represents a list of Delegated Administration Permissions granted to a User. The list of permissions is stored in a child form attached to the main process form for the Application Instance. For more information about Developing Application Instances refer to the Developers Guide for Oracle Identity Manager which can be found here.

The list of permissions is published as Entitlements. Each Entitlement represents the membership of the Entitlement Holder in a SAR. This allows Users to request the permissions through the Catalog or select them as entries in the child form of the Application Instance containing the list of Delegated Administration Permissions. So when the Application Instance is provisioned to the User, either via request or via Access Policies, the list of permissions will be added to the User’s provisioned Entitlements. For an explanation of the Architecture and the Concepts involving Application Instances refer to Section 8 of the Administrators Guide for Oracle Identity Manager which can be found here.

Following this approach simplifies the management of Delegated Administration Permissions by defining meaningful sets of permissions and associating them to a single Role.

As previously mentioned, requests for a Role can be subject of Approval in OIM, so one or more Approval Policies can be created to control the granting of roles that will ultimately result in the assignment of administrative users into SARs.

The enforcement of the Delegated Administration Model can be automated by associating multiple Entitlements to an Access Policy tied to a Role. Some Customers may define one-to-one relationships between Roles and Entitlements by having the Access Policy provisioning only that one Entitlement when the associated Role is granted to an administrative User. Others may choose to associate a list of Entitlements to a single Role, so the Access Policy will provision a list of Entitlements in this case. Regardless of the approach, this implementation supports any granularity of associations between Entitlements and Roles.

Entitlement Definitions

In OIM 11g R2, Entitlements are created by linking a Lookup Type (which is a list of values) to a Form Field in the Child Form added to an Application Instance’s Process Form. The Form Field has a property that flags it as an Entitlement field. OIM provides a Scheduled Task called List Entitlements. This task collects the data currently present in the Lookup Types associated to Child Form Fields marked as Entitlements and creates entries in a table containing the Entitlements grouped by Application Instance. Each Application Instance has it’s own set of Entitlements.

For the purposes of representing SAR assignments as Entitlements, a Lookup Type was created using the following notation:

ScopedAdminRole:<Admin Role Name>:<Name of Organization providing the Scope for the Role>:<Cascade the permission to the sub organizations (true) | Do not Cascade Permissions to Sub-Orgs (false)>

An example of an Entitlement definition using this convention would be: ScopedAdminRole:OrclEntitlementViewer:EMEA:true - this means that users having this Entitlement will be assigned the OrclEntitlementViewer administrative role within the scope of EMEA organization and its sub-organizations.

Entitlement Provisioning

Once the Entitlements are defined, OIM can provision them along with the Application Instance representing the list of permissions.

This article illustrates the approach of using an Access Policy to provision a set of Permissions when a particular Role is granted to Users.

Since the Application Instance for the Permissions List is a Disconnected Application Instance, an invocation of a predefined SOA Composite provided by OIM out of the box will occur when an Access Policy executes the provisioning process of the Disconnected Application Instance. The out-of-the-box SOA Composite application is customized to process the Entitlements as they come in. The SOA Composite is invoked for each Entitlement to be provisioned or revoked. For more details on SOA Composites used in OIM refer to the Developers Guide for Oracle Identity Manager Section 21 which can be found here.

A Web Service, created for this implementation, invokes the OIM APIs used to assign/remove Users to/from Scoped Administrative Roles. This Web Service parses the incoming Entitlement according to the format described previously, and executes the proper operation on the Entitlement (Provision or Revoke).

The Web Service has two main methods, which are invoked when appropriate within the customized SOA Composite for Disconnected Provisioning. The listings below show the code for those two methods and some other routines:

    public AdminRoleMembership addAdminRoleMembershipFor(String userId, String roleName, String scopeId, boolean hierarchy) {
        AdminRole role = this.getAdminRoleByName(roleName);
        String orgKey = this.getOrganizationID(scopeId);
        String usrKey = this.getUserKeyFor(userId);
        AdminRoleMembership membership = new AdminRoleMembership();
        membership.setAdminRole(role);
        membership.setUserId(usrKey);
        membership.setScopeId(orgKey);
        membership.setHierarchicalScope(hierarchy);
        AdminRoleService adminRoleSvc = oimClient.getService(AdminRoleService.class);
        AdminRoleMembership foundMembership = isRoleProvisioned(usrKey, orgKey, roleName); 
        if (foundMembership == null) {
            return adminRoleSvc.addAdminRoleMembership(membership);    
        }
        else {
            return foundMembership;
        }
    }

    public boolean removeAdminRoleMembershipFor(String userId, String roleName, String scopeId, boolean hierarchy) {
        AdminRole role = this.getAdminRoleByName(roleName);
        String orgKey = this.getOrganizationID(scopeId);
        String usrKey = this.getUserKeyFor(userId);
        AdminRoleMembership membership = new AdminRoleMembership();
        membership.setAdminRole(role);
        membership.setUserId(usrKey);
        membership.setScopeId(orgKey);
        membership.setHierarchicalScope(hierarchy);
        AdminRoleService adminRoleSvc = oimClient.getService(AdminRoleService.class);
        AdminRoleMembership foundMembership = isRoleProvisioned(usrKey, orgKey, roleName); 
        if (foundMembership != null) {
            System.out.println("Role Membership " + roleName + " in Organization Key " + orgKey + " for Organization " + scopeId + " will be removed.");
            return adminRoleSvc.removeAdminRoleMembership(foundMembership);
        }
        else {
            return false;
        } 
    }

    private List getScopedAdminRoleMemberships() {
        AdminRoleService adminRoleSvc = this.oimClient.getService(AdminRoleService.class);
        return adminRoleSvc.getScopedAdminRoles();
    }

    private AdminRole getAdminRoleByName(String adminRoleName) {
        List adminRoles = this.getScopedAdminRoleMemberships();
        Iterator adminRolesIter = adminRoles.iterator();
        while (adminRolesIter.hasNext()) {
            AdminRole adminRole = (AdminRole)adminRolesIter.next();
          if (adminRole.getRoleName().equals(adminRoleName)) {
              return adminRole;
          }
        }
        return null;
    }

    private String getOrganizationID(String orgName) {
        OrganizationManager orgManager = this.oimClient.getService(OrganizationManager.class);
        Organization org;
        try {
          org = orgManager.getDetails(orgName, null, true);
          return org.getEntityId();
        } catch (OrganizationManagerException e) {
            e.printStackTrace();
            return null;
        }
    }

    private AdminRoleMembership isRoleProvisioned(String usrKey, String orgKey, String roleName) {
        AdminRoleService adminRoleSvc = oimClient.getService(AdminRoleService.class);
        System.out.println("Organization key for scoping is " + orgKey);
        List<AdminRoleMembership> memberships = adminRoleSvc.listUsersMembership(usrKey, null, orgKey, true, null);
        System.out.println("Memberships are " + memberships);
        Iterator<AdminRoleMembership> iter = memberships.iterator();
        while (iter.hasNext()) {
            AdminRoleMembership membership = iter.next();
            System.out.println("AdminRoleName in Membership is " + membership.getAdminRoleName() + " will be compared to " + roleName);
            if (membership.getAdminRoleName().equals(roleName)) {
                System.out.println("Found the membership!!!");
                return membership;
            }        
        }
        System.out.println("The membership in role " + roleName + " for user with key " + usrKey + " was not found");
        return null;
    }

The APIs work with keys, meaning that the login id of a user nor the name of the organization can be used directly in the API calls. Developers need to obtain the user key (usr_key) and the organization key (act_key) to be able to successfully call the APIs to manage AdminRoleMemberships. The documentation for the APIs used in this implementation can be found here.

Part II of this article will describe how this approach is applied to a theoretical use-case for a Delegated Administration Model.

This post is part of OIM Academy available here.

OIM Reset Password Customization Example

$
0
0

Out-of-the-box, the OIM reset password functionality is available to system administrators, and to delegated administrators who have administrative privileges on users’ accounts and have the ‘reset password’ privilege assigned to them. The data of the user who is having his/her password reset plays no role on how this functionality is presented to delegated administrators.

This post shows a way of having password reset functionality behaving differently depending on the end user data. This post is another post of the OIM Academy series.

Before going further, it is important to mention that there is a need to first understand the OIM UI customizations concepts. Apart from the OIM documentation available here, you can also check this example and this post.

Out-of-the-box, the OIM reset password functionality is available through a pop-up. The behavior of this pop-up is driven by the “XL.ResetWithGeneratedPwd” system property. The following quote from OIM documentation explains it: “If a user’s password is to be reset, then this property determines how the password is to be reset by the delegated administrator. If this property is set to true, then the password is always automatically generated. If set to false, then an additional option of setting the password manually is provided.OIM Identity console provides an easy way to reset someone’s password”.

In other words, out-of-the-box, there is only a single way of showing the out-of-the-box reset password pop-up, and such way is driven by the property mentioned above. In one configuration, delegated administrators have the flexibility of either manually provide a password or automatically generate a password; in the other configuration, only the option to automatically reset the password is available.

But customers might have a different requirement: “for external users, help desks can only trigger automatically password generation; for internal users, help desks can either manually provide a password or automatically generate a password”.

The requirement described above can be achieved with a simple UI customization plus a custom managed bean. First, some of the details on this customization:

  • The main idea is to add a custom action button to the user detail page. The button will invoke a custom managed bean to reset a user’s password (automatically generation).
  • The out-of-the-box ‘reset password’ button will be modified and a condition will be added to it. This condition determines whether or not the button will show on the user detail page
  • This blog post uses the ‘user type’ attribute to create the conditional expressions: the user details page will show OOTB ‘Reset Password’ button when a ‘Employee’ user is shown, and it will show a custom reset password button for any other ‘user type’. Any other user attribute can be used to build the expressions
  • A sandbox is needed to accommodate the UI customizations

Implementing

1. Deploying the custom managed bean

Below the code that was created as part of this example. This code must be deployed as a custom managed bean. The code is invoked when the delegated administrator confirms that he/she wants to reset the end user’s password. The code uses OIM APIs to generate a random password.

package com.oracle.iam.demo.view.pwd;

import com.oracle.iam.util.FacesUtils;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import oracle.adf.view.rich.event.DialogEvent;

import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.ui.platform.model.common.OIMClientFactory;

public class CustomPwdResetBean {

    private static Logger logger = Logger.getLogger("IAM.DEMO");

    public CustomPwdResetBean() {}

    public void confirmReset(DialogEvent evt){ 

        logger.entering(this.getClass().getName(), "confirmReset ","confirm outcome is "+ evt.getOutcome().name());

        try {
            if (evt.getOutcome().compareTo(DialogEvent.Outcome.yes) == 0) {

                String userLogin  = FacesUtils.getAttributeBindingValue("userLogin",String.class).trim();

                UserManager userMgtService = OIMClientFactory.getUserManager();   
                userMgtService.resetPassword(userLogin,true,true);

                this.setFacesMessage("Password for user "+userLogin+" has been reset successfully!");

                logger.logp(Level.FINEST, this.getClass().getName(), "confirmReset", "Reset password for user "+userLogin);
            }
        }
        catch (Exception e) {
            this.setFacesMessage("An internal error has occourred: "+e.getLocalizedMessage());
            logger.logp(Level.SEVERE, this.getClass().getName(), "confirmReset", "Error changing user status",e);   
        }
        logger.exiting(this.getClass().getName(), "confirmReset");
    }

    private void setFacesMessage(String msg) {

        FacesMessage message = new FacesMessage();
        message.setDetail(msg);
        message.setSummary(msg);
        message.setSeverity(FacesMessage.SEVERITY_INFO);

        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, message);
    }
}

2. Adding a condition in the out-of-the-box ‘Reset Password’ button

The condition is based on an EL expression that evaluates the ‘User Type’ attribute (keep in mind that internally this attribute is called ‘Role’). Such EL is created on the ‘Visible’ property of ‘Reset Password’ button. In this example, the EL is #{bindings.role.inputValue==’Employee’}:

pwdReset1

3. Creating custom UI components

Add an af:commandImageLink UI component right after the OOTB ‘Reset Password’ button. You can copy all the properties from the OOTB ‘password reset’ button to this custom button, the only property to be different is ‘Visible’, it will have a different EL #{bindings.role.inputValue!=’Employee’}. You may want to add a af:spacer as well and then reorder the components

pwdReset2

4. Manually modifying the sandbox

Export the sandox, open the zip file, and then open oracle\iam\ui\manageusers\pages\mdssys\cust\site\site\userdetails.jsff.xml in a text editor. You will see the af:commandImageLink and the af:spacer you added in the previous step. In order to provide a good user experience to the delegated administrator, add a confirm dialog and configure it to invoke the custom managed bean to reset the user’s password. When the delegated administrator clicks on the custom ‘Reset Password’ button, a confirmation dialog will show up, when he/she confirms, the managed bean is invoked and resets the password.

The screenshot below highlights what needs to be manually added to the userdetails.jsff.xml file. You can notice that the dialogListener property is configured with “#{backingBeanScope.customPwdResetBean.confirmReset}”, the customPwdResetBean is the custom managed bean deployed in step 1:

pwdReset3

5. Importing the sandbox

Zip up the manually edited file back into the sandbox zip file and then import the file back into OIM. Then make the sandbox active and test the reset password.

The screenshots below show how the results:

pwdReset4

pwdReset5

Disclaimers and observations:

  • The search user page also shows a reset password button. A similar customization can be done or you can simply hide that button, forcing delegated administrators to navigate to the user details page in order to reset someone’s password
  • The content and codes are provided “as is” and without warranties as to performance or merchantability and are just examples and for informational purpose
  • This post does not go deep in details discussing all the technologies involved in the customization, it is more of a ‘how-to’ example
  • Keep in mind that customizations can always bring performance impact, especially in environments with lots of data. This post does NOT cover any tuning, performance impact or anything like and it was not conceived with performance as an objective

OIM monitoring check-list

$
0
0

Introduction

Systematic monitoring of OIM deployments helps to reduce risk of both technical and security related issues. It also can help to avoid performance degradation that can happen because of data growth over time.

This post presents a set of topics about OIM and WebLogic monitoring, and it presents tools that can be used for both monitoring and diagnostic.This list is not intended to replace any official product documentation, instead, it should be used in conjunction with it.

This is another post in the OIM academy series. You can check the complete series here.

OIM Features

  • OIM scheduler: scheduled tasks are an essential feature of OIM. Administrators should check for things like failed tasks, long running tasks, unnecessary tasks that can be disabled, and others.
  • Open provisioning tasks: when provisioning tasks fail, they are assigned to the system administrator group (unless configured differently) and will show up in the open tasks list. The open tasks list should be checked frequently to make sure that tasks are not accumulating. Growing number of open tasks might be a symptom of an environmental problem. OIM is also capable of sending notifications out when a task fails, but the task needs to be configured for that.
  • Pending approval tasks: approval tasks that are pending for longer than expected might be a symptom of a problem. For example: notifications are not going out of OIM/SOA and approvers are not aware of the pending tasks. It also could be a symptom of communication problems between SOA and OIM.
  • Non-processed reconciliation events: accumulation of events in ‘Data Received’ or ‘Event Received’ status might be a symptom of a problem. Check here a complete list of event status. Administrators should periodically check the reconciliation events to make sure they are being correctly processed.
  • Pending audit events: when the audit events creation rate is higher than the audit events processing rate, events will start accumulate in the AUD_JMS table. The ‘Issue Audit Message’ scheduled task must be properly configured to handle the load. Accumulations of events in the AUD_JMS table can also be a symptom of event processing failure. Administrators should monitor the table growth and space consumption on the database side.
  • Data growth: OIM transaction data will grow over time if proper archival and purge processes are not in place. Make sure that the processes are in place, that their frequency is according to the expectation around data growth. The archival and purge processes take care of four different types of data and it is documented here:
    • Orchestration: data related to the transactions that happens over users, roles, organizations and provisioning.
    • Request: data related to requests raised in OIM.
    • Reconciliation: data generated by the connectors and the reconciliation engine.
    • Provisioning: data related to the connectors provisioning tasks.

Tools

  • DMS Metrics: OIM uses Oracle Dynamic Monitoring Service feature to report internal metrics. A lot of metrics are available through DMS, including average, maximum and minimum execution time for provisioning adapters, client API login, event handlers and scheduled tasks. DMS metrics are accessible through http://admin_server:port/dms, WebLogic domain administrator credentials can be used to access it. DMS metrics can, among other things, be used to find bottlenecks in OIM operations. More information about DMS is found here.
  • Diagnostic dashboard: the dashboard is a tool that provides diagnostic of an OIM deployment. It runs as a separate Web application deployed to OIM server/cluster. It does not bring any considerable performance impact to OIM. Instructions on how to deploy Diagnostic Dashboard are found here.

Infrastructure

  • WebLogic resources: it is also important to monitor WebLogic resources
    • Data-sources: are the data sources well sized? WebLogic console offers a page that contains a set of data source usage numbers like peak number of connections in use, average number of connections in use, number of leaked connections, and so on
    • JMS queues: make sure that the number of pending messages is not growing over time
    • Cluster: WebLogic console offers live cluster information like frequency of servers dropping from the cluster and others.
    • Stuck threads: WebLogic is capable of notifying administrators of threads that have been running for longer than a specific threshold. Although WebLogic considers such threads as stuck, it does nothing to address possible issues. Long running threads might be an indication of problems
  • JVM and OS: as any other Java based application, it is important to monitor the operating system and the JVM resources to make sure that the CPU, memory, IO and other factors are not imposing performance penalties. There are plenty of tools that can be used for that, but this is a subject to another post.

This post was created with the help of my colleagues Rob Otto and Pulkit Sharma. Thanks to them for sharing their ideas.

Logging in OIM custom code

$
0
0

Proper logging is one of the main considerations during custom development. This is no different in OIM projects in which custom code is being developed and deployed to OIM. Proper logging is fundamental part of development, helping in finding issues, fixing them and also in reporting relevant runtime conditions.

This post shows how to leverage the Oracle Fusion Middleware infrastructure in which OIM runs in order to create proper logging information from custom code. It is not the intent of this post to cover all logging considerations; there are plenty of materials on the internet and book stores to cover the basics.

OIM running on WebLogic leverages ODL for logging. ODL stands for Oracle Diagnostic Logging, the OIM related documentation is available here. This documentation provides details on the out-of-the-box loggers, how they can be changed, where the logging statements go, and what each log level will produce. The image below depicts some of the OIM loggers:

oim_logging1When it comes to proper logging in your custom code, the task is pretty simple. Below a very basic example of an OIM event handler containing some logging related code:

...
import java.util.logging.Level;
import java.util.logging.Logger;

public class MyCustomEventHandler implements PostProcessHandler {
    
    private static Logger myLogger = Logger.getLogger("MY.CUSTOM.LOGGER");
    
    public EventResult execute(long l, long l1, Orchestration orchestration) {
       
        myLogger.entering("MyCustomEventHandler", "execute");
     
        try {
            myLogger.logp(Level.FINEST, "MyCustomEventHandler", "execute", "Trying to convert X to an integer");
            
            int x = Integer.parseInt("x");
        }
        catch (NumberFormatException e) {
            myLogger.logp(Level.SEVERE, "MyCustomEventHandler", "execute", "Error during operation "+e.getMessage(), e);
        } 
        myLogger.exiting("MyCustomEventHandler", "execute");
        
        return new EventResult();
    }

...

Some important details about the code above:

  • Although it could, it does not use ODL APIs, it uses plain java.util.logging classes. At runtime, FMW stack redirects the java.util.logging logging to ODL logging. This makes your life easier when compiling the code as you do not need extra libraries.
  • It is very important to mention that the code is intentionally forcing a Java exception by trying to parse an alpha String into a Java integer. The intention was to force the exception to happen for demonstrating the logging use
  • The logger being used is name ‘MY.CUSTOM.LOGGER’.
  • The code is an event handler, but the same logging approach can be used in other customizations like scheduled tasks, notification providers, plug-ins in general and also in UI customizations
  • There are different log levels being used by the code. Below a simplified table showing the mapping between ODL and java.logging levels (click here for a complete table):
Java Log Level ODL Level
SEVERE ERROR:1
WARNING WARNING:1
INFO NOTIFICATION:1
CONFIG NOTIFICATION:16
FINE TRACE:1
FINER TRACE:16
FINEST TRACE:32

When the custom code is loaded for the first time, ODL will create the proper logger instances, and they will be exposed through /em console. Then the logging level can be changed accordingly to the needs. The image below depicts the custom logger and it shows how log level changes can be persisted to survive server restarts:

oim_logging2

And below the excerpt from the log file with the log statements generated by the code above:

[2014-06-03T12:57:53.284-07:00] [wls_oim1] [WARNING] [ADF_FACES-30118] [oracle.adfinternal.view.faces.renderkit.rich.SelectItemUtils] [tid: [ACTIVE].ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: xelsysadm] [ecid: 004yjFhM1xh2rIQ5Ib_Aif0006Tz000JZ4,0:3] [APP: oracle.iam.console.identity.self-service.ear#V2.0] [DSID: 0000KPZJ3LD2rIQ5Ib_Aif1JZYPa000008] [URI: /identity/faces/home] No help provider found for helpTopicId=modify_user.
[2014-06-03T12:57:53.605-07:00] [wls_oim1] [NOTIFICATION] [] [OAM Notification Logger] [tid: [ACTIVE].ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: oiminternal] [ecid: 004yjFhM1xh2rIQ5Ib_Aif0006Tz000JZ4,0] [APP: oim#11.1.2.0.0] Notification status true

[2014-06-03T12:57:53.892-07:00] [wls_oim1] [TRACE:16] [] [MY.CUSTOM.LOGGER] [tid: [ACTIVE].ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: oiminternal] [ecid: 004yjFhM1xh2rIQ5Ib_Aif0006Tz000JZ4,0] [APP: oim#11.1.2.0.0] [SRC_CLASS: MyCustomEventHandler] [SRC_METHOD: execute] ENTRY
[2014-06-03T12:57:53.892-07:00] [wls_oim1] [TRACE:32] [] [MY.CUSTOM.LOGGER] [tid: [ACTIVE].ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: oiminternal] [ecid: 004yjFhM1xh2rIQ5Ib_Aif0006Tz000JZ4,0] [APP: oim#11.1.2.0.0] [SRC_CLASS: MyCustomEventHandler] [SRC_METHOD: execute] Trying to convert X to an integer
[2014-06-03T12:57:53.892-07:00] [wls_oim1] [ERROR] [] [MY.CUSTOM.LOGGER] [tid: [ACTIVE].ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: oiminternal] [ecid: 004yjFhM1xh2rIQ5Ib_Aif0006Tz000JZ4,0] [APP: oim#11.1.2.0.0] Error during operation For input string: "x"
java.lang.NumberFormatException: For input string: "x"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
        at java.lang.Integer.parseInt(Integer.java:449)
        at java.lang.Integer.parseInt(Integer.java:499)
        at oracle.iam.demo.eventhandlers.MyCustomEventHandler.execute(MyCustomEventHandler.java:27)
        at oracle.iam.platform.kernel.impl.OrchProcessData.runPostProcessEvents(OrchProcessData.java:1490)
        at oracle.iam.platform.kernel.impl.OrchProcessData.runEvents(OrchProcessData.java:896)
        at oracle.iam.platform.kernel.impl.OrchProcessData.executeEvents(OrchProcessData.java:357)
        at oracle.iam.platform.kernel.impl.OrchestrationEngineImpl.resumeProcess(OrchestrationEngineImpl.java:948)
        at oracle.iam.platform.kernel.impl.OrchestrationEngineImpl.resumeProcess(OrchestrationEngineImpl.java:978)
        at oracle.iam.platform.kernel.impl.OrhestrationAsyncTask.execute(OrhestrationAsyncTask.java:134)
        at oracle.iam.platform.async.impl.TaskExecutor.executeUnmanagedTask(TaskExecutor.java:99)
        at oracle.iam.platform.async.impl.TaskExecutor.execute(TaskExecutor.java:69)
        at oracle.iam.platform.async.messaging.MessageReceiver.onMessage(MessageReceiver.java:68)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at com.bea.core.repackaged.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131)
        at com.bea.core.repackaged.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119)
        at com.bea.core.repackaged.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy411.onMessage(Unknown Source)
        at weblogic.ejb.container.internal.MDListener.execute(MDListener.java:583)
        at weblogic.ejb.container.internal.MDListener.transactionalOnMessage(MDListener.java:486)
        at weblogic.ejb.container.internal.MDListener.onMessage(MDListener.java:388)
        at weblogic.jms.client.JMSSession.onMessage(JMSSession.java:4659)
        at weblogic.jms.client.JMSSession.execute(JMSSession.java:4345)
        at weblogic.jms.client.JMSSession.executeMessage(JMSSession.java:3821)
        at weblogic.jms.client.JMSSession.access$000(JMSSession.java:115)
        at weblogic.jms.client.JMSSession$UseForRunnable.run(JMSSession.java:5170)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:545)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)


[2014-06-03T12:57:53.892-07:00] [wls_oim1] [TRACE:16] [] [MY.CUSTOM.LOGGER] [tid: [ACTIVE].ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: oiminternal] [ecid: 004yjFhM1xh2rIQ5Ib_Aif0006Tz000JZ4,0] [APP: oim#11.1.2.0.0] [SRC_CLASS: MyCustomEventHandler] [SRC_METHOD: execute] RETURN

By using the approach described in this post, the custom logging statements will be written to the <managed-serve-name>-diagnostics.log located, in the out-of-the-box configuration, under $DOMAIN_HOME/servers/<server_name>/logs. You can also create your own ODL log handlers and redirect your custom logging to a different log file, check the documentation here on how to do that. The Fusion Middleware logging infrastructure used by OIM has been the same since first 11g release, so this blog post applies to all the 11g versions. Have fun!

Monitoring OIM R2 PS2 Orchestration

$
0
0

The OIM R2 PS2 (11.1.2.2.0) release provides a great new feature: monitoring of OIM orchestration processes through Enterprise Manager console.

Such feature provides the capability of querying orchestration data to check orchestration processes details. For example, you can check what happened during a user modification operation, or you can get details of failed orchestration processes, such details can help you to fix issues in your environment. It is also possible to check configuration information, like which event handlers are defined for a specific orchestration process.

To access the new feature you have to:

  • Point your browser to http://admin_server:port/em
  • Log in with domain administrator credentials
  • On the left menu, open the ‘Identity and Access’ menu item
  • Right click on ‘OIM’ menu item
  • In the opened context menu, click on ‘Administration’

After the steps above, the following page will show:

oim_em11

The Dashboard page shows the most recent orchestration operation instances that happened in OIM. It contains a table with all the orchestration operation instances and a specific table for the failed orchestration operation instances.

If you click on the Operations tab, you can check the configuration of the different orchestration operations, including the event handlers configured for each of the them. You can verify the order of the out-of-the-box event handlers so you can configure custom ones with the right order. You can also verify the custom event handlers deployed to your environment. The image below depicts this tab and highlights a custom event handler definition:

oim_em3

The third tab provides you with a search form that you can use to search for specific orchestration operations instances. You can filter your search by a particular operation, by beneficiary, by operation id and some other fields. The screenshot below depicts a search filtered by beneficiary. Note the different orchestration operations on the left table column:

oim_em4

But the most interesting and useful feature of this new monitoring tool is the ability to investigate the failed orchestration operations and find the failure causes. There are a couple of different ways of doing that, so let’s first go back to the Dashboard tab: in this tab, there are two links available in the each row of the Failed Operations table. The first link is on the Operation Id column, the second one is on the ECID column, the screenshot below depicts that. The failed orchestration operation was an attempt to update some user’s attributes, in other words, it was a Modify User operation. Let’s follow the links on the failed operation instance below and try to figure the issue out:

oim_em6

Clicking on the Operation ID column link will take you to a new tab showing the orchestration operation instance details, including the sequence of the executed event handlers. Depending upon the failure cause, a link on the ‘Error Message’ column might be available, so you can click on it to get more details. The two screenshots below depict that:

oim_em7

oim_em8

Although the full stack trace is available, it is not possible to conclude what has caused the orchestration operation to fail. So the other route to take is to go back to the Dashboard page and click on the link in the ECID column.This link is very interesting and it will take you to a different page; a page that is actually another feature provided by Enterprise Manager console: diagnostic log files analyses. And, to make things even better, /em console will filter the diagnostic contents based on the ECID value that you clicked on, the screenshot below depicts that:

oim_em9

So, according to the log statements in the screenshot above, OIM was not able to get a connection to the LDAP server in order to execute the user modification (the OIM environment used to build this post is configured with LDAP Synch), therefore the User Modification orchestration operation failed.

It is important to mention that the information shown by the monitoring tool is based on the data from the orchestration tables. Such data gets cleaned up according to the configuration of the OIM Data Purge scheduled job. It is always a good practice to configure this job according to your needs so you have control over the data growth in some of the OIM operational tables.

Have fun!

Exposing User System Attributes in OIM 11gR2PS2 GUI Customization

$
0
0

Introduction

Recently while working with a customer to help with an upgrade from OIM 11gR1 to 11gR2PS2, one interesting request came up regarding OIM GUI customization.

The requirement was to expose some User System Attributes that in R1 were directly available in the GUI customization data but in R2 are not exposed in the GUI Customization options.

There is a way in R2 to easily expose the data using a custom Managed Bean along with some GUI tweaks.

The process for customizing the OIM UI is easy enough and well documented in the OIM Customization Guide.

The following content takes you through the steps for exposing the User System Attributes.

The Requirement

Like said before, we need to expose some User System Attributes that are not directly available in the GUI. In this example, we are going to expose:

usr.usr_create: user creation date;

usr.usr_pwd_expired: if the user password is expired;

usr.usr_update: user update date;

The page where we will expose this data is the User Details in the OIM Identity Self Service and we want to show something like that:

img1

The Solution

To implement our requirement we will have to:

1. Develop a custom Managed Bean, where we will obtain the user that is being inspected in the OIM User Details page and the required attributes;

2. Export our project as a ADF Library Jar File, which will result in a JAR file;

3. Repackage our JAR file into the Custom Library placeholder, oracle.iam.ui.custom-dev-starter-pack.war;

4. Redeploy the customizations to OIM as a Library;

5. Reference the Managed Bean properties (usr_create, usr_pwd_expired and usr_update) in the User Details Page.

Develop a Custom Managed Bean

The OIM guide to Interface Customizations has the complete details on how to set up the JDeveloper ViewController project, configuration and deployment steps.

I will not go over those details here as it is out of the scope of this post, but the important things to have in mind are:

1. Make sure you create an ‘ADF ViewController Project';

2. Set the correct Library and Classpath dependencies from “IDM_HOME/server/jdev.lib” folder, as described in the Interface Customization guide;

3. Make sure your Managed Bean has scope set as “backingBean”;

4. Make sure your project has deployment profile configured as “ADF Library JAR File”, as described in the guide.

5. Add a Managed Bean to your project, as described in the guide, and name it as ExposeUserSystemAttributesMBean, for example.

The important implementation details of the Managed Bean are as follows:

• Declare the attributes you want to expose (and auxiliary class properties) and generate getters and setters:

    //System Attributes to be exposed on the User Details GUI
    private String usr_create = "";
    private String usr_update = "";
    private String usr_pwd_expired = "";
    private SimpleDateFormat sdf = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy");
    private static Logger log = Logger.getLogger("oracle.iam.ui.custom");

• Since it is a Request Bean, and it will be instantiated for every request made to the User Details page, so it makes sense to initialize the attributes in the Bean constructor:

    public ExposeUserSystemAttributesMBean() {
        log.entering("ExposeUserSystemAttributesMBean", "ExposeUserSystemAttributesMBean()");
        getUserSystemAttribute();
        log.exiting("ExposeUserSystemAttributesMBean", "ExposeUserSystemAttributesMBean()");
    }

• The actual work:

    private void getUserSystemAttribute() {
        //Evaluates the EL expression, obtaining the user login being inspected in the OIM GUI
        String usr_lgn = FacesUtils.getValueFromELExpression("#{bindings.userLogin.inputValue}").toString();

        //Gets the UserManager object, so we can search for the User object
        UserManager userMgr = OIMClientFactory.getUserManager();

        //Sets which User Attributes will be returned populated in our User object
        HashSet<String> searchAttrs = new java.util.HashSet<String>();
        searchAttrs.add(UserManagerConstants.AttributeName.USRCREATED.getId());
        searchAttrs.add(UserManagerConstants.AttributeName.USRUPDATED.getId());
        searchAttrs.add(UserManagerConstants.AttributeName.PWD_EXPIRED.getId());
        
        try {
            //Obtains the User Object, searching by USER_LOGIN. If USER_LOGIN is not unique (by default it is)
            //OIM API will throw an SearchKeyNotUniqueException
            User usr = userMgr.getDetails(UserManagerConstants.AttributeName.USER_LOGIN.getId(),usr_lgn,searchAttrs);
            
            //Sets the Bean creation_date property from the User Object
            setUsr_create(sdf.format(usr.getCreationDate()));

            //Some system users (xelsysadm, oiminternal) has usr_pwd_expired=null
            //throwing a NumberFormatException when we try to parse it
            try {
                Boolean is_pass_exp = (Integer.parseInt(usr.getPasswordExpired()) != 0);
                //Sets the Bean usr_pwd_expired property from the User Object
                setUsr_pwd_expired(String.valueOf(is_pass_exp));
            } catch (NumberFormatException nfe) {
                //Sets N/A since in those cases usr_pwd_expired=null
                setUsr_pwd_expired("N/A");
            }

            String u_updt = usr.getAttribute(UserManagerConstants.AttributeName.USRUPDATED.getId()).toString();
            //Sets the Bean usr_update property from the User Object
            setUsr_update(u_updt);     
        } catch (NoSuchUserException nsue) {
            log.log(Level.SEVERE, "Error while getting User System Attributes, caused by: "+nsue.getMessage()+". Check the logs for more details");
            nsue.printStackTrace();
        } catch (UserLookupException ule) {
            log.log(Level.SEVERE, "Error while getting User System Attributes, caused by: "+ule.getMessage()+". Check the logs for more details");
            ule.printStackTrace();
        } catch (SearchKeyNotUniqueException sknue) {
            log.log(Level.SEVERE, "Error while getting User System Attributes, caused by: "+sknue.getMessage()+". Check the logs for more details");
            sknue.printStackTrace();
        } 
    }

Export your project as ADF Library Jar File

If you configured your project deployment profile correctly, all you need to do in JDeveloper is right click your project name, select ‘Deploy’ option, and select your deployment profile:


img2

This will generate the JAR file in the location you configured in your deployment profile.

Repackage our JAR file into the Custom Library placeholder

In order to deploy customizations to OIM GUI, we need to repackage our artifacts into the Library placeholder.

The library placeholder is a file called oracle.iam.ui.custom-dev-starter-pack.war which can be found in “IDM_HOME/server/apps/” directory.

Make a backup copy of file. Copy the original oracle.iam.ui.custom-dev-starter-pack.war to your workstation.

Open the file using any ZIP utility, like 7-Zip. Copy your JAR file (in my example it is called “adflibOIMUserSystemAttributes.jar”) to “oracle.iam.ui.custom-dev-starter-pack.war\WEB-INF\lib\”. If the lib folder does not exist into WEB-INF, you will have to create it.

The resulting file should look like this:

img3

Copy the modified “oracle.iam.ui.custom-dev-starter-pack.war” back to “IDM_HOME/server/apps/” directory.

Redeploy the customizations to OIM as a Library

Log in to Weblogic Admin Console and go to “Deployments”, click “Lock and Edit”, select “oracle.iam.ui.custom(11.1.1,11.1.1)” from the list and click “Update” button.

img4

The update process will ask you to select which referencing applications should be updated as well in the process, select both “oracle.iam.console.identity.self-service.ear (V2.0)” and “oracle.iam.console.identity.sysadmin.ear (V2.0)”, click Finish then “Activate Changes”.

img5

Reference the Managed Bean properties in the User Details Page

To expose our system properties in the User Details page we need to login to OIM Identity Self Service, create and activate a Sandbox first.

Then go to “Administration > Users” and search for a user. In the User Details page, click “Customize” then “View > Source”.

This opens a frame on top of the User Details page, where we can add more fields and data to our page.

With your mouse, scroll to the page section where you want to add the managed beans fields, in my case, I chose “Other Attributes”, and click the area marked with a blue square:

img6

Select the “panelFormLayout” and click “Add Content”

img7

From the list, select “Web Components” then “Panel with Label and Message”, click on the “Add” link, and “Close”.

img8

A “panelLabelAndMessage” element is added to the “panelFormLayout” we selected before.

img9

Now, select the recently added “panelLabelAndMessage” and click “Edit” button. Set the Label property to one of our properties label, like “User Update Date” and click “OK”.

img10

Select the “panelLabelAndMessage” again but now click “Add Content” button. From the list select “Web Components” then “Output Text”, click on the “Add” link and click “Close”.

img11

Select the “outputText” we just added and click “Edit” button. In the dialog that appears, remove the default Value for the component, and click in the small downward arrow in the right side, to open the Expression Builder.

img12

In the next dialog, select “Type a value or expression” and enter “#{backingBeanScope.exposeUserSystemAttributes.usr_update}”, without quotes.

The backingBeanScope part of the EL expression is the standard way ADF references the backing beans (we defined the scope in the adfc-config.xml) in the JSFF/taskflow.

The exposeUserSystemAttributes part is the name we gave to our Managed Bean (also defined in the adfc-config.xml).

Finally, the usr_update part is the bean property we’re exposing in our Managed Bean.

img13

Repeat the same procedure for each of the User System attributes fields we’re exposing in our Managed Bean.

The location and the way you expose them is a design decision and OIM is flexible enough to allow you a few options, choose what suits you best.

Logging and troubleshooting

If you implement a logger for our custom Managed Bean you can set its log levels in Enterprise Manager once our class in instantiated for the first time.

For instructions on how to do it, please take a look at my colleague’s excellent post on the subject: Logging in OIM Custom Code

You can easily insert log messages for any granularity you wish in your code and check them in the oim_server-diagnostic.log files for troubleshooting or runtime information purposes.

In case you accidentally published your SandBox or you realized you need to revert back the changes, you can follow the procedure here or follow Support Note “OIM 11gR2: How to Roll back A Published Sandbox (Doc ID 1496179.1)”.

OIM Access Policy Harvesting

$
0
0

OIM R2 PS2 delivers a long time expected functionality: access policy harvesting. This new feature adds more flexibility to OIM access policies usage.

This is another post in the Oracle Identity Manager Academy from the Fusion Security Blog. for the entire post list click here.

In order to understand what this new feature brings, let us first remind the past: in previous OIM releases it was not possible to associate reconciled accounts to access policies. The impact of this restriction can be described this way: a reconciled account could not be changed or revoked by a configured access policies. Explaining from a different angle: access policies could manage only the accounts initially provisioned through access policies; they could not manage direct provisioned and/or reconciled accounts. The same was true for accounts loaded through the use of the bulkload utility.

Because of this restriction, some OIM customers implemented workarounds like manually modifying OIM database to associate accounts to access policies, and forcefully provision accounts through access policy and, once the provisioning fails, manually complete the provisioning tasks.

The restriction is gone and OIM can now associate reconciled accounts and access policy properly, therefore access policies can now manage accounts that were not provisioned through them. This is a very nice feature, especially because a lot of customers rely on target reconciliation to bring existing user’s accounts into OIM, and the very same is true for bulkloading of accounts.

The following statements are available in OIM release notes:

“Oracle Identity Manager enables you to link the reconciled and bulk loaded accounts to pre-existing access policies by running the ‘Evaluate User Policies’ scheduled task, and therefore, such reconciled and bulk loaded accounts can be managed via access policies. The linking of access policies to reconciled or bulk loaded accounts is also referred to as access policy harvesting.

Only reconciled and bulk loaded accounts are linked with access policy, which means that the direct or request-based provisioned accounts are not considered for access policy harvesting.”

It is important to pay attention to the second statement in the excerpt above: only reconciled accounts are considered for access policy harvesting.

There are a few required configuration steps in order to enable access policy harvesting, such steps are documented here.

Have fun!

Viewing all 54 articles
Browse latest View live


Latest Images