Saturday, March 28, 2020

Sailpoint Identity IIQ Complex Correlation Rule


Here I have written a Complex Correlation Rule which can be used for the Application where the AccountIdentitfier from the Application matches any of the multiple identity Attribute such as the name, email,employee Number , Since the Correlation is the Case sensitive so most of the scenario we see the issue with the correlation config or the default correlation doesn't work.


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Application Correlation Rule" type="Correlation">
  <Description>
 Rule to correlate accounts to identities based on lanId.
  </Description>
  <Signature returnType="Map">
    <Inputs>
      <Argument name="log">
        <Description>
          The log object associated with the SailPointContext.
        </Description>
      </Argument>
      <Argument name="context">
        <Description>
          A sailpoint.api.SailPointContext object that can be used to query the database if necessary.
        </Description>
      </Argument>
      <Argument name="environment" type="Map">
        <Description>
          Arguments passed to the aggregation task.
        </Description>
      </Argument>
      <Argument name="application">
        <Description>
          Application being aggregated.
        </Description>
      </Argument>
      <Argument name="account">
        <Description>
          A sailpoint.object.ResourceObject returned from the
          collector.
        </Description>
      </Argument>
      <Argument name="link">
        <Description>
          Existing link to this account.
        </Description>
      </Argument>
    </Inputs>
    <Returns>
      <Argument name="identityName">
        <Description>
          The name of an Identity object.
        </Description>
      </Argument>
      <Argument name="identity">
        <Description>
          A fully resolved Identity object if the rule wants
          to do its own queries to locate the identity.
        </Description>
      </Argument>
      <Argument name="identityAttributeName">
        <Description>
          The name of the extended attribute that can be used
          to locate an existing identity.
        </Description>
      </Argument>
      <Argument name="identityAttributeValue">
        <Description>
          The value of the named extended attribute that can be used
          to locate an existing identity. This attribute is used
          together with the identityAttributeName argument.
        </Description>
      </Argument>
    </Returns>
  </Signature>
  <Source>

Map returnMap = new HashMap();
  
String VIS_APP_LAN_ID = "AppliCationAccountIdentifier";
String VIS_IDENTITY_NAME = "name";
String VIS_IDENTITY_EMAIL = "email";
String VIS_IDENTITY_EMPLOYEE_NUMBER = "employeeNumber";

Map objectPropertiesFetched = new HashMap();
List objectPropertiesToFetch = new ArrayList();
objectPropertiesToFetch.add(VIS_IDENTITY_NAME);

Filter filter = null;
String appLanId = null;

Log log = LogFactory.getLog("vishal.rule.CorrelationRule");
log.debug("Entering Correlation Rule");

try{
 appLanId = account.getAttribute(VIS_APP_LAN_ID);
 filter = Filter.or( Filter.ignoreCase(Filter.eq(VIS_IDENTITY_NAME, appLanId)), Filter.ignoreCase(Filter.eq(VIS_IDENTITY_EMAIL, appLanId)), Filter.ignoreCase(Filter.eq(VIS_IDENTITY_EMPLOYEE_NUMBER, appLanId)) );
 objectPropertiesFetched = getObjectProperties(Identity.class, filter, objectPropertiesToFetch);
 if(objectPropertiesFetched.get(VIS_IDENTITY_NAME) != null){ 
  returnMap.put( "identityName", objectPropertiesFetched.get(VIS_IDENTITY_NAME));
 }
}catch(Exception exception){
 log.error("Exception caught in Correlation Rule: "+exception);
}
return returnMap;

  </Source>
</Rule>

We need to make sure that getObjectProperties() need to be added to some Rule Library and that rule library need to be referenced in the above rule using 


<ReferencedRules>
    <Reference class="sailpoint.object.Rule" name="VIS Rule Library"/>
 </ReferencedRules> 


public Map getObjectProperties(java.lang.Class objectType, Filter searchFilter, List propertiesToFetch){
 Object[] objectProperties;
 Map propertiesMap = new HashMap();
 QueryOptions queryOptions = new QueryOptions();
 queryOptions.addFilter(searchFilter);
 //iterator to iterate over managed attributes to fetch properties
 Iterator iterator = context.search(objectType, queryOptions, propertiesToFetch);
 //Assign iterator to objectProperties if iterator hasNext
 if(iterator.hasNext()){
  objectProperties = iterator.next();
  if (objectProperties != null ){
   //invoke method propertyArrayToMap to retrieve a map of property names and values
   propertiesMap = propertyArrayToMap(objectProperties, propertiesToFetch);
  }       
 } 
 Util.flushIterator(iterator);
 return propertiesMap; 
}