Design
Once high level analysis of whether or not a connector can be built or not, we need to start designing the various components.
The following topics are covered in this section:
Source Configuration Template
The source configuration template is the default set of configurations which for the source and connector. In Identity Security Cloud, this defines three things:
-
Default Connector Settings - Configuration values used by the connector, such as host, port, user, password, etc.
-
Default Schema - Default user account attributes, as well as what makes an account unique.
-
Default Correlation - Default logic to match user accounts with owners.
<Application
name="Custom HR Connector"
type="Custom HR Connector"
connector="sailpoint.connector.ExampleConnector"
featuresString="ITERATE" >
<Attributes>
<Map>
<entry key="url" value=""/>
<entry key="username" value=""/>
<entry key="password" value=""/>
<entry key="token" value="OAuth"/>
<entry key="pageSize" value="200"/>
</Map>
</Attributes>
...
<Schemas>
<Schema
identityAttribute="Employee Number"
displayAttribute="Employee Number"
nativeObjectType="account"
objectType="account">
<AttributeDefinition name="First Name" type="string"/>
<AttributeDefinition name="Last Name" type="string"/>
<AttributeDefinition name="Employee Number " type="string"/>
...
</Schema>
</Schemas>
</Application>
In the above example, you can see this is an Application XML object. Application is the internal name for a Source, not to be confused with Application SSO objects in Identity Security Cloud. The default configurations for the connector live in the Attributes section of the configuration.
Object Type and Schema
The account definition lives in the schema section, specified with a objectType="account" attribute. While a connector can technically support multiple schemas, Identity Security Cloud currently only supports schemas with an objectType of account or group. The identityAttribute attribute specifies the Identity Security Cloud Account ID, which is the attribute which makes an account unique (e.g. distinguishedName on LDAP). The displayAttribute attribute specified the Identity Security Cloud Account Name, which is the attribute which an account is known by (e.g. sAMAccountName in AD). Sometimes this can be set the same as the Account ID, and sometimes they differ. It really depends on the object model you are reading from. In this example above, these are set to the same attribute, called "Employee Number" which presumably makes a record unique in the fictional custom HR source above.
Choose Connector Features
The first step in connector design is determining the desired features for the connector. Available features are:
-
AUTHENTICATE: will the connector support authenticating a user and password combination against the resource
-
CREATE: will the connector be able to create a resource object (e.g. account or group)
-
DELETE: will the connector be able to delete a given resource object (by ID)
-
DISCOVER_SCHEMA: will the connector report schemas (account or group) to Identity Security Cloud when queried, including both attribute names and types (valid types are BOOLEAN, DATE, INT, SECRET, STRING)
-
ENABLE: will the connector support enabling or disabling of a resource object
-
GET: will the connector be able to read and return a map of a specific resource object (by ID)
-
ITERATE: will the connector return an iterator of resource objects (possibly a filtered set)
-
PERMISSIONS: will the connector return permission attributes
-
SET_PASSWORD: will the connector set the password of a resource object
-
UNLOCK: will the connector be able to unlock a resource object
-
UPDATE: will the connector support updates of resource objects
These features are listed as an enumeration in the openconnector.connector class, but this enumeration is not currently used in determining connector functionality; it is provided only as a connector design guide. The Application object also has a Feature enumeration, specified as the FeaturesString attribute of the application definition, which is used to control the functionality available through the connector (as discussed in the Integrating with Identity Security Cloud section of this document). The Connector Feature enumeration overlaps with but is not identical to the Application Feature enumeration. They correlate as shown here:
Connector Features |
Application Features |
---|---|
AUTHENTICATE |
AUTHENTICATE |
CREATE |
PROVISIONING |
DELETE |
PROVISIONING |
DISCOVER_SCHEMA |
DISCOVER_SCHEMA |
ENABLE |
ENABLE and PROVISIONING together |
GET |
Opposite of NO_RANDOM_ACCESS (this is an assumed function for all applications unless explicitly turned off) |
ITERATE |
No specific feature: assumed functionality for all applications |
PERMISSIONS |
DIRECT_PERMISSIONS |
SET_PASSWORD |
PASSWORD and PROVISIONING together |
UNLOCK |
UNLOCK and PROVISIONING together |
UPDATE |
PROVISIONING |
User Interface Forms
Once we understand all the configurations, we can start designing the user interface forms. The user interface forms which you interact with, and provide configurable elements which an administrator can configure a particular source. It looks something like this in Identity Security Cloud:
The technical implementation of this is built as an XML form object, which is understood by Identity Security Cloud and renders configurable form elements such as text fields, checkboxes, radio buttons, or select boxes. These also support default values (assuming your source configuration template doesn't define these), and you can even mark fields as required or hidden. It is up to you as an implementer to decide which configurations you should expose where. You can leverage Identity Security Cloud's ‘Advanced’ Section to hide more complex configurations if you need to.
The implementation of an example form looks something like this:
<Form ... >
<Section layout="horizontal">
<Section label="Connection Credentials" layout="horizontal">
<Field name="url" type="String" displayName="URL" required="true" defaultValue="https://tenant.myhr.com"/>
<Field name="user" type="String" displayName="Username" required="true"/>
<Field name="password" type="Secret" displayName="Password" required="true"/>
</Section>
<Section label="Advanced Settings" layout="horizontal">
<Field name="pageSize" type="String" displayName="Page Size" defaultValue="20"/>
<Field name="token" displayName="Document Type" type="String" required="true">
<AllowedValues>
<List>
<String>OAuth</String>
<String>PKI</String>
...
</List>
</AllowedValues>
</Field>
...
</Form>
Custom Connector Development
The next phase of the implementation of the connector, is to develop the technical implementation of the connector using the OpenConnector framework. The custom connector architecture uses the OpenConnector framework provided by SailPoint in the openconnector package. All custom connectors must inherit from openconnector.AbstractConnector, which in turn implements the openconnector.Connector interface. The connectors are stateful and require configuration, use, and finally closure. The connector SDK, which includes the OpenConnector classes and the javadocs, is attached to this article for your future development needs.
Using the openconnector framework, developers must implement separate methods for different types operations. These methods are automatically called by the various Identity Security Cloud interfaces in the cloud connector gateway in the VA. The popular methods of the openconnector framework are as follows:
Which methods you choose to implement, are ultimately up to you. However here is a chart which details these in greater detail:
Methods marked with an asterisk (*) are required for any custom connector, regardless of the feature set chosen. However, the custom connector can simply defer to the AbstractConnector’s default behavior instead of implementing its own version of the method when that method has been defined in the AbstractConnector class. AbstractConnector’s provided functionality for each of these methods is noted below. In some cases, AbstractConnector provides some default functionality that can be used or overridden by the custom class. In other cases, it contains no method or contains a method that throws an unsupported operation exception, both of which require the method to be written in the custom connector class for the operation to be supported.
Method |
Description |
Default Behavior of AbstractConnector's Method |
---|---|---|
getSupportedObjectTypes() * |
Should return a list of the connector's supported object types. |
Returns Account |
getSupportedFeatures() |
Should return the list of supported features for the connectorNOTE: This method is not currently used by Identity Security Cloud; instead, the application object's FeaturesString is used to determine the connector's supported features. |
Returns GET and ITERATE |
configure() * |
Should set up any configuration information which might be helpful in supporting other connector functionality; this is called only once during connector construction Note
|
Saves the connector config and log objects passed to it in local variables for later use by other methods. |
setObjectType() * |
Should set the object type, which can influence the read, iterate, and provision behaviors of the connector when the methods supporting those functions contain separate functionality for each object type; is called by the OpenConnectorAdapter to set the correct target object type before executing operations. |
Sets the object type to the type named in the method call (defaulting to “account” if none named) and retrieves the schema for that type from the connector configuration. |
close() |
Should perform any required steps to close the connection to the application. |
Does nothing |
testConnection() * |
Should determine if the resource is accessible; e.g. connect to the application with login credentials pulled from the connector configuration. |
Throws unsupported |
discoverSchema() |
Should return the schema (attributes and data types) of the currently selected object type. |
Throws unsupported |
authenticate() |
Should connect to the application with the credentials provided in the method call and attempt to authenticate to the application with that user id and password. |
Throws unsupported |
read() |
Should refresh the account or group in Identity Security Cloud corresponding to the provided native identity to match its current values in the application (i.e. targeted aggregation functionality)This can also be used in preparation for an update operation to ensure Identity Security Cloud has the latest data from the application before performing any updates. |
Not implemented |
iterate() |
Should return an iterator over the accounts/groups in the application (can be a subset of accounts/groups based on a specified filter). |
Not implemented |
provision() |
Should parse the provisioningPlan and drive provisioning activities. Note
|
Splits the plan into individual actions for each request type (delete, create, update, enable, etc.) and calls other methods to provide the requested action. |
delete() ^ |
Should delete the object from the application based on the native identifier. |
Throws unsupported |
create() ^ |
Should create an account (or group) in the application given a native identifier and a list of attribute values. |
Throws unsupported |
update() ^ |
Should update the values for the specified account or group, matched by native identifier. |
Throws unsupported |
enable() ^ |
Should enable the object on the application based on native identifier. |
Throws unsupported |
disable() ^ |
Should disable the object on the application based on native identifier. |
Throws unsupported |
unlock() ^ |
Should unlock the account on the application based on native identifier. |
Throws unsupported |
setPassword() |
Should set/reset the account password on the application, given a native identifier, new password, optional current password, and expiration date. |
Throws unsupported |
* - Required method
^ - These methods each accept a hashmap of options which can influence the operation. Any arguments passed in the request (within the provisioning plan) are passed to the target method by the provision() method to be used as needed by the connector.
Methods can throw any of the following exceptions: ConnectorException, AuthenticationFailedException, UnsupportedOperationException, ObjectAlreadyExistsException, ObjectNotFoundException, or ExpiredPasswordException.