Saturday, June 27, 2015

Send email to user from OAAM 11G

We came across one of the interesting requirement few months back that is, when user either blocked or updated his/her self-profile in OAAM, user should notified with an email about their status. Even though OAAM has ability to send email to user using java mail API but, it is hard to main the template. We came out with option that design and create email templates in OIM as all emails templates in centralized in one location and easy to maintain. OAAM will make call to OIM to send emails to user.

Note: OIM-OAM-OAAM-OID-OVD were integrated together.

In this post, we are going to see how to read and connect to OIM from OAAM. Since OIM and OAAM were integrated, OIM connection details were maintained in OAAM properties. If Credential Store Factory (CSF) is enabled in OAAM then, OIM credentials available in Weblogic CSF. Otherwise, it will be in OAAM properties.

Make sure you need to pass OIM user login id as well, email template which you have created in OIM to the below method.
You need to import the below classes in order to read credentials from weblogic CSF:
import oracle.oaam.common.util.CSFUtil;
import oracle.security.jps.service.credstore.PasswordCredential;
private void sendEmailFromOIM(String userLogin, String emailTemplate)
{
 try {
  OIMClient mOimClient = null;
  String oimUsername = null;
  String oimPassword = null;

  boolean isCSFEnabled = BharosaConfig.getBoolean("oaam.oim.csf.credentials.enabled", false);
  System.out.println("isCSFEnabled : " + isCSFEnabled);

  if (isCSFEnabled) {
   // Read OIM Credentials from CSF if enabled. 
   PasswordCredential oimCredentials = (PasswordCredential)CSFUtil.getCredential("oaam", "oim.credentials");
   if (oimCredentials != null) {
    oimUsername = oimCredentials.getName();
    oimPassword = new String(oimCredentials.getPassword());
   } else {
    String message = "OIM CSF Credentials flag 'oaam.oim.csf.credentials.enabled' is set to true but there are no credentials under 'oim.credentials' alias";
    System.out.println("message : " + message);
   }
  } else {
   // Read OIM Credentials from OAAM properties. 
   oimUsername = BharosaConfig.get("oaam.oim.admin.loginid");
   oimPassword = BharosaConfig.get("oaam.oim.admin.password");
  }

  // Print OIM credentials :: TESTING PURPOSE ONLY
  System.out.println("oimUserName : " + oimUsername);
  System.out.println("oimPassword : " + oimPassword);
  
  String oimUrl = BharosaConfig.get("oaam.oim.url");
  System.out.println("oimUrl : " + oimUrl);

  String oimInitCtxFactory = BharosaConfig.get("oaam.oim.initial.context.factory", "weblogic.jndi.WLInitialContextFactory");
  System.out.println("oimInitCtxFactory : " + oimInitCtxFactory);

  String xlHomeDir = BharosaConfig.get("oaam.oim.xl.homedir", "${oracle.oaam.home}/../designconsole");
  System.out.println("xlHomeDir : " + xlHomeDir);

  String authCfg = BharosaConfig.get("oaam.oim.auth.login.config", "${oracle.oaam.home}/../designconsole/config/authwl.conf");
  System.out.println("authCfg : " + authCfg);

  oimUrl = StringUtil.expandProperties(oimUrl);
  oimInitCtxFactory = StringUtil.expandProperties(oimInitCtxFactory);
  xlHomeDir = StringUtil.expandProperties(xlHomeDir);
  authCfg = StringUtil.expandProperties(authCfg);

  System.setProperty("XL.HomeDir", xlHomeDir);
  System.setProperty("java.security.auth.login.config", authCfg);

  Hashtable env = new Hashtable();
  env.put("java.naming.factory.initial", oimInitCtxFactory);
  env.put("java.naming.provider.url", oimUrl);

  System.out.println("connecting to oim....");
  // Instantiate OIMClient
  mOimClient = new OIMClient(env);
  mOimClient.login(oimUsername, oimPassword.toCharArray());
  System.out.println("oim connection established");

  // Data required for email 
  HashMap emailData = new HashMap();
  emailData.put("Display_Name", userLogin);
  
  //Instantiate Notification Service for email
  NotificationService notifySrvc = (NotificationService)mOimClient.getService(NotificationService.class);
  NotificationEvent emailEvent = new NotificationEvent();
  emailEvent.setTemplateName(emailTemplate);
  emailEvent.setSender("NOTIFICATIONADMIN");
  emailEvent.setUserIds(new String[] { userLogin });
  emailEvent.setParams(emailData);
  
  try {
   // Send email to user
   notifySrvc.notify(emailEvent);
  } catch (Exception e) {
   System.out.println("Error on sending email : " + e.getMessage());
   e.printStackTrace();
  }
 }
 catch (Exception e) {
  System.out.println("OIM Changes :" + e.getLocalizedMessage());
  e.printStackTrace();
 }
}

NOTE: In this example, I have printed all values including OIM credentials for testing purpose. Make sure you should not print in any of value in your environment.

Wednesday, June 10, 2015

OIM 11GR2 Disconnected resource creation and provision

This post covers detailed steps about creation and provision of disconnected resource. I hope this will help for new learners who are pretty much interested learning about connectors. And also, it will handy for quick reference.

High Level Steps:
  1. Creation of  IT Resource Type Definition
  2. Creation of Resource Object
  3. Creation of  IT Resource
  4. Creation of User Form
  5. Creation of Process Definition
  6. Creation of Application Instance
  7. Provisioning Resource

Creation of IT Resource Type Definition for Virtual Resource

IT Resource Type Definition represents the resource connection details. Since this is virtual resource that is not going to interact with external system, we can have with dummy values.

Steps to create IT Resource Type Definition:
  1. Log in to the OIM Design Console.
  2. Click IT Resource Type Definition under Resource Management.
  3. Create a new IT Resource Type Definition with the Server Type defined as IT_SSU.
  4. Add parameter Field Name as “Name” and Default Field Value is “SSU” as per below screen shot:


Creation of Resource Object for Virtual Resource

The resource object is OIM representation of resource.

Steps to create Resource Object:
  1. Log in to the OIM Design Console.
  2. Click Resource Objects under Resource Management.
  3. Create a new resource object with the name RO_SSU and save it.

This Resource Object should have below values:
·        Type as Application
·        In Status Definition tab, you should be checked “Enabled” and “Provisioned”



Creation of IT Resource for Virtual Resource

Login in to OIM system admin console and create new IT Resource with name “ITR_SSU”. Since this is dummy resource so, we can give any dummy value to IT Resource parameters. I have given parameter “Name” as Value “SSU”.



Creation of User Form for Virtual Resource

Process form contains provisioning details that needs to be pass to target system. Since this is virtual resource, I have set default value for all field values.

Steps to create process form:
  1. Log in to the Oracle Identity Manager Design Console.
  2. Click Form Designer under Development Tools.
  3. Create a new form with the Table Name UD_SSU as per below screen shot. Save it.
  
  1. Click on Properties tab, add the properties Type as “IT_SSU”, Required as “true”, and IT Resource as “ITR_SSU” for ITResource column as per below screen shots.

  1. Save it.

Creation of Process Definition for Virtual Resource

Process definition defines the behavior of connector. Every operation corresponding task associated with it. In this post, we are covering only provisioning and deprovisioning.

Steps to create Process Definition
  1. Log in to the Oracle Identity Manager Design Console.
  2. Click Process Definition under the Process Management tab.
  3. Create a new process definition and name it PD_SSU
  4. Select Provisioning as the Type of process.
  5. Provide the resource Object Name for the identity connector and select RO_SSU.
  6. Provide the process form Table Name and select UD_SSU.
  7. Save it

  1. Add process task and name it Delete User. This will trigger when a resource is deprovisioning for user.
Create task with name “Delete user”. Save it.

Make sure you should checked the box Conditional and unchecked the Allow Multiple Instances. This is optional, you can set the retry count and retry period in minutes in order to retry failed task by OIM.


In the integration tab, choose  adapter  “tcCompleteTask” because, this is not going to interact with real world target system. 

Add response for complete with status “R”


In Task to Object Status Mapping, the status of the complete to be displayed in Resource history.


  1. Add process task and name it Create User. This will trigger when a resource is provisioning for user.

Create task with name “Create User” and description as your wish. Save it.

Make sure you should unchecked the Conditional as well, Allow Multiple Instances. This is optional, you can set the retry count and retry period in minutes in order to retry failed task by OIM.


In the integration tab, choose  adapter  “tcCompleteTask” because, this is not going to interact with real world target system.


Add response for complete with status “C”


In undo/recovery tab, add the deprovisioning task that is “Delete User”

In Task to Object Status Mapping, the status of the complete to be displayed in Resource history.


Save all process definition changes.

Creation of Application Instance

  1. Log in to OIM system admin console with admin privileges.
  2. Create sandbox “SSU” and activate for Application Instance.
  3. Create New Form “FORMSSU” for resource object “RO_SSU”.
  1.  Create new application instance AppSSU1

  1. Export the sandbox “SSU” in case if you propagating from one environment to another. Otherwise, you can publish it.

Note: Once you created Application Instance, you should run “Catalog Synchronization” job in order to make available newly created app instance to users.


Provision Resource to User

Testing provisioning a resource to user:

  1. Log in to OIM identity console
  2. Select any user and go to accounts tab then, click on “Request Accounts” and it will take you to Catalog page.
  3. Select the application instance “AppSSU1” and then click on “Add to Cart”.
  4. Click on “Checkout” and then, “Ready To Submit”.
  5. Finally click on Submit and the resource will be provisioned to user.

OAAM 11G Redirect User To Security Profile Setting Page

I came across one of the interesting requirement few months back.  Users are migrating from their existing legacy system to Oracle IAM. During migration, user should authenticate against legacy trusted system instead of IAM directory service and should redirect them to product's security profile setting in order to set their profile.

Here we had two challenge's in the requirements are,
    1. Implementing custom authentication instead of product's OOTB authentication.
    2. Redirection to product's security profile setting


Note: Oracle won't provide any support as we are doing customization at extensively.

1. Authentication Against Legacy System
Once user enters their credentials, a custom servlet  placed in default flow that, intercept the user request and does validation against legacy system.


2. Redirect to Security Profile Setting Page
Once user authentication successful, user redirected to migration page. Upon successful migration, user will be redirected to product's profile setting page to complete security profiles.

In order to redirect security profile page, we should do below changes custom servlet:

  i. Create user object if does not exists otherwise, retrieve user from OAAM using OAAM API. Mostly, user creation will not need as OAAM maintains user details in persistent cookie in the browser.

        User Exists In OAAM
        Retrieve the user id from the session data.
UIOSessionData sessionData = UIOSessionData.instance(request);
VCryptAuthUser user = sessionData.getClientAuthUser(); 
        User Does Not Exists In OAAM
        Whenever user logs in, OAAM creates the user account and will be stored in vcrypt_user table. If user does not exist then, create OAAM user object and set in session data.

// Set user attributes such as user id, customer id, group, status, preference
VCryptAuthUser user = new VCryptAuthUser();

// Create User using Private API
user = getBharosaProxy().createUser(user);

// Retrieve user object 
user = BharosaProxyImpl.getInstance().getUserByLoginId(“chella”);
user.setCustomerGroupId(“Default”);
sessionData.setClientAuthUser(user);
sessionData.setCustomerId(user.getCustomerId());
sessionData.setLoginId(user.getLoginId());
sessionData.setUserEnteredLoginId(user.getLoginId());

 ii. Set authentication result as success and user authenticated should be set to true because, this makes OAAM to believe that user is authenticated successful.
sessionData.setAuthResult(0); // Success
sessionData.setIsAuthenticated(true); // Authenticate True is success

iii. Update authentication status before redirecting
UIOUtil uioUtil = UIOUtil.instance();
uioUtil.updateAuthStatus(sessionData);

 iv. Redirect user to oaam server’s updateLoginStatus.do in order to user set security profile setting.

  v. If user profile was not set already then, user will be prompted to choose image and security profile questions.  Otherwise, user will be prompted to answer challenge questions.

Friday, May 22, 2015

List of resource provisioned to user in OIM

Query to list the resource that are in different status for given user.

Table Name
Table Description
OIU
Object Instance Request Target User Information.

Associate user information to the resource object instance when provisioning take places.
OST
Object Status Information.
OBI
Object Instance Information.

Once resource provisioned to user, OIM created resource instance for each resource provisioning.
OBJ
Resource Object definition information

This contains detail about resource such as resource name, auto-save enable or not and auto-prepopulate is enable or not, and whether or not the resource object allows multiple instances.
USR
It contains user information like login id, password, etc.,

SQL Query:
select oiu.oiu_key, oiu.obi_key, oiu.orc_key, ost.ost_status, obj.obj_name, obj.obj_key,oiu.req_key 
from oiu 
inner join ost on oiu.ost_key = ost.ost_key 
inner join obi on oiu.obi_key = obi.obi_key
inner join obj on obi.obj_key = obj.obj_key 
where oiu.usr_key =(select usr_key from usr where usr_login='chellappan.sampath');

Set Environment Variables OIM 11G R2 PS2

Before we do deployments such as, register plugin, unregister plugin, upload jar, delete jar, etc., we need to set environment variable. I hope below list of environment variable will be easier for reference.
Note: These variables configured as per my local environment and you need make changes according to your environment.
export APP_SERVER=weblogic
export ANT_HOME=/opt/middleware/modules/org.apache.ant_1.7.1
export JAVA_HOME=/opt/java/jdk1.7.0_02
export PATH=/opt/java/jdk1.7.0_02/bin:/opt/middleware/modules/org.apache.ant_1.7.1/bin:$PATH
export MW_HOME=/opt/middleware
export XEL_HOME=/opt/middleware/Oracle_IDM1
export WL_HOME=/opt/middleware/wlserver_10.3
export OIM_ORACLE_HOME=/opt/middleware/Oracle_IDM1
export OIM_HOME=/opt/middleware/Oracle_IDM1/server
export DOMAIN_HOME=/opt/middleware/user_projects/domains/base_domain

Tuesday, May 19, 2015

OIM 11G Orchestration tables

Orchestration is vital component in OIM and we can say it is heart of OIM because, all operations, such as create user, modify user, delete, ldap sync, etc., were closely integrate with OIM Orchestration.

Known Issue: OIM Orchestration will retry failed event handlers ONLY 2 times and will ignore after that. Because, the retry limit was hard coded in OIM.

Table Name
Table Description
ORCHPROCESS
Stores the process instances that are being executed.
ORCHEVENTS
Stores event handler names, status and result for all orchestration processes.

Event status like COMPLETED, FAILED, PENDING, etc.
ORCHFAILEDEVENTS
Stores event handler information that are executed because of failures in main flow.

SQL Query:

Below sql query is to get list of event handlers, which are executed for a particular users during enable process:

This query used to get user key from usr table.
select usr_key from USR 
where usr_login = ‘chellappan.sampath’;
-- 1024
This query get process instance of enabled user ‘chellappan.sampath’
select id from orchprocess 
where entityid=’1024’ and entitytype='User' and operation='ENABLE';
-- 561092
This query gets all the event handler for enabled user ‘chellappan.sampath’
select * from orchevents 
where processid=’561092’ order by orchorder;
Similarly you can do for user enable, create user, etc.,

Tuning database & application servers for OIM

Tuning Database

Since OIM has heavily depends on database, obviously we need to tune the database for better performance. Every time a user is created or provisioned resource to user, there are dozens of operations taking places behind the scenes especially tables of the functional databases.

Below table show recommended initial setting for 4 CPU (64 bit) and 8/20 GB RAM:

Parameters
Initial setting for DB
db_block_size
8192
memory_target
Minimum value is 6 GB.
Maximum is MEMORY_TARGET/MEMORY_MAX_TARGET=Total Memory X 80% or 20GB, whichever is greate
sga_target
Minimum value is 4 GB.
Maximum is SGA_TARGET=Total Memory X 80% X 60% or 16 GB assuming an overall memory cap of 20 GB for the Oracle Identity Manager database to run.
pga_aggregate_target
Minimum value is 2 GB. Maximum is
PGA_TARGET=Total Memory X 80% X 40% or 4 GB whichever is greater
sga_max_size
10 GB
db_keep_cache_size
800M
log_buffer
15 MB
cursor_sharing
FORCE
open_cursors
2000
session_cached_cursors
800
query_rewrite_integrity
TRUSTED
db_file_multiblock_read_count
16
db_writer_processes
2
processes
Based on connection pool settings

While it is always recommended to check the Oracle Database Tuning reports within the database, Oracle provides recommendations of which can be found at this location: http://docs.oracle.com/cd/E14571_01/doc.1111/e14308/tuningfordb.htm#OMADM1811


Tuning Application Server

  1. OIM uses oimOperationsDB and oimJMSStoreDS datasource deployed on WebLogic server. By default, maximum connection size is set to 50. You can increase size as per your environment. Note: Make sure the same connection size should be set to in DB side too.
  2. Number of Message Driven Bean (MDB):OIM uses OIMMDBWorkManager MDB for processing all offline operations such as recon, audit, orchestration, etc. By default, it set to 80. You can set to -1 for unlimited.
  3. Disable Reloading of Adapters and Plug-in Configuration
  4. Change default memory arguments.
Periodically purging the Orchestration, Requests, Audit, Reconciliation tables in OIM.