Showing posts with label Oracle Identity Management. Show all posts
Showing posts with label Oracle Identity Management. Show all posts

Saturday, June 28, 2014

MDS-00010 DuplicateRefException Issue

When one of my team mate reported me an issue saying that they not able to modify and create user in OIM and are seeing the below exception every time they click on Create User/ Modify User link in OIM:

oracle.mds.exception.MDSRuntimeException: MDS-00010: DuplicateRefException. In document /oracle/iam/ui/runtime/form/view/pages/userCreateForm.jsff there are multiple elements with the same ID _xg_pfl0

My first impression was that I am the culprit and it’s due to some of the UDF changes I did few days back and made me curse the sandbox. I hate Sandbox. However, after ransacking all the sandboxes that I have imported in OIM and not able to find the ID _xg_pf in them. I didn't even saw the /oracle/iam/ui/runtime/form/view/pages folder. I started looking at the list of configuration changes made in the environment and found out that one of my team mate has accidentally installed Web Tier in the IAM middleware instead of IDM Middleware. Due to installation of web tier installation in IAM 11g R2 Middleware, some of the library files inside $MW_HOME/oracle_common got modified which caused this issue. I tried copying all the modified folders inside $MW_HOME/oracle_commons from another environment but that didn’t worked; the OIM Admin server didn’t get started.

Here are the list of sub-directories that got modified inside the $MW_HOME/oracle_common directory:
  • bin
  • modules
  • common
  • lib
  • jlib
There were few files (I think 2) that were also modified but they were not environment specific.

I also found a note# 1615855.1 on MOS which confirms the same. However the notes tells you to run the opatch lsinventory command on $MW_HOME/oracle_common to find if any IDM component is installed in IAM but I didn’t see OUI inventory being modified. The note says the solution is to install the IDM and IAM components again but you know that’s stupid and not doable.  A file system restore has worked for us. You might need to do db restore also if you have made significant changes in database or MDS recently.

Here is the error snippet:

2013-12-04T15:41:29.938-04:00] [WLS_OIM1] [NOTIFICATION] [J2EE JSP-00008] [oracle.j2ee.jsp] [tid: [ACTIVE].ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: xelsysadm] [ecid: 11d1def534ea1be0:67c0781c:142bf1864c8:-8000-0000000000000050,0] [APP: oracle.iam.console.identity.self-service.ear#V2.0] unable to dispatch JSP page: The following exception occurred:.[[
oracle.mds.exception.MDSRuntimeException: MDS-00010: DuplicateRefException. In document /oracle/iam/ui/runtime/form/view/pages/userCreateForm.jsff there are multiple elements with the same ID _xg_pfl0.
at oracle.mds.internal.melement.MDocument.insertMapNode(MDocument.java:2502)
at oracle.mds.internal.melement.MDocument.insertMapNode(MDocument.java:1194)
 
....
 
Cheers!
 

Sunday, May 4, 2014

Exporting all of the MDS data for OIM 11g

If you want to export/backup all the MDS configuration files for OIM, then use the below WLST command:
 
Step1: Create a directory where you want all the configuration to be exported, for example MDSExport.
 
Step2: From the shell/command prompt, navigate to $MW_HOME/oracle_common/common/bin
 
Step3: Execute the wlst.sh/wlst.cmd and issue the connect() command.
 
Step4: Provide the weblogic username, password and URL to Admin Server.
 
Step5: Execute the exportMetadata command providing at least the following arguments: application, server and toLocation.
 
For example, exportMetadata(‘OIMMedata’,’oim_server1’,’<<Full Path to MDSExport’)
 
Step6: You should see a list of the files exported, at that point you can issue the disconnect() command followed by the exit() command.
 
you can also save the above commands in a .py file, let’s say MDSExport.py and it can be executed directly without entering the credentails and URL everytime.
 
MDSExport.py
 
connect('weblogic',<<PASSWORD>>,'t3://<<server:7001>>)
exportMetadata(application='OIMMetadata', server='oim_server1', toLocation=<<Full Path to MDSExport’)
disconnect()
exit()
 
Now, you can simply run the below command:
./wlst.sh MDSExport.py
 
Note: You cannot export all the configuration files using Deployment Manager (DM) and also, DM doesn’t have version control.




Friday, January 10, 2014

Java Code to Add Entry in Lookup & Display Lookup Values

Here is the same java code to add entry in existing OIM Lookup and display all the Values from an existing OIM Lookup

import java.util.HashMap;
import java.util.Hashtable;
import oracle.iam.platform.OIMClient;
import Thor.API.tcResultSet;
import Thor.API.Operations.tcLookupOperationsIntf;

public class UpdateLookup {

 private static final String OIM_URL = "t3s://<>:14001";
 private static final String AUTH_CONF = "<< Path of authwl.conf >>";
 private static final String OIM_USERNAME = "<< UserID >>";
 private static final String OIM_PASSWORD = "<< Password >>";
 private static OIMClient oimClient = null;
 Hashtable env = new Hashtable();

 public UpdateLookup() {
  try {
   env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL,
     "weblogic.jndi.WLInitialContextFactory");
   env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, OIM_URL);
   System.setProperty("java.security.auth.login.config", AUTH_CONF);
   System.setProperty("OIM.AppServerType", "wls");
   System.setProperty("APPSERVER_TYPE", "wls");
   oimClient = new OIMClient(env);
   oimClient.login(OIM_USERNAME, OIM_PASSWORD.toCharArray());
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public void addLookupEntry(String LookupCode,String Lookup) {
  try {
   tcLookupOperationsIntf lookupOps = oimClient
     .getService(tcLookupOperationsIntf.class);
   lookupOps.addLookupValue("<>", LookupKey,
     LookupValue, "", "");

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


 public void displayLookup(String lookupname) {
  try {
   tcLookupOperationsIntf lookupOps = oimClient
     .getService(tcLookupOperationsIntf.class);
   tcResultSet values = lookupOps.getLookupValues(lookupname);
   for (int i = 0; i < values.getRowCount(); i++) {
    values.goToRow(i);
    System.out
      .print(values
        .getStringValue("Lookup Definition.Lookup Code Information.Decode"));
    System.out
      .println(","
        + values.getStringValue("Lookup Definition.Lookup Code Information.Code Key"));
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public static void main(String args[]) {
   UpdateLookup obj = new UpdateLookup();
   obj.addLookupEntry("LookupKey","LookupValue");

   obj.displayLookup("LookupName");
 }
}


Reference:

http://docs.oracle.com/cd/E17904_01/apirefs.1111/e17334/toc.htm

Wednesday, October 23, 2013

OIM11g: Searching & retrieve Authorization Policy Data using APIs

Here is the sample code to search and retrieve "Role Management" type Authorization Policy Data:

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import oracle.iam.authzpolicydefn.api.Action;
import oracle.iam.authzpolicydefn.api.AuthzPolicyConstants.AuthzPolicyAttributes;
import oracle.iam.authzpolicydefn.api.Feature;
import oracle.iam.authzpolicydefn.api.PolicyDefinitionService;
import oracle.iam.authzpolicydefn.vo.AuthzPolicy;
import oracle.iam.authzpolicydefn.vo.RoleDataConstraint;
import oracle.iam.identity.vo.Identity;
import oracle.iam.platform.OIMClient;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;

 public void getPolicyDetails(String policyName) {
  try {
   PolicyDefinitionService policyService = oimClient.getService(PolicyDefinitionService.class);
   SearchCriteria criteria = new SearchCriteria(AuthzPolicyAttributes.NAME.getId(),policyName,SearchCriteria.Operator.EQUAL);
   List policies = policyService.search(criteria);
   for (AuthzPolicy policy : policies) {


// Returns Display Name of Policy
    System.out.println(" Policy Name : " + policy.getDisplayName()); 


//Returns Description of the Policy
    System.out.println(" Description : " + policy.getDescription());   


//Returns the Enabled Permissions
    List
actions = policy.getActions();
    for(Action action: actions) {
     System.out.println(action.getDisplayName());
    }
  
    //Returns Type of Policy i.e., Role Management
    Feature features = policy.getFeature();
    System.out.println(" Entity Name : " + features.getDisplayName());
  
    //Returns the Assignment i.e., roles that are added to the Policy
    ArrayList
userList = policy.getRoleAssignees();
  for(Identity id: userList) {
   System.out.println(" Assign by Role : " + id.getAttribute("Role Name"));
  }

// Data Constraints i.e., Returns the Role Name attached with Policy
 RoleDataConstraint rDataConstraint = (RoleDataConstraint) policy.getDataSecurity();
 ArrayList
roles = rDataConstraint.getRoles();
 for(Identity role: roles) {
  System.out.println(role.getAttribute("Role Name"));
 }
}
}
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

}

Note: The APIs used above are not documented by Oracle.

Thursday, September 19, 2013

OIM11g R1 Post Processor Event Handler to remove User Role after user is disabled

Here is the code:

package oim.custom.eventhandlers;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import oracle.iam.identity.rolemgmt.api.RoleManager;
import oracle.iam.identity.rolemgmt.api.RoleManagerConstants.RoleAttributeName;
import oracle.iam.identity.rolemgmt.vo.Role;
import oracle.iam.identity.rolemgmt.vo.RoleManagerResult;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.usermgmt.vo.User;
import oracle.iam.platform.Platform;
import oracle.iam.platform.context.ContextManager;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;
import oracle.iam.platform.kernel.spi.PostProcessHandler;
import oracle.iam.platform.kernel.vo.AbstractGenericOrchestration;
import oracle.iam.platform.kernel.vo.BulkEventResult;
import oracle.iam.platform.kernel.vo.BulkOrchestration;
import oracle.iam.platform.kernel.vo.EventResult;
import oracle.iam.platform.kernel.vo.Orchestration;
import Thor.API.tcResultSet;
import Thor.API.Operations.tcLookupOperationsIntf;
import com.thortech.util.logging.Logger;

public class RemoveRolesFromRetiredUser implements PostProcessHandler {
 private static final Logger logger = Logger.getLogger("CUSTOM.EVENTS");
 private static final String CLASS_NAME = "oim.custom.eventhandlers.RemoveRolesFromRetiredUser : ";
 private static final String LOOKUP_COLUMN_DECODE = "Lookup Definition.Lookup Code Information.Decode";


 public void initialize(HashMap arg0) {
  String METHOD_NAME = "initialize :: ";
  logger.info(CLASS_NAME + METHOD_NAME
    + " Initializing RemoveRolesFromRetiredUser Event Handler ");
 }


 @Override
 public BulkEventResult execute(long processId, long eventId,
   BulkOrchestration bulkorchestration) {
  String METHOD_NAME = "BulkEventResult execute :: ";
  logger.info(CLASS_NAME + METHOD_NAME + "Inside ");
  try {
   String operation = bulkorchestration.getOperation();
   logger.debug(CLASS_NAME + METHOD_NAME
     + "bulkorchestration.getOperation() " + operation);

   String user = bulkorchestration.getTarget().getEntityId();
   logger.debug(CLASS_NAME + METHOD_NAME
     + "bulkorchestration.getTarget().getEntityId() " + user);

   logger.debug(CLASS_NAME + METHOD_NAME
     + " ContextManager.getContextType() "
     + ContextManager.getContextType());

   // Remove the  Roles of the Retired User
   if (isUserRetired(user) && operation.equals("DISABLE")) {
    logger.info(CLASS_NAME + METHOD_NAME
      + " Updated Description of Disabled User "
      + getUserName(user, "User Login") + " is "
      + getUserName(user, "Description"));
    logger.info(CLASS_NAME + METHOD_NAME
      + " Updated Container of Disabled User "
      + getUserName(user, "User Login") + " is " + getUserName(user, "UserDN"));
    logger.info(CLASS_NAME + METHOD_NAME
      + "Removing the Roles from the Disabled User "
      + getUserName(user, "User Login"));
    removeRolesOfUser(user);
   }
  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
   e.printStackTrace();
  }
  return new BulkEventResult();
 }


 public boolean isUserRetired(String userKey) {
  String METHOD_NAME = "isUserRetired :: ";
  logger.debug(CLASS_NAME + METHOD_NAME + "Inside ");
  boolean isUserRetired = false;
  try {
   HashSet retiredContainers = readLookup("Lookup.OIM.RetiredContainers");
   Iterator itr = retiredContainers.iterator();
   String userDN = getUserName(userKey, "UserDN");
   while(itr.hasNext()) {
    String containername = itr.next().toString();
    if(userDN.contains(containername)) {
     isUserRetired = true;
    }
   } 
  } catch (Exception e) {
   logger.error(CLASS_NAME
     + METHOD_NAME
     + "Error checking User Container "
     + e.getMessage());
  }
  return isUserRetired;
 }


 // Method to remove Roles from User
 public void removeRolesOfUser(String userkey) {
  final String METHOD_NAME = "removeOIMRoles :: ";
  logger.debug(CLASS_NAME + METHOD_NAME + "Inside ");
  String rolename = null;
  try {
   HashSet groupList = getRolesForUser(userkey);
   Set roleKeysSet = new HashSet();
   Iterator itr = groupList.iterator();
   while (itr.hasNext()) {
    rolename = itr.next().toString();
    roleKeysSet.add(getRoleKey(rolename));
   }
   RoleManagerResult result = null;
   RoleManager rmgr = Platform.getService(RoleManager.class);
   result = rmgr.revokeRoleGrants(userkey, roleKeysSet);
   logger.debug(CLASS_NAME + METHOD_NAME + "Role " + rolename
     + " Removed from User "
     + getUserName(userkey, "User Login") + result.getStatus());
  } catch (Exception e) {
   logger.debug(CLASS_NAME + METHOD_NAME + "Error Removing Roles "
     + e.getMessage());
   e.printStackTrace();
  }
 }

 public HashSet getRolesForUser(String userkey) {
  String METHOD_NAME = "getRolesForUser :: ";
  logger.debug(CLASS_NAME + METHOD_NAME + "Inside ");
  HashSet roleList = new HashSet();
  try {
   logger.debug(CLASS_NAME + METHOD_NAME + "Reading "
     + getUserName(userkey, "User Login") + "Roles ");
   RoleManager rolemanager = Platform.getService(RoleManager.class);
   List groupList = rolemanager
     .getUserMemberships(userkey, true);
   for (Role role : groupList) {
    String roleName = role.getAttribute("Role Name").toString();
    logger.debug(CLASS_NAME + METHOD_NAME + "RoleName :" + roleName);
    roleList.add(roleName);
   }
   HashSet removeRoles = readLookup("Lookup.OIM.IgnoreRole");

   // Exclude Default Roles from the List
   roleList.removeAll(removeRoles);

  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + "Error Reading Roles"
     + e.getMessage());
   e.printStackTrace();
  }
  return roleList;
 }

 // Method to read Lookup containing default OIM Roles
 public HashSet readLookup(String lookup) {
  String METHOD_NAME = "readLookup :: ";
  logger.debug(CLASS_NAME + METHOD_NAME + "Inside ");
  HashSet records = new HashSet();
  try {
   String lookupDecode = lookup;
  
   // Read Lookup to Find FilteredRoles
   tcLookupOperationsIntf lookupOps = Platform
     .getService(tcLookupOperationsIntf.class);
   tcResultSet lookupResultSet = lookupOps
     .getLookupValues(lookupDecode);
   for (int i = 0; i < lookupResultSet.getRowCount(); i++) {
    lookupResultSet.goToRow(i);
    String decode = lookupResultSet.getStringValue(
      LOOKUP_COLUMN_DECODE).trim();
    records.add(decode);
   }
  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + "Error Reading Lookup"
     + e.getMessage());
   e.printStackTrace();
  }
  return records;
 }

 // Method to get RoleKey based on Rolename input
 public String getRoleKey(String roleName) {
  final String METHOD_NAME = "getRoleKey :: ";
  logger.debug(CLASS_NAME + METHOD_NAME + "Inside ");
  RoleManager rmgr = Platform.getService(RoleManager.class);
  Set retAttrs = new HashSet();
  String roleKey = null;
  try {
   retAttrs.add(RoleAttributeName.DISPLAY_NAME.getId());
   SearchCriteria criteria = null;
   criteria = new SearchCriteria(RoleAttributeName.NAME.getId(),
     roleName, SearchCriteria.Operator.EQUAL);
   List roles = rmgr.search(criteria, retAttrs, null);
   roleKey = roles.get(0).getEntityId();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return roleKey;
 }

 // Method to retrieve User Login based on the usr_key
 public String getUserName(String key, String attribute) {
  String METHOD_NAME = "getUserName :: ";
  logger.debug(CLASS_NAME + METHOD_NAME + "Inside ");
  String userattr = null;
  try {
   HashMap attributes = null;
   HashMap parameters = null;
   Set attrNames = null;
   List users = null;
   UserManager umgr = Platform.getService(UserManager.class);
   SearchCriteria criteria = new SearchCriteria("usr_key", key,
     SearchCriteria.Operator.EQUAL);
   attrNames = new HashSet();
   attrNames.add(attribute);
   users = umgr.search(criteria, attrNames, parameters);
   if (users != null && !users.isEmpty()) {
    for (User user : users) {
     attributes = user.getAttributes();
     userattr = attributes.get(attribute).toString();
     logger.debug(CLASS_NAME + METHOD_NAME + " User : "
       + userattr);
    }
   }
  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME
     + "Error Retrieving User Login " + e.getMessage());
   e.printStackTrace();
  }
  return userattr;
 }

 @Override
 public EventResult execute(long processId, long eventId,
   Orchestration orchestration) {
  return null;
 }

 @Override
 public boolean cancel(long arg0, long arg1,
   AbstractGenericOrchestration arg2) {
  return false;
 }

 @Override
 public void compensate(long arg0, long arg1,
   AbstractGenericOrchestration arg2) {
 }

}

Here is the plugin.xml:

http://www.w3.org/2001/XMLSchema-instance
">
Here is the eventhandlers.xml:

http://www.oracle.com/schema/oim/platform/kernel
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oracle.com/schema/oim/platform/kernel orchestration-handlers.xsd"> 
Cheers!

Saturday, February 2, 2013

OIM11g: Bulk Load the Data in Access Policies

Hi All,

The requirement for the code that you see below comes from my client who while learning to create access policies asked me below question:

In OIM, you cannot add multiple groups in single iteration to AccessPolicy but you can remove multiple groups. What's the rationale behind this?

Well, I couldn't agree more with him and I have no answer for him and before he could throw any other question or think of asking me to modifying the OIM UI to provide capability to add multiple groups to Access Policy, I told him that I can create a Bulk Data Load Utility which can be used for loading the groups in bulk to access policies and below is the code for that:

package security.provisioning;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.thortech.xl.vo.AccessPolicyResourceData;
import com.thortech.xl.vo.PolicyChildTableRecord;
import Thor.API.tcResultSet;
import Thor.API.Operations.tcAccessPolicyOperationsIntf;
import oracle.iam.identity.rolemgmt.api.RoleManager;
import oracle.iam.identity.rolemgmt.api.RoleManagerConstants.RoleAttributeName;
import oracle.iam.identity.rolemgmt.vo.Role;
import oracle.iam.platform.Platform;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;
import oracle.iam.scheduler.vo.TaskSupport;
import com.thortech.util.logging.Logger;

public class InitialAccessPolicyLoad extends TaskSupport {
 HashMap> mapping = new HashMap>();
 tcAccessPolicyOperationsIntf moAccesspolicyutility = null;
 private static final Logger logger = Logger.getLogger("SECURITY.EVENTS");
 private static final String CLASS_NAME = "security.provisioning.InitialAccessPolicyLoad : ";
 private static final long formKey = 25;
 private static final long objectKey = 24;
 private static final String tableKey = "22";
 private static final String objName = "OID User";
 private static final String fName = "UD_OID_USR";
 private static final String groupPrefix ="41~cn=";
 private static final String groupSuffix=",cn=Groups,dc=sample,dc=com";

 public void execute(HashMap arg0) {
  final String METHOD_NAME = "execute :: ";
  try {

   logger.debug(CLASS_NAME + METHOD_NAME + "Entering Method - execute");
   // Output File Name
   String inputFileName = arg0.get("Input File Name").toString();
   logger.debug(CLASS_NAME + METHOD_NAME + " Input File Name "
     + inputFileName);

   // Delimiter for EDR Group List
   String ROLE_DELIMITER = arg0.get("List Delimiter").toString();
   logger.debug(CLASS_NAME + METHOD_NAME + " List Delimiter "
     + ROLE_DELIMITER);

   // Delimiter for the Attributes in the Input File
   String FILE_DELIMITER = arg0.get("Field Delimiter").toString();
   logger.debug(CLASS_NAME + METHOD_NAME + " Field Delimiter "
     + FILE_DELIMITER);

   // Read Input File
   BufferedReader buff = new BufferedReader(new FileReader(inputFileName));
   buff.readLine();
   String Line = null; 
   boolean isValidRecord = true;
   String PolicyName = null;
   String RoleName = null;
   String Groups = null;
   ArrayList GroupList = new ArrayList();
   while ((Line = buff.readLine()) != null) {
  
    if (Line.startsWith("#")) {
     isValidRecord = false;
    }
  
    String[] values = Line.split(FILE_DELIMITER);
  
    if (values.length == 1) {
     PolicyName = values[0];
     isValidRecord = false;

    } else if (values.length == 2) {
     PolicyName = values[0];
     RoleName = values[1];
     isValidRecord = false;

    } else if (values.length == 3) {
     isValidRecord = true;
     PolicyName = values[0];
     RoleName = values[1];
     Groups = values[2];
     String[] gList = Groups.split(ROLE_DELIMITER);
     for(int i=0;i      GroupList.add(gList[i]);
     }
    }
  
  
    if (isValidRecord) {
     uploadPolicyData(PolicyName,RoleName,GroupList);
     logger.debug(CLASS_NAME + METHOD_NAME + "ADDING RECORD: " + Line);
    } else {
     logger.debug(CLASS_NAME + METHOD_NAME + "INVALID RECORD: " + Line);
    }

   }
   

   logger.info(CLASS_NAME + METHOD_NAME
     + " Access Policies Data Loaded");

  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
 }

 public void uploadPolicyData(String PolicyName, String RoleName, ArrayList GroupList) {
  final String METHOD_NAME = "uploadPolicyData :: ";

  try {

   tcAccessPolicyOperationsIntf moAccesspolicyutility = Platform
     .getService(tcAccessPolicyOperationsIntf.class);
   HashMap searchPolicy = new HashMap();
   searchPolicy.put("Access Policies.Name", PolicyName);
   tcResultSet result = moAccesspolicyutility.findAccessPolicies(searchPolicy);
 
   long policyKey = result.getLongValue("Access Policies.Key");
   logger.debug(CLASS_NAME + METHOD_NAME + "Access Policies.Key" +policyKey);
 
   Long roleKey = Long.parseLong(getRoleKey(RoleName));
   long[] roleKeys = { roleKey };
 
   //Add the Role NAME
   moAccesspolicyutility.assignGroups(policyKey, roleKeys);
   logger.info(CLASS_NAME + METHOD_NAME
     + " Role: "+ RoleName +" is attached to the Access Policy: " + PolicyName);
 
   for(int i = 0;i  
    HashMap childTableMap = new HashMap();
    String groupName = groupPrefix+GroupList.get(i)+groupSuffix;
    logger.debug(CLASS_NAME + METHOD_NAME + "OID Group Name: " +groupName);
    childTableMap.put("UD_OID_GRP_GROUP_NAME", groupName);
    AccessPolicyResourceData policyData = new AccessPolicyResourceData(objectKey,objName,formKey,fName,"P");
    PolicyChildTableRecord pChildTableData = policyData.addChildTableRecord(tableKey, "UD_OID_GRP", "Add", childTableMap);
    moAccesspolicyutility.setDataSpecifiedForObject(policyKey, objectKey, formKey, policyData);
    logger.info(CLASS_NAME + METHOD_NAME
      + " Group: "+ GroupList.get(i) +" attached to the Access Policy: " + PolicyName);
   }

  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
 }



 public String getRoleKey(String roleName) {

  final String METHOD_NAME = "getRoleKey :: ";
  System.out.println(CLASS_NAME + METHOD_NAME
    + "Entering Method - getRoleKey");

  RoleManager rmgr = Platform.getService(RoleManager.class);
  Set retAttrs = new HashSet();
  String roleKey = null;
  try {
   retAttrs.add(RoleAttributeName.DISPLAY_NAME.getId());
   SearchCriteria criteria = null;
   criteria = new SearchCriteria(RoleAttributeName.NAME.getId(),
     roleName, SearchCriteria.Operator.EQUAL);
   List roles = rmgr.search(criteria, retAttrs, null);
   roleKey = roles.get(0).getEntityId();
  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
  return roleKey;
 }

 // Method to check if  Role exists in OIM or not
 public boolean isRoleExist(String[] roles) {

  String METHOD_NAME = "isRoleExist :: ";
  logger.debug(CLASS_NAME + METHOD_NAME +"Entering Method - isRoleExist");
  boolean roleExist = false;
  boolean roleListEmpty = false;
  if(Arrays.toString(roles).length() == 2) {
   roleListEmpty = true;
  }

  try {
   if (!roleListEmpty) {
   RoleManager rmgr = Platform.getService(RoleManager.class);
   Set retAttrs = new HashSet();
   retAttrs.add(RoleAttributeName.DISPLAY_NAME.getId());
   SearchCriteria criteria = null;
   for (int i = 0; i < roles.length; i++) {
    criteria = new SearchCriteria(RoleAttributeName.NAME.getId(),
      roles[i], SearchCriteria.Operator.EQUAL);
    List role = rmgr.search(criteria, retAttrs, null);
    if (role.size() != 0) {
     roleExist = true;
    } else {
     logger.debug(CLASS_NAME + METHOD_NAME + roles[i]
       + " DOESN'T EXIST IN OIM");
     roleExist = false;
    }
   }
  }
   }catch (Exception e) {
    logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
  return roleExist;
 }

 public HashMap getAttributes() {
  return null;
 }

 public void setAttributes() {
 }

}
I don't know how easy/hard is to modify the UI to provide the capability but considering this as "Nice To Have" requirement, I think the above solution is good enough. There are couple of things like Checking if OID Group exist or not or update(add & delete) the Groups I might need to add later.

Note: This code is specific to OID Resource and assume that access policy is already created.

 

Wednesday, July 21, 2010

Is it Possible to Change the AD Organization Name from an Access Policy?

There is a small confusion in the way access policies work for AD, once an access policy is created and assigned to a group, whenever a user is added to that group, the access policy will be applied to him and AD User resource will be provisioned to him .

Now , if you make an update on the group membership on active directory process form(child form) in the access policy , then it will work and will be updated on the target side, but if you update the Organization name on active directory process form, then it will not be reflected in the target side and in the OIM side.

Now open the Access policy which you created and if you try to change the group membership on active directory process form(child form) in the access policy , then it will work and it will be updated on the target side, but if you update the Organization name on active directory process form,then it will not be reflected in the target side and in the OIM side. Now, one may have a doubt that when a change in the child form is reflected, why does a change in parent form not reflected in the target system .


As per the development the above behaviour is correct , the documentation says "Access policy engine checks if the resource is already provisioned to the user. If it is, then the resource will not be provisioned again. [...] After this, it checks the list of policies being newly added to see if any of them specify child table data for this resource. If they do, then the appropriate child table entries need to be made in the process form for this resource."


This explains why the change in the organization has no effect (resource is not provisioned again) but the change in the child form has an effect (new child table entries are added),so any change in the child form will be reflected but changes to the parent form/organization change will not be reflected.

Regards,
Sunny Ajmera

How To : Can Access Policies Manage The Life-cycle Of Users Created via Reconciliation?

Can Access Policies Manage The Life-cycle Of Users Created via Reconciliation?

Currently policy engine is able to manage life cycle of the resource only if the Resource Object is provisioned via OIM access policy.

If the resource is reconciled, OIM does not retrofit the data of the reconciled resource with the existing access policies. This means that OIM can not manage those users with access policy. This is also true when the users are obtained either through trusted reconciliation or target reconciliation. Please note that OIM has no way of knowing how accounts were created before OIM was deployed.

It is possible that before OIM was integrated with the target, accounts were created directly in the target based on policies, requested or delegated administrator based direct assignment or any other means ( like bulk upload from HR system or some other application or some meta-directory product). OIM cannot start de-provisioning accounts or entitlement assignments only because the new policies defined in OIM would not provision the account/entitlement to the user. Access policies can only do additional entitlement assignment for accounts discovered by recon. Additionally, once new accounts are provisioned from OIM, OIM knows the context for how they were provisioned and so can correctly de-provision accounts based on "revoke if no longer applies" flag.

One way to do this is to cleanse the existing data before integrating into OIM or run manual attestation in OIM to cleanse the data. Once the data is cleansed and uploaded in OIM, from thereon OIM can be configured to manage the accounts.


Regards,
SunShine

How to Delete Access Policy in OIM

The general instructions for removing an Access Policy from a group can be found in the Admin and User Console Guide, Chapter 10 Creating and Managing User Groups. A link to that chapter in the 9.1 version is below:
http://download.oracle.com/docs/cd/E10391_01/doc.910/e10360/usergroups.htm#BACCGCGB

This would remove the policy from the group, but not specifically delete the actual policy itself from the Oracle Identity Manager (OIM) server. There is the existing Enhancement Request Bug 5179943 for providing that complete delete feature and it has been approved for inclusion into the future release of OIM (11g version).