11 Developing Identity Connectors Using .NET

This chapter is a tutorial that walks through the procedures necessary to develop an identity connector in .NET using the Identity Connector Framework (ICF) and the Oracle Identity Manager metadata. It includes information about important ICF classes and interfaces, the connector bundle, the connector server, and code samples for implementing a flat file .NET identity connector and creating Oracle Identity Manager metadata for user provisioning and reconciliation processes. It contains the following sections:

11.1 Developing a Flat File .NET Connector

The procedure for developing a flat file connector is to develop an implementation of the Configuration interface followed by the implementation of the Connector class. In the documentation we would discuss sample implementation of a flat file connector showing Create, Delete, Update and Search operations. To keep implementations and documentation simple, Configuration properties and Schema supported by connector have been kept to a minimum. This connector implementation should only be used as a sample which would help to create actual connectors.

To keep the connector implementation simple, lets assume that flat file has only Name, Gender, Qualification, Age attributes. We would have only two configurations File Location and Delimiter. Rest configurations would be hardcoded in the sample.

  1. Setting up the project in Microsoft Visual Studio and using the connector:

    1. Create a new visual studio project of type library.

    2. Make sure to add the following dlls as references:

      - Common.dll

      - Framework.dll

      - FrameworkInternal.dll

      - System.dll

      - System.Core.dll

      These dlls should be available with the .NET connector server.

  2. Implement the configuration class for the Flat File Connector by extending the Org.IdentityConnectors.Framework.Spi.AbstractConfiguration base class.

    Example 11-1 Implementation of AbstractConfiguration

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Org.IdentityConnectors.Framework.Spi;?
    using Org.IdentityConnectors.Framework.Common.Exceptions;?
    using System.IO;
     
    namespace Org.IdentityConnector.FlatFileConnector?
    {
        /// <summary>
        /// Configuration class for flat file connector representing target system information?
        /// </summary>
        public class FlatFileConfiguration : AbstractConfiguration?
        {
            #region FileName
            /// <summary>
            /// Target file name
            /// </summary>
            /// <value>
            /// File name with complete path. As for executing the .NET Connector bundle we need .NET Connector Server, hence the file should reside
            /// on the machine where the connector server is present.
            /// </value>
            [ConfigurationProperty(Required = true, Order = 1)]
            public String FileName { get; set; }
            #endregion
     
            #region Delimiter
            /// <summary>
            /// Delimiter used within the target flat file
            /// </summary>
            /// <value>
            /// Delimter
            /// </value>
            [ConfigurationProperty(Required = true, Order = 2)]
            public String Delimiter { get; set; }
            #endregion
                    
            #region
            /// <summary>
            /// Validates if the configuration properties provided are as requiered, if not throw ConfigurationException
            /// </summary>
            public override void Validate()
            {
                if (this.FileName == null || this.FileName.Length == 0)
                {
                    throw new ConfigurationException("Configuration property FileName cannot be null or empty");
                }
                if (!File.Exists(this.FileName))
                {
                    throw new ConfigurationException("Target file " + this.FileName + " does not exist");
                }
                if (this.Delimiter == null || this.Delimiter.Length == 0)
                {
                    throw new ConfigurationException("Configuration property Delimiter cannot be null or empty");
                }
            }
            #endregion
        }
    }
    
  3. Create connector class for the Flat File Connector by implementing different SPI interfaces Org.IdentityConnectors.Framework.Spi.

    Example 11-2 implements the PoolableConnector,CreateOp,SchemaOp,TestOp,DeleteOp,UpdateOp,SearchOp<String> interfaces and thus supports all CRUD operations

    Example 11-2 Implementation of PoolableConnector

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Org.IdentityConnectors.Framework.Spi;
    using System.IO;
    using Org.IdentityConnectors.Framework.Common.Exceptions;
    using System.Security.AccessControl;
    using Org.IdentityConnectors.Framework.Spi.Operations;
    using Org.IdentityConnectors.Framework.Common.Objects;
    using Org.IdentityConnectors.Common;
     
    namespace Org.IdentityConnector.FlatFileConnector
    {
        /// <summary>
        /// FlatFileConnector showing implementation of SchemaOp, test, create, delete, update and search operations.
        /// </summary>
        [ConnectorClass("FlatFileConnector_DisplayNameKey",typeof(FlatFileConfiguration))]
        public class FlatFileConnector : PoolableConnector,CreateOp,SchemaOp,TestOp,DeleteOp,UpdateOp,SearchOp<String>
        {
     
            /// <summary>
            /// Flat file configuration instance. This instance has the target system information.
            /// </summary>
            private FlatFileConfiguration config;
     
     
            #region Init
            /// <summary>
            /// Create a connection to target and store it for later use. But here we just set attributes of target file
            /// name to Normal
            /// </summary>
            /// <param name="config">Configuration Object</param>
            public void Init(Configuration config)
            {
                this.config = (FlatFileConfiguration)config;
                File.SetAttributes(this.config.FileName, FileAttributes.Normal);
            }
            #endregion
     
     
     
            #region CreateOp Members
            /// <summary>
            /// This creates a new row in the target file with the data as sent in the 'attrs'
            /// </summary>
            /// <param name="objClass">The ObjectClass. Here we support only Account</param>
            /// <param name="attrs">Attributes of this Account that need to be created on target</param>
            /// <param name="options">Will always be empty</param>
            /// <returns>Unique id Uid, representing the Account which was just created</returns>
            public Uid Create(ObjectClass objClass, ICollection<ConnectorAttribute> attrs, OperationOptions options)
            {            
                ConnectorAttribute NameAttribute = ConnectorAttributeUtil.Find(Name.NAME, attrs);
                ConnectorAttribute AgeAttribute = ConnectorAttributeUtil.Find("Age", attrs);
                ConnectorAttribute QualificationAttribute = ConnectorAttributeUtil.Find("Qualification", attrs);
                ConnectorAttribute GenderAttributute = ConnectorAttributeUtil.Find("Gender", attrs);
                StreamWriter writer = File.AppendText(this.config.FileName);
                writer.WriteLine("\nName:" + ConnectorAttributeUtil.GetAsStringValue(NameAttribute) + this.config.Delimiter + "Age:" + ConnectorAttributeUtil.GetAsStringValue(AgeAttribute) + this.config.Delimiter + "Qualification:" + ConnectorAttributeUtil.GetAsStringValue(QualificationAttribute) + this.config.Delimiter + "Gender:" + ConnectorAttributeUtil.GetAsStringValue(GenderAttributute));
                writer.Flush();            
                writer.Dispose();
                writer.Close();
                return new Uid(ConnectorAttributeUtil.GetAsStringValue(NameAttribute));
            }
            #endregion
     
     
            
            #region DeleteOp Members
            /// <summary>
            /// Deletes an entity from target flat file. We support only ACCOUNT object class.
            /// If the Uid (user name) is not found then UnknownUidException is thrown
            /// </summary>
            /// <param name="objClass"></param>
            /// <param name="uid"></param>
            /// <param name="options"></param>
            public void Delete(ObjectClass objClass, Uid uid, OperationOptions options)
            {
                String[] allLines = File.ReadAllLines(this.config.FileName);            
                String[] newLines = new String[allLines.Length];            
                Boolean userExisted = false;            
                for (int i = 0; i < allLines.Length; i++)
                {                
                    char[] separator = new char[] { '$' };
                    String[] thisLineSplit = allLines[i].Split(separator);                
                    
                    String name = "";
                    foreach (String str in thisLineSplit)
                    {
                        if (str.StartsWith("Name"))
                        {
                            name = str;
                            break;
                        }
                    }                
                    if (!name.Equals("Name" + ":" + uid.GetUidValue()))
                    {
                        newLines[i] = allLines[i];
                    }
                    else
                    {
                        userExisted = true;
                    }
                    
                }
                if (userExisted)
                {                
                    File.WriteAllText(this.config.FileName, String.Empty);
                    File.WriteAllLines(this.config.FileName, newLines);
                }
                else
                {
                    throw new UnknownUidException("Uid "+uid.GetUidValue()+" not found");
                }            
            }
            #endregion
                    
            #region UpdateOp Members
            /// <summary>
            /// Updates information of an existing user on the target flat file
            /// </summary>
            /// <param name="objclass">The ObjectClass. Here we support only user</param>
            /// <param name="uid">Unique id of the user using which we can find out the user on target. This is the returned vaue by CreateOp implementation</param>
            /// <param name="replaceAttributes">Updated attributes of user which should replace all existing user information on target</param>
            /// <param name="options">This will always be empty</param>
            /// <returns>Updated uid. It can be the same value which was provided to this method.</returns>
            public Uid Update(ObjectClass objclass, Uid uid, ICollection<ConnectorAttribute> replaceAttributes, OperationOptions options)
            {
                String uidValue = uid.GetUidValue();
                String[] allLines = File.ReadAllLines(this.config.FileName);
                String[] updatedLines = new String[allLines.Length];
                Boolean userExists = false;
                Uid updatedUid = uid;
                for(int i = 0; i < allLines.Length; i++)
                {
                    String[] thisLineSplit = allLines[i].Split(new char[] { '$' });
                    String name = "";
                    foreach (String str in thisLineSplit)
                    {
                        if (str.StartsWith("Name"))
                        {
                            name = str;
                            break;
                        }
                    }
                    String nameToBeUpdated = "Name:" + uidValue;
                    if (!name.Equals(nameToBeUpdated))
                    {
                        updatedLines[i] = allLines[i];
                    }
                    else
                    {
                        ConnectorAttribute NameAttribute = ConnectorAttributeUtil.Find(Name.NAME, replaceAttributes);
                        ConnectorAttribute AgeAttribute = ConnectorAttributeUtil.Find("Age", replaceAttributes);
                        ConnectorAttribute QualificationAttribute = ConnectorAttributeUtil.Find("Qualification", replaceAttributes);
                        ConnectorAttribute GenderAttribute = ConnectorAttributeUtil.Find("Gender", replaceAttributes);
                        updatedLines[i] = "Name:"+NameAttribute.Value.First().ToString()+this.config.Delimiter+
                                          AgeAttribute.Name+":"+AgeAttribute.Value.First().ToString()+this.config.Delimiter+
                                          QualificationAttribute.Name+":"+QualificationAttribute.Value.First().ToString()+this.config.Delimiter+
                                          GenderAttribute.Name+":"+GenderAttribute.Value.First().ToString();
                        userExists = true;
                        updatedUid = new Uid(NameAttribute.Value.First().ToString());
                    }
     
                }
                File.WriteAllText(this.config.FileName, String.Empty);
                File.WriteAllLines(this.config.FileName, updatedLines);
                if (!userExists)
                {
                    throw new UnknownUidException("User "+uid.GetUidValue()+" not found");
                }
                return updatedUid;
            }
     
            #endregion
     
            #region SearchOp<string> Members
     
            /// <summary>
            /// Returns a filter translator used by ExecuteQuery. The functionality of filter translator is to translate any filters provided by calling application (OIM/OW/OPAM) to native queries.
            /// </summary>
            /// <param name="oclass">The ObjectClass. We support only ACCOUNT</param>
            /// <param name="options">Options</param>
            /// <returns>FilterTranslator instance</returns>
     
            public Org.IdentityConnectors.Framework.Common.Objects.Filters.FilterTranslator<string> CreateFilterTranslator(ObjectClass oclass, OperationOptions options)
            {
                return new FlatFileFilterTranslator();
            }
     
            /// <summary>
            /// Performs search on target based on query. Uses the handler instance to return back the searched result.
            /// </summary>
            /// <param name="oclass">The ObjectClass. This tells if we have to search for user (ACCOUNT) or group (GROUP). We support only user</param>
            /// <param name="query">Query as returned by FilterTranslator</param>
            /// <param name="handler">handler to return back result to caller</param>
            /// <param name="options">Options containing what attributes of entity to return back</param>
            public void ExecuteQuery(ObjectClass oclass, string query, ResultsHandler handler, OperationOptions options)
            {
    
                String[] results = GetResults(query);
                foreach (String result in results)
                {
                    Console.WriteLine("Result = "+result);
                    String result1 = result.Trim();
                    if (result1.Length > 0)
                    {
                        Console.WriteLine("Submitting result = " + result1);
                        SubmitConnectorObject(result1, handler);
                    }
                }
            }
     
            #region SchemaOp Members
            /// <summary>
            /// Defines the schema supported by this connector
            /// </summary>
            /// <returns>Schema</returns>
            public Schema Schema()
            {
                SchemaBuilder schemaBuilder = new SchemaBuilder(SafeType<Connector>.Get(this));
                ICollection<ConnectorAttributeInfo> connectorAttributeInfos = new List<ConnectorAttributeInfo>();
                connectorAttributeInfos.Add(ConnectorAttributeInfoBuilder.Build("Name"));
                connectorAttributeInfos.Add(ConnectorAttributeInfoBuilder.Build("Age"));
                connectorAttributeInfos.Add(ConnectorAttributeInfoBuilder.Build("Qualification"));
                connectorAttributeInfos.Add(ConnectorAttributeInfoBuilder.Build("Gender"));
                schemaBuilder.DefineObjectClass(ObjectClass.ACCOUNT_NAME, connectorAttributeInfos);
                return schemaBuilder.Build();
            }
     
            #endregion
     
            #region TestOp Members
            /// <summary>
            /// Should ideally test the connecttion with target. But here we just print something as we have assumed that target file is on same machine
            /// </summary>
            public void Test()
            {
                Console.Write("Tested connection!");
            }
     
            #endregion
     
     
            #region CheckAlive
            /// <summary>
            /// Check connection to target system is alive or not. But here we just check if target file name
            /// provided in the FlatFileConfiguration is available or not.
            /// </summary>
            public void CheckAlive()
            {
                if (!File.Exists(this.config.FileName))
                {
                    throw new ConnectorException("Target file " + this.config.FileName + " does not exist");
                }
            }
            #endregion
     
     
     
            #region Dispose
            /// <summary>
            /// Remove connection from target, dispose any of the resources used. But here we just chill.
            /// </summary>
            public void Dispose()
            {
                //chill :)
            }
            #endregion
     
            private void SubmitConnectorObject(String result, ResultsHandler handler)
            {
                ConnectorObjectBuilder cob = new ConnectorObjectBuilder();
                String[] resultSplit = result.Split(new char[]{'$'});
                ICollection<ConnectorAttribute> attrs = new List<ConnectorAttribute>();
                foreach (String str in resultSplit)
                {
                    ConnectorAttributeBuilder cab = new ConnectorAttributeBuilder();
                    cab.AddValue(str.Split(new char[] { ':' })[1]);
                    if (str.StartsWith("Name"))
                    {
                        cob.SetName(Name.NAME);
                        cob.SetUid(str.Split(new char[] { ':' })[1]);
                        cab.Name = Name.NAME;                    
                    }
                    else
                    {
                        cab.Name = str.Split(new char[] { ':' })[0];
                    }
                    attrs.Add(cab.Build());
                }
                cob.AddAttributes(attrs);
                handler(cob.Build());
            }
     
            private String[] GetResults(String query)
            {
                String[] allLines = File.ReadAllLines(this.config.FileName);
                String[] results = allLines;
    if (query != null)
                {
                    for (int i = 0; i < allLines.Length; i++)
                    {
                        String[] thisLineSplit = allLines[i].Split(new char[]{'$'});
                        Boolean foundResult = false;
                        foreach (String str in thisLineSplit)
                        {
                            if (str.StartsWith("Name") && str.Equals(query))
                            {
                                foundResult = true;
                                break;
                            }
                        }
                        if (foundResult)
                        {
                            return new String[] {allLines[i]};
                        }
                    }
                }
     
                return results;
            }
     
            #endregion
        }
    }
    
  4. This connector supports only the CreateEqualsExpression operation. Implement the CreateEqualsExpression. Example 11-3 illustrates the sample implementation of Org.IdentityConnectors.Framework.Common.Objects.Filters.AbstractFilterTranslator<T> that defines the filter operation.

    Example 11-3 Implementation of AbstractFilterTranslator<T>

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Org.IdentityConnectors.Framework.Common.Objects.Filters;
    using Org.IdentityConnectors.Framework.Common.Objects;
     
    namespace Org.IdentityConnector.FlatFileConnector
    {
        /// <summary>
        /// FlatFileFilterTranslator. This translator converts the equalsFilter provided by the calling application to native query which can be used by the connector while searching.
        /// The implementation shown supports only equals filter. i.e it has provided implementation for only CreateEqualsExpression, this means that if any other filter is provided 
        /// by the calling application, it would not be translated as a native query and search implementation gets all users and filtering will be done by ICF with all results.
        /// 
        /// </summary>
        public class FlatFileFilterTranslator : AbstractFilterTranslator<String>
        {
            /// <summary>
            /// Creates a native query for equals filter and returns it only if equals filter is constructed for Name attribute and not for any other attributes.
            /// </summary>
            /// <param name="filter">Filter provided by calling application</param>
            /// <param name="not"></param>
            /// <returns></returns>
            protected override string CreateEqualsExpression(EqualsFilter filter, bool not)
            {
                ConnectorAttribute attr = filter.GetAttribute();
                if (attr.Name.Equals(Name.NAME))
                {
                    return "Name:" + attr.Value.First().ToString();
                }
                return null;
            }
        }
    }
    
  5. Implement the different classes (as mentioned in steps 2, 3, and 4).

  6. Make a note of AssemblyVersion present in the AssemblyInfo.cs of the project.

    Sample AssemblyInfo.cs file:

    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
     
    // General Information about an assembly is controlled through the following 
    // set of attributes. Change these attribute values to modify the information
    // associated with an assembly.
    [assembly: AssemblyTitle("FlatFileConnector")]
    [assembly: AssemblyDescription("")]
    [assembly: AssemblyConfiguration("")]
    [assembly: AssemblyCompany("Oracle Corporation")]
    [assembly: AssemblyProduct("FlatFileConnector")]
    [assembly: AssemblyCopyright("Copyright © Oracle Corporation 2012")]
    [assembly: AssemblyTrademark("")]
    [assembly: AssemblyCulture("")]
     
    // Setting ComVisible to false makes the types in this assembly not visible 
    // to COM components.  If you need to access a type in this assembly from 
    // COM, set the ComVisible attribute to true on that type.
    [assembly: ComVisible(true)]
     
    // The following GUID is for the ID of the typelib if this project is exposed to COM
    [assembly: Guid("79eec317-62bd-49a5-9512-88d61135684c")]
     
    // Version information for an assembly consists of the following four values:
    //
    //      Major Version
    //      Minor Version 
    //      Build Number
    //      Revision
    //
    // You can specify all the values or you can default the Build and Revision Numbers 
    // by using the '*' as shown below:
    // [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]
    
  7. Build the project. The project must create the connector DLL.

11.2 Deploying the Identity Connector Bundle on .NET Connector Server

For all the connectors that are implemented in .NET, you need to have .NET Connector Server for the execution of the connector. The connector bundle cannot be deployed within Oracle Identity Manager. Therefore, you must perform the following procedures in order to integrate the ICF .NET Identity Connector with Oracle Identity Manager:

11.2.1 Registering the Connector Bundle with .NET Connector Server

For registering or deploying the connector bundle on .NET Connector Server, perform the following steps:

  1. Install the .NET Connector Server. See Section 9.6.2.1, "Installing the .NET Connector Server" for more information about installing the .NET Connector Server.

  2. Stop the Connector Server. Make sure that Connector Server Service is not running.

  3. Copy the connector DLL in the CONNECTOR_SERVER_HOME location. CONNECTOR_SERVER_HOME is the location where ConnectorServer.exe and other connector server related files are present after .NET Connector Server installation.

  4. Start the .NET Connector Server.

11.2.2 Creating Basic Identity Connector Metadata

This metadata configuration is needed for both provisioning and reconciliation. Perform the following procedures by using the Oracle Identity Manager Design Console.

11.2.2.1 Creating the IT Resource Type Definition

An IT resource type definition is the representation of a resource's connection information. The configuration parameters in the IT resource type definition should be matched with the configuration parameters of the connector bundle. The values of the parameters in the IT resource will be set in the bundle configuration.

Note:

You may include parameters the bundle configuration is not using. They produce no negative effects on the bundle operations.
  1. Log in to the Oracle Identity Manager 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 Flat File.

  4. Add the following parameters as illustrated in Figure 11-1.

    • Configuration Lookup is the marker of the main configuration lookup for the resource. The name of the parameter must be Configuration Lookup. It is a good practice to add a value to Default Field Value.

    • Delimiter maps to the Delimiter parameter in the bundle configuration. The value of this parameter will be passed.

    • FileName maps to the FileName parameter in the bundle configuration. The value of this parameter will be passed.

    • Connector Server Name, provide the connector server IT Resource name where .NET Connector Server is running.

      Figure 11-1 IT Resource Type Definition in Design Console

      Description of Figure 11-1 follows
      Description of "Figure 11-1 IT Resource Type Definition in Design Console"

11.2.2.2 Creating the Resource Object

The resource object is the Oracle Identity Manager representation of a resource. The connector bundle is tied to the resource object.

  1. Log in to the Oracle Identity Manager Design Console.

  2. Click Resource Objects under Resource Management.

  3. Create a new resource object with the name Flat File.

    As the resource object is a target resource, do not check the Trusted Source box as illustrated in Figure 11-2.

    Figure 11-2 Resource Objects in Design Console

    Description of Figure 11-2 follows
    Description of "Figure 11-2 Resource Objects in Design Console"

11.2.2.3 Creating Lookups

Separate lookups have to be defined for different objects supported by the connector bundle. This lookup can contain provisioning and reconciliation related information for those objects. The Main Configuration Lookup is the root for object specific lookups as it contains the pointers to those lookups. The following sections contain information on how to create lookups.

11.2.2.3.1 Creating the Main Configuration Lookup

The Configuration Lookup (as defined in Section 11.2.2.1, "Creating the IT Resource Type Definition") holds connector bundle configurations that are not counted as connection information. If a configuration parameter is not found in the IT Resource Type Definition, Oracle Identity Manager will look in the Configuration Lookup. The main Configuration Lookup contains bundle properties and bundle configurations. Bundle Property parameters are mandatory as they are needed for identifying the correct bundle. Bundle configurations that are not defined as part of the IT resource type definition (discussed in Section 11.2.2.1, "Creating the IT Resource Type Definition") can be declared here.

Note:

The values for Code Key should match exactly as illustrated. The values for Decode are specific to the connector bundle.
  1. Log in to the Oracle Identity Manager Design Console.

  2. Click Lookup Definition under Administration.

  3. Create a new lookup and add Lookup.FlatFile.Configuration as the value for Code.

  4. Add the following Lookup Code Information as illustrated in Figure 11-3.

    • Add AssemblyVersion as the required Bundle Version.

    • Add FlatFile.Connector as the required Bundle Name. The bundle name can be identified from the connector dll name. Connector DLL is in BUNDLE_NAME.dll format.

    • Add Org.IdentityConnector.FlatFileConnector.FlatFileConnector as the required Connector Name.

    • OBJECT_TYPE_NAME Configuration Lookup is the configuration lookup for the particular object type. In this example, the object type is User as User Configuration Lookup is defined.

    Figure 11-3 Lookup Definition in Design Console

    Description of Figure 11-3 follows
    Description of "Figure 11-3 Lookup Definition in Design Console"

11.2.2.3.2 Creating Object Type Configuration Lookup

Object type configuration lookup contains the parameters specific to the particular object type. Object type is an entity over which an identity connector operates. It is mapped to ICF ObjectClass. In Section 11.2.2.3.1, "Creating the Main Configuration Lookup," User Configuration Lookup has been referenced so that User is the object type, in this case mapped to ObjectClass.ACCOUNT. (Roles and UserJobData are two other object types.) The object type name has to match with ObjectClass name supported by the identity connector bundle. The User object type is mapped to predefined ObjectClass.ACCOUNT, the Group object type is mapped to predefined ObjectClass.GROUP. If the identity connector supports multiple objects, then this step must be repeated for each.

Note:

Because these use cases cover only the basic functionality, the configuration is kept to the mandatory attribute.
  1. Log in to the Oracle Identity Manager Design Console.

  2. Click Lookup Definition under Administration.

  3. Create a new Lookup and add Lookup.FlatFile.UM.Configuration as the Code.

  4. Set the following attributes as illustrated in Figure 11-4.

    Note:

    This tutorial focuses on the minimum configurations needed to run an identity connector.
    • Provisioning Attribute Map takes a value of Lookup.FlatFile.UM.ProvAttrMap. This lookup contains the mapping between Oracle Identity Manager fields and identity connector attributes. The mapping is used during provisioning.

    • Reconciliation Attribute Map takes a value of Lookup.FlatFile.UM.ReconAttributeMap. This lookup contains the mapping between Oracle Identity Manager reconciliation fields and identity connector attributes. The mapping is used during reconciliation.

      Figure 11-4 Second Lookup Definition in Design Console

      Description of Figure 11-4 follows
      Description of "Figure 11-4 Second Lookup Definition in Design Console"

11.2.3 Creating Provisioning Metadata

The following sections should be followed in order to configure Oracle Identity Manager for flat file provisioning.

11.2.3.1 Creating a Process Form

A process form is used as the representation of object attributes on Oracle Identity Manager. This facilitates user input to set object attributes before passed to the connector bundle for an operation.

Attributes defined in the process form are not conventions. The form is a way to challenge the attributes that need to be passed to the identity connector. In general, define an attribute for each supported attribute in the identity connector.

Note:

It is good practice to have a one to one mapping on the identity connector attributes.

There should be a field for querying the IT resource that should be associated with the respective IT Resource Type Definition. Variable type of each field should map to the type of the object attribute.

  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_FLATFILE as illustrated in Figure 11-5.

    Figure 11-5 Form Designer in Design Console

    Description of Figure 11-5 follows
    Description of "Figure 11-5 Form Designer in Design Console"

  4. Add the attributes defined in the connector schema, as listed in Table 11-1.

    Table 11-1 Form Designer Fields

    Name Variant Field Label Field Type

    UD_FLATFILE_NAME

    String

    Name

    TextField

    UD_FLATFILE_AGE

    String

    Age

    TextField

    UD_FLATFILE_QUALIFICATION

    String

    Qualification

    TextField

    UD_FLATFILE_GENDER

    String

    Gender

    LookupField

    UD_FLATFILE_RETURNIDQ

    String

    Return Id

    DOField

    UD_FLATFILE_ITRESOURCE

    Long

    IT Resource

    ITResourceLookup


    Note:

    The flat file column names are FirstName, ChangeNo, EmailID, Server, LastName, and AccountID.
  5. Click the Properties tab.

  6. Add the following properties to Server(ITResourceLookupField) as illustrated in Figure 11-6.

    • Required = true

    • Type = Flat File

    Figure 11-6 Properties of Form Designer in Design Console

    Description of Figure 11-6 follows
    Description of "Figure 11-6 Properties of Form Designer in Design Console"

  7. Save the form.

  8. Click Make Version Active.

11.2.3.2 Creating Adapters

An adapter has to be created for all operations supported by the connector bundle, including Create, Update, and Delete.

  1. Log in to the Oracle Identity Manager Design Console.

  2. Click Adapter Factory under Development Tools.

  3. Create a new adapter and add Flat File Create User as the Adapter Name.

  4. Add Process Task as the Adapter Type.

  5. Save the adapter.

  6. Click the Variable List tab and add the following variables, as shown in Figure 11-7.

    • objectType with Type String and Mapped as Resolve at runtime.

    • processInstanceKey with Type long and Mapped as Resolve at runtime.

    • itResourceFieldName with Type String and Mapped as Resolve at runtime.

    Figure 11-7 Adapter Factory Variable List in Design Console

    Description of Figure 11-7 follows
    Description of "Figure 11-7 Adapter Factory Variable List in Design Console"

  7. Add a Java functional task to the adapter by following this sub procedure, as shown in Figure 11-8.

    1. Click the Adapter Tasks tab.

    2. Select the adapter and click Add.

    3. Select Java from the task options.

    4. Select icf-oim-intg.jar from the API source.

    5. Select oracle.iam.connetors.icfcommon.prov.ICProvisioninManager as the API Source.

    6. Select createObject as the method for the task.

    7. Save the configurations.

    8. Map the variables (previously added to the Variables List) against the appropriate method inputs and outputs.

    9. Map the configuration parameters against the appropriate method inputs and outputs.

      Database Reference maps to Database Reference (Adapter References) and Return Variable maps to Return Variable (Adapter Variables).

    Figure 11-8 Adapter Factory in Design Console

    Description of Figure 11-8 follows
    Description of "Figure 11-8 Adapter Factory in Design Console"

  8. Save and build the adapter.

11.2.3.3 Creating A Process Definition

Process Definition defines the behavior of the connector bundle for a particular operation. Every operation has a corresponding task associated with it. This procedure will configure the process definition and integration of the process task for the Create operation.

  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 Flat File as illustrated in Figure 11-9.

    Figure 11-9 Process Definition in Design Console

    Description of Figure 11-9 follows
    Description of "Figure 11-9 Process Definition in Design Console"

  4. Select Provisioning as the Type of process.

  5. Provide the resource Object Name for the identity connector; in this example, Flat File.

  6. Provide the process form Table Name; in this example, UD_FLATFILE.

  7. Add a process task and name it Create User.

  8. Double click Create User to edit as illustrated in Figure 11-10.

    Figure 11-10 Editing Task Screen in Design Console

    Description of Figure 11-10 follows
    Description of "Figure 11-10 Editing Task Screen in Design Console"

  9. Click the Integration tab.

  10. Click Add and select the adpFLATFILECREATEUSER from the list as illustrated in Figure 11-11.

    The adapter will be available only after it is compiled.

    Figure 11-11 Integration Tab in Design Console

    Description of Figure 11-11 follows
    Description of "Figure 11-11 Integration Tab in Design Console"

  11. Map the variables as follows to set the response code returned by the identity connector.

    • Adapter Return Variable – Response Code

    • Object Type – [Literal:String] User (Name of the object type)

    • Process Instance Key – [Process Data] Process Instance

    • IT Resource Field Name – [Literal:String] UD_FLATFILE_ITRESOURCE (Form field name that contains the IT resource information)

  12. Click the Responses tab and configure the responses as illustrated in Figure 11-12.

    • UNKNOWN can be described as Unknown response received with a status of R (Rejected).

    • SUCCESS can be described as Operation completed with a status of C (Completed).

    • ERROR can be described as Error occurred with a status of R.

    Figure 11-12 Configure Responses in Design Console

    Description of Figure 11-12 follows
    Description of "Figure 11-12 Configure Responses in Design Console"

  13. Click the Task to Object Status Mapping tab.

  14. Update the Object Status to Provisioned for Status C, as shown in Figure 11-13:

    Figure 11-13 Task to Object Status Mapping

    Description of Figure 11-13 follows
    Description of "Figure 11-13 Task to Object Status Mapping"

  15. Save the process task.

11.2.3.4 Creating a Provisioning Attribute Mapping Lookup

Provisioning Attribute Mapping Lookup contains mappings of Oracle Identity Manager fields to identity connector bundle attributes. In the Provisioning Attribute Mapping Lookup:

  • Code keys are Field Labels of the process form.

  • Decodes are identity connector bundle attributes.

  • Child form attributes can be configured as embedded objects in inputs.

  • The identity connector's provisioning operation returns the UID in response. This can be set in a form field by coding it against the identity connector bundle attribute.

Following is the procedure to create a Provisioning Attribute Mapping Lookup.

  1. Log in to the Oracle Identity Manager Design Console.

  2. Click Lookup Definition under the Administration tab.

  3. Create a new lookup and name it Lookup.FlatFile.UM.ProvAttrMap.

    The name of this lookup is referred from the object type configuration lookup. See Section 11.2.2.3.2, "Creating Object Type Configuration Lookup."

  4. Add the form Field Labels as the code keys and identity connector bundle attributes as the decode as shown in Figure 11-14.

    • Name : __NAME__

    • Gender: Gender

    • Return Id: __UID__

    • Age: Age

    • Qualification: Qualification

    Figure 11-14 Lookup Code Mapping

    Description of Figure 11-14 follows
    Description of "Figure 11-14 Lookup Code Mapping"

11.2.3.4.1 Field Flags Used in the Provisioning Attributes Map

Note:

These properties are advanced options and can be skipped for the current implementation of the connector.

For provisioning attributes mapping, the following field flags can be appended to the code key:

  • LOOKUP: This must be specified for all fields whose values are obtained by running a lookup reconciliation job. The values obtained from lookup reconciliation job have IT Resource Name/Key appended to it. Specifying this flag helps ICF integration to remove the appended value just before passing them onto the bundle. For example, the code key for a field with label Database whose value is obtained by running a lookup reconciliation job looks similar to Database[LOOKUP].

    Note:

    The LOOKUP flag can be specified for both Provisioning and Reconciliation Attribute Map. For provisioning, IT Resource Name/IT Resource Key prefix must be removed. For reconciliation, IT Resource Name/IT Resource Key prefix must be added.
  • IGNORE: This must be specified for all fields whose values are to be ignored and not sent to bundle. For example, the code key for a field with label Database whose value need not be sent to bundle looks similar to Database[IGNORE].

  • WRITEBACK: This must be specified for all fields whose values need to be written back into the process form right after the create or update operation. Adding this flag makes the ICF integration layer call ICF Get API to get values of attributes marked with the WRITEBACK flag. For example, the code key for a field with label Database whose value needs to be written back to the process form right after create/update looks similar to Database[WRITEBACK]. For this to work, the connector must implement the GetApiOp interface and provide an implementation for the ConnectorObject getObject(ObjectClass objClass,Uid uid,OperationOptions options) API. This API searches the target for the account whose Uid is equal to the passed in Uid, and builds a connector object containing all the attributes (and their values) that are to be written back to process form.

    Note:

    If the connector does not implement the GetApiOp interface, then the WRITEBACK flag does not work and an error is generated.
  • DATE: This must be specified for fields whose type need to be considered as Date, without which the values are considered as normal strings. For example, the code key for a field with label Today whose value needs to be displayed in the date format looks similar to Today[DATE].

  • PROVIDEONPSWDCHANGE: This must be specified for all fields that need to be provided to the bundle(target) when a password update happens. Some targets expect additional attributes to be specified on every password change. Specifying the PROVIDEONPSWDCHANGE flag, tells ICF integration to send all the extra fields or attributes whenever a password change is requested. For example, the code key for a field with label Extra Attribute Needed for Password Change whose value needs to be provided to bundle(target) while password update looks similar to Extra Attribute Needed for Password Change[PROVIDEONPSWDCHANGE].

11.2.4 Creating Reconciliation Metadata

This section contains the procedures to configure the reconciliation of records from the flat file. We will use the target reconciliation as an example; trusted reconciliation can also be configured in a similar fashion. Do the procedures in the listed order.

11.2.4.1 Creating a Reconciliation Schedule Task

By default, reconciliation uses a Search operation on the connector bundle. This operation is invoked with a schedule task configured using Oracle Identity Manager. This procedure is comprised of the following sub procedures.

  1. Section 11.2.4.1.1, "Defining the Schedule Task"

  2. Section 11.2.4.1.2, "Creating a Scheduled Job"

11.2.4.1.1 Defining the Schedule Task

To define the scheduled task:

  1. Create a Deployment Manager XML file containing the scheduled task details as shown in Example 11-4. Make sure to update database value to your database.

    Example 11-4 Deployment Manager XML with Scheduled Task Details

    <?xml version = '1.0' encoding = 'UTF-8'?>
    <xl-ddm-data version="2.0.1.0" user="XELSYSADM" database="jdbc:oracle:thin:@localhost:5524/estView.regress.rdbms.dev.mycompany.com" exported-date="1307546406635" description="FF">
    <scheduledTask repo-type="MDS" name="Flat File Connector User Reconciliation" mds-path="/db" mds-file="Flat File Connector User Reconciliation.xml">
        <completeXml>
            <scheduledTasks xmlns="http://xmlns.oracle.com/oim/scheduler">
                <task>
                <name>Flat File Connector User Reconciliation</name>
                <class>oracle.iam.connectors.icfcommon.recon.SearchReconTask</class>
                <description>Flat File Connector User Reconciliation</description>
                <retry>0</retry>
                <parameters>
                  <string-param required="false" encrypted="false" helpText="Filter">Filter</string-param>
                  <string-param required="false" encrypted="false" helpText="Incremental Recon Date Attribute">Incremental Recon Date Attribute</string-param>
                  <string-param required="false" encrypted="false" helpText="IT Resource Name">IT Resource Name</string-param>
                  <string-param required="false" encrypted="false" helpText="Object Type">Object Type</string-param>
                  <string-param required="false" encrypted="false" helpText="Latest Token">Latest Token</string-param>
                  <string-param required="false" encrypted="false" helpText="Resource Object Name">Resource Object Name</string-param>
                </parameters>
              </task>
            </scheduledTasks>
        </completeXml>
    </scheduledTask>
    </xl-ddm-data>
    
  2. Save the file as Flat File Connector User Reconciliation.xml.

  3. Login into the Identity System Administration. Under System Management, click Import.

  4. Select the Flat File Connector User Reconciliation.xml file, and click Import.

  5. Complete the steps in the wizard.

11.2.4.1.2 Creating a Scheduled Job

This procedure explains how to create a scheduled task.

  1. Log in to the Oracle Identity Manager Advanced Administration.

  2. Click Scheduler under the System Management tab.

  3. Click New for creating a new scheduled job. After that provide the job name as Flat File and in the Task field, select the value as Flat File Connector User Reconciliation from the lookup. Once the job is created, provide the values in the job as shown in Figure 11-15.Add a scheduled task and add Flat File Connector User Reconciliation as the type as illustrated in Figure 11-15.

    Figure 11-15 Scheduled Task Screen in Advanced Console

    Description of Figure 11-15 follows
    Description of "Figure 11-15 Scheduled Task Screen in Advanced Console"

  4. Set the parameters as follows:

    • IT Resource Name takes a value of Flat File.

    • Resource Object Name takes a value of FLATFILE.

    • Object Type takes a value of User.

  5. Click Apply.

11.2.4.2 Creating a Reconciliation Profile

A reconciliation profile defines the structure of the object attributes while reconciliation. The reconciliation profile should contain all the attributes that have reconciliation support.

  1. Log in to the Oracle Identity Manager Design Console.

  2. Click Resource Objects under Resource Management.

  3. Open the Flat File resource object.

  4. Click the Object Reconciliation tab as illustrated in Figure 11-16.

    Figure 11-16 Object Reconciliation in Design Console

    Description of Figure 11-16 follows
    Description of "Figure 11-16 Object Reconciliation in Design Console"

  5. Add following reconciliation fields:

    • Return Id [String] , Required]

    • Name [String] , Required

    • Gender [String]

    • Age [String]

    • Gender [String]

    • IT Resource Name [IT Resource] , Required

  6. Save the configuration.

11.2.4.3 Setting a Reconciliation Action Rule

A Reconciliation Action Rule defines the behavior of reconciliation. In this procedure, define the expected action when a match is found. This procedure assumes you are logged into the Oracle Identity Manager Design Console.

  1. Open the Flat File resource object.

  2. Click the Object Reconciliation tab.

  3. Click the Reconciliation Action Rules tab in the right frame.

    Figure 11-17 Reconciliation Action Rules in Design Console

    Description of Figure 11-17 follows
    Description of "Figure 11-17 Reconciliation Action Rules in Design Console"

  4. Add an action rule defined as One Process Match Found (Rule Condition) and Establish Link (Action).

  5. Add an action rule defined as One Entity Match Found (Rule Condition) and Establish Link (Action).

  6. Click Create Reconciliation Profile.

  7. Click Save.

11.2.4.4 Creating Reconciliation Mapping

The reconciliation mapping has to be done in the process definition. This is to map the supported reconciliation fields (from resource object) to the process form fields. This mapping is needed only for configuring target reconciliation.

  1. Log in to the Oracle Identity Manager Design Console.

  2. Click Process Definition under Process Management.

  3. Open the Flat File process definition.

  4. Click the Reconciliation Field Mappings tab as illustrated in Figure 11-18.

    Figure 11-18 Reconciliation Field Mapping in Design Console

    Description of Figure 11-18 follows
    Description of "Figure 11-18 Reconciliation Field Mapping in Design Console"

  5. Add mappings between the reconciliation profile fields and the process form fields.

    • ReturnId[String] = UD_FLATFILE_RETURNID

    • Name[String] = UD_FLATFILE_NAME, <KEY>

    • Age[String] = UD_FLATFILE_AGE

    • Gender[String] = UD_FLATFILE_GENDER

    • Qualification[String] = UD_FLATFILE_QUALIFICATION

    • IT Resource Name[IT Resource] = UD_FLATFILE_ITRESOURCE,<KEY>

  6. Save the configuration.

11.2.4.4.1 Field Flags Used in the Reconciliation Attributes Map

9

Note:

These properties are advanced options and can be skipped for the current implementation of the connector

For reconciliation attributes mapping, the following field flags can be appended to the code key:

  • TRUSTED: This must be specified in the Recon Attribute Map for the field that represents the status of the account. This flag must be specified only for trusted reconciliation. If this is specified, then the status of the account is either Active or Disabled. Otherwise, the status is either Enabled or Disabled. For example, the code key for a field with label Status whose value needs to be either Active/Disabled must look similar to Status[TRUSTED].

  • DATE: In Recon Attribute Map, this must be specified for fields whose type need to be considered as Date. For example, the code key for a field with label Today whose value needs to be displayed in the date format must look similar to Today[DATE].

11.2.4.5 Defining a Reconciliation Matching Rule

A reconciliation matching rule defines the equation for calculating the user match.

  1. Log in to the Oracle Identity Manager Design Console.

  2. Open the Reconciliation Rules form under Development Tools.

  3. Click Add Rule.

    Figure 11-19 Adding Reconciliation Matching Rule

    Description of Figure 11-19 follows
    Description of "Figure 11-19 Adding Reconciliation Matching Rule"

  4. Select resource object Flat File.

  5. Once the reconciliation rule element is added, make sure to check Active flag so that the reconciliation rule is made active.

  6. Save and add the rule element.

    User Login from the user profile data equals the Name resource attribute.

  7. Save the rule.

    Note:

    You must recreate the reconciliation profile whenever you make any changes to the reconciliation rule.

11.3 Provisioning a Flat File Account

The flat file connector is ready to work so now the user needs to log in to Oracle Identity Manager and create an IT resource (target) using the following procedure.

  • Create IT resource of type "Flat File".

  • Provide the IT resource parameters as appropriate.

  • Provide the configuration parameters in Lookup.FlatFile.Configuration as appropriate.