PingAM 7.5.1

Customize identity stores

Your deployment might require additional functionality than that offered by the default AM identity store. Use these sections to create custom attributes to store additional information in identity stores, or to create identity repository plugins to customize how AM maps users and groups to a realm:

Add custom user profile attributes

You can extend user profiles by adding custom attributes. This section shows how to add a custom attribute to user profiles stored in the LDAP directory.

Adding a custom attribute involves updating the identity repository schema to hold the new attribute, and updating the UI. To give users write permissions to the custom attribute, you must also update the AM configuration store.

This section includes the following procedures:

Update the identity repository for a custom attribute

These steps update the identity repository schema for the custom attribute, then update AM to use the custom attribute and object class.

If you intend to use an existing attribute that is already allowed in user profile entries, you can skip these steps.

  1. Prepare the attribute type object class definitions in LDIF format. For example:

    $ cat custom-attr.ldif
    dn: cn=schema
    changetype: modify
    add: attributeTypes
    attributeTypes: ( temp-custom-attr-oid NAME 'customAttribute' EQUALITY case
     IgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstrings
     Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications )
    -
    add: objectClasses
    objectClasses: ( temp-custom-oc-oid NAME 'customObjectclass' SUP top AUXILIARY
      MAY customAttribute )

    In this example, the attribute type is called customAttribute and the object class is called customObjectclass.

  2. Add the schema definitions to the directory.

    $ /path/to/opendj/bin/ldapmodify \
    --hostname 'id.example.com' \
    --port 1636 \
    --useSsl \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --truststorepassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=admin \
    --bindPassword str0ngAdm1nPa55word \
    /path/to/custom-attr.ldif
    Processing MODIFY request for cn=schema
    MODIFY operation successful for DN cn=schema
  3. In the AM admin UI, go to Realms > Realm Name > Identity Stores > Identity Store Name > User Configuration.

  4. Add the object class, for example customObjectclass, to the LDAP User Object Class list.

  5. Add the attribute type, for example customAttribute, to the LDAP User Attributes list.

  6. Save your work.

  7. Add the attribute type to the profile attribute allowlist.

    The profile attribute allowlist controls the information returned to non-administrative users when they send requests to json/user endpoints. For example, the allowlist controls the attributes shown in the user profile page.

    Common profile attributes are allowlisted by default. You must add any custom attributes that you want non-administrative users to see.

    The allowlist can be set globally, or per realm, in the user self-service service. To modify the list:

    Globally

    Go to Configure > Global Services > User Self-Service > Profile Management, and edit the Self readable attributes field.

    By realm

    Go to Realms > Realm Name > Services > User Self-Service > Profile Management, and edit the Self readable attributes field.

You must add the user self-service service to the realm if you have not done so already, but you don’t need to configure anything other than the allowlist.

Use an LDAP browser to let users update custom attributes

Update the AM configuration store to give users write permission to the custom attribute.

This procedure assumes that you use an LDAP browser, for example, Apache Directory Studio. If you use the command line, follow Use the command line to let users update custom attributes.

  1. Connect to the AM configuration store.

    You can see the configuration store details at Deployment > Servers > Directory Configuration > Server.

  2. Search for ou=SelfWriteAttributes.

    You should find DNs similar to the following. The DNs have been folded for legibility:

    • dn:ou=SelfWriteAttributes,ou=Policies,ou=default,ou=OrganizationConfig,ou=1.0, ou=iPlanetAMPolicyService,ou=services,o=sunamhiddenrealmdelegationservicepermissions, ou=services,dc=openam,dc=forgerock,dc=org

    • dn:ou=SelfWriteAttributes,ou=default,ou=default,ou=OrganizationConfig,ou=1.0, ou=sunEntitlementIndexes,ou=services,o=sunamhiddenrealmdelegationservicepermissions, ou=services,dc=openam,dc=forgerock,dc=org

  3. In the entry under iPlanetAMPolicyService, edit the sunKeyValue attribute to add the custom attribute to the list of self-writable attributes.

    For example, <Value>customAttribute</Value>.

  4. In the entry under sunEntitlementIndexes, edit the sunKeyValue attribute to add the custom attribute to the list of self-writable attributes.

    This example shows a custom attribute as the first element of the list:

    \"attributes\": [\n \"customAttribute\",\n …​.

  5. Restart AM or the web container where it runs.

Use the command line to let users update custom attributes

Update the AM configuration store to give users write permission to the custom attribute.

This procedure assumes that you use the command line. Follow Use an LDAP browser to let users update custom attributes if you use an LDAP browser. Adapt the file paths to your configuration store.

  1. Search for the value of sunKeyValue in ou=SelfWriteAttributes by running the following command:

    $ /path/to/opendj/bin/ldapsearch \
     --hostname openam.example.com \
     --port 1636 \
     --useSSL \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --truststorepassword:file /path/to/opendj/config/keystore.pin \
     --bindDn uid=admin \
     --bindPassword myPassword \
     --baseDn "dc=openam,dc=forgerock,dc=org" "(ou=SelfWriteAttributes)" \
     sunKeyValue
    dn: ou=SelfWriteAttributes,ou=Policies,ou=default,ou=OrganizationConfig,ou=1.0,ou=iPlanetAMPolicyService,ou=services,
        o=sunamhiddenrealmdelegationservicepermissions,ou=services,dc=openam,dc=forgerock,dc=org
    sunKeyValue:: eG1scG9saWN5PTw…​…​..
    
    dn: ou=SelfWriteAttributes,ou=default,ou=default,ou=OrganizationConfig,ou=1.0,ou=sunEntitlementIndexes,ou=services,
        o=sunamhiddenrealmdelegationservicepermissions,ou=services,dc=openam,dc=forgerock,dc=org
    sunKeyValue: serializable={"eCondition":{"className":"com.sun…​..

    Note that the command returns two DNs, and the value of sunKeyValue in the first one is base64-encoded.

  2. Decode the base64 string of the iPlanetAMPolicyService DN.

    For example:

    $ ./base64 decode --encodedData eG1scG9saWN5PTw…​…​..
    xmlpolicy=<?xml version="1.0" encoding="UTF-8"?>
    <Policy name="SelfWriteAttributes" createdby="cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org"
     lastmodifiedby="cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" creationdate="1528296269883"
     lastmodifieddate="1528296269883" referralPolicy="false" active="true" >
     <Rule name="user-read-rule">
      <ServiceName name="sunAMDelegationService" />
      <ResourceName name="sms://dc=openam,dc=forgerock,dc=org/sunIdentityRepositoryService/1.0/application/" />
      <AttributeValuePair>
       <Attribute name="MODIFY" />
       <Value>allow</Value>
      </AttributeValuePair>
     </Rule>
     <Subjects name="Subjects" description="">
      <Subject name="delegation-subject" type="AuthenticatedUsers" includeType="inclusive">
      </Subject>
     </Subjects>
     <Conditions name="AttrCondition" description="">
      <Condition name="condition" type="UserSelfCheckCondition">
       <AttributeValuePair>
        <Attribute name="attributes"/>
         <Value>givenname</Value>
         <Value>sn</Value>
         <Value>cn</Value>
         <Value>userpassword</Value>
         <Value>mail</Value>
         <Value>telephonenumber</Value>
         <Value>postaladdress</Value>
         <Value>preferredlocale</Value>
         <Value>iplanet-am-user-password-reset-options</Value>
         <Value>iplanet-am-user-password-reset-question-answer</Value>
         <Value>description</Value>
         <Value>oath2faEnabled</Value>
         <Value>sunIdentityServerDeviceKeyValue</Value>
         <Value>sunIdentityServerDeviceStatus</Value>
       </AttributeValuePair>
      </Condition>
     </Conditions>
    </Policy>
  3. Create a file with the decoded string, then add the custom attribute to the <AttributeValuePair> list. For example:

    $ vi to-encode.xml
    …​
       <Attribute name="attributes"/><Value>customAttribute</Value><Value>givenname</Value>…​</AttributeValuePair>
    …​
  4. Base64-encode the content of the file.

    For example:

    $ ./base64 encode -f to-encode.xml
    EG1scG9saWN5PTw22…​..
  5. Create an LDIF file, for example, change.ldif.

    The following excerpt is an example of the LDIF file:

    dn: ou=SelfWriteAttributes,ou=Policies,ou=default,ou=OrganizationConfig,ou=1.0,ou=iPlanetAMPolicyService,
        ou=services,o=sunamhiddenrealmdelegationservicepermissions,ou=services,dc=openam,dc=forgerock,dc=org
    changetype: modify
    replace: sunKeyValue
    sunKeyValue: EG1scG9saWN5PTw22.....
    
    dn: ou=SelfWriteAttributes,ou=default,ou=default,ou=OrganizationConfig,ou=1.0,ou=sunEntitlementIndexes,
        ou=services,o=sunamhiddenrealmdelegationservicepermissions,ou=services,dc=openam,dc=forgerock,dc=org
    changetype: modify
    replace: sunKeyValue
    sunKeyValue: serializable={"eCondition":{"className": ...  \"properties\":
        {\"attributes\": [\n    \"customAttribute\",\n    \"givenname\",\n    \"sn\",\n  ... \"values\": []\n}"}
    }

    The file must contain the following:

    • The LDIF properties and rules required to modify the value of the sunKeyValue attribute for both DNs.

    • The base64-encoded string as the value of the sunKeyValue attribute of the iPlanetAMPolicyService DN. The string already contains the custom attribute.

    • The value of the sunKeyValue attribute of the sunEntitlementIndexes DN. You must add the custom attribute inside the attributes list.

  6. Apply the changes in the LDIF file to the LDAP configuration store, as follows:

    $ /path/to/opendj/bin/ldapmodify \
    --hostname 'id.example.com' \
    --port 1636 \
    --useSsl \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --truststorepassword:file /path/to/opendj/config/keystore.pin \
    --bindDn uid=admin \
    --bindPassword str0ngAdm1nPa55word \
    --filename change.ldif
    # MODIFY operation successful for DN ou=SelfWriteAttributes,ou=Policies,ou=default,ou=OrganizationConfig,ou=1.0,
      ou=iPlanetAMPolicyService,ou=services,o=sunamhiddenrealmdelegationservicepermissions,ou=services,dc=openam,dc=forgerock,dc=org
    # MODIFY operation successful for DN ou=SelfWriteAttributes,ou=default,ou=default,ou=OrganizationConfig,ou=1.0,
      ou=sunEntitlementIndexes,ou=services,o=sunamhiddenrealmdelegationservicepermissions,ou=services,dc=openam,dc=forgerock,dc=org
  7. Restart AM or the web container where it runs.

Add custom attributes to the end-user UI

To ensure the new attribute shows up in the user profile, you must download the UI source code, edit it, then rebuild the UI.

  1. Download the UI source.

  2. Modify the UI as follows:

    • Edit the openam-ui-user/src/resources/locales/en/translation.json file and add a new line with the description for the custom attribute. This description will show in the UI user’s profile page. For example:

      {
          "profile": "Profile",
          "username" : "Username",
          "emailAddress" : "Email address",
          "givenName" : "First Name",
          "customAttribute" : "My Custom Attribute",
          "sn" : "Last Name",
          "changePassword" : "Change password"
      }

      Note that the example adds the custom attribute under the common.user JSON path.

      If you have translated the UI pages, remember to edit all the translation.json files in your installation.
    • Edit the openam-ui-user/src/resources/themes/default/templates/user/UserProfileTemplate.html file and add a new line for the custom attribute. Consider the following points:

      • property must contain the name of the custom attribute created in the LDAP. For example, customAttribute.

      • label must contain the path to the label created in the translation.json file. In this case, common.user.customAttribute.

        For example:

        {{#user}}
          {{> form/_basicInput property="username" label="common.user.username" readonly=true}}
          {{> form/_basicInput property="givenName" label="common.user.givenName"}}
          {{> form/_basicInput property="sn" label="common.user.sn" required="true"}}
          {{> form/_basicInput type="email" property="mail" label="common.user.emailAddress"
          extraAttributes='data-validator="validEmailAddressFormat" data-validator-event="keyup"' }}
          {{> form/_basicInput type="tel" property="telephoneNumber" label="common.user.phoneNumber"
          extraAttributes='data-validator="validPhoneFormat" data-validator-event="keyup"'}}
          {{> form/_basicInput property="customAttribute" label="common.user.customAttribute"}}
        {{/user}}
    • Edit the openam-ui-user/src/js/org/forgerock/openam/ui/user/UserModel.js file and add the custom attribute on the ServiceInvoker.restCall function.

      Consider the following constraints when modifying this file:

      • The file does not support tab indentation. You must use space indentation.

      • The file does not support lines longer than 120 characters. If the line you are modifying exceeds this limit, break it into multiple lines.

        For example:

        return ServiceInvoker.restCall(_.extend(
        {
            type: "PUT",
            data: JSON.stringify(
                _.chain(this.toJSON())
                .pick(["givenName", "sn", "mail", "postalAddress", "telephoneNumber", "customAttribute"])
                .mapValues((val) => {
                    ...
        }
  3. Rebuild the UI by running the yarn build command.

  4. Test the UI pages by following the steps detailed in Test and deploy the UI.

    The UI user profile page now shows the custom attribute, and users are able to read and write its values:

    Users are able to read and write the custom attribute value.
  5. Once you are satisfied with the changes, deploy the output in the build directory to the /path/to/tomcat/webapps/openam/XUI/ directory of your AM instances.

    You don’t need to restart the AM instance. Subsequent visits to the UI pages will use the rebuilt files.

Customize identity data storage with an IdRepo plugin

AM maps user and group identities to realms using data stores. Data stores rely on a Java identity repository (IdRepo) plugin to interact with the identity repository that stores the users and groups.

This section describes how to create a custom identity repository plugin. AM includes built-in support for LDAP identity repositories. For most deployments, you therefore do not need to create your own identity repository plugin. Only create custom identity repository plugins for deployments with particular requirements not met by built-in AM functionality.

IdRepo plugin inheritance

Your identity repository plugin class must extend the com.sun.identity.idm.IdRepo abstract class, and must include a constructor method that takes no arguments.

IdRepo plugin lifecycle

When AM instantiates your IdRepo plugin, it calls the initialize() method.

public void initialize(Map configParams)

configParams are service configuration parameters for the realm where the IdRepo plugin is configured. They set up communication with the underlying identity store. AM calls the initialize() method once, and considers the identity repository ready for use.

If you encounter errors or exceptions during initialization, catch and store them in your plugin for use later when AM calls other plugin methods.

After initialization, AM calls the addListener() and removeListener() methods to register listeners that inform AM client code of changes to identities managed by your IdRepo.

public int addListener(SSOToken token, IdRepoListener listener)
public void removeListener()

Your IdRepo plugin must handle listener registration, and return events to AM through the IdRepoListener.

When stopping, AM calls your IdRepo plugin shutdown() method.

public void shutdown()

You don’t need to implement the shutdown() method, unless your IdRepo plugin has shutdown work of its own to do, such as closing connections to the underlying identity store.

IdRepo plugin capabilities

Your IdRepo plugin provides AM with a generic means to manage identities, and to create, read, update, delete, and search identities. Identities include users and groups, and special identity types such as roles, realms, and agents. In order for AM to determine your plugin’s capabilities, it calls the methods described in this section.

getSupportedTypes()

public Set getSupportedTypes()

The getSupportedTypes() method returns a set of IdType objects, such as IdType.USER and IdType.GROUP. You can either hard-code the supported types in your plugin, or make them configurable through the IdRepo service.

getSupportedOperations()

public Set getSupportedOperations(IdType type)

The getSupportedOperations() method returns a set of IdOperation objects, such as IdOperation.CREATE and IdOperation.EDIT. You can either hard-code these operations, or make them configurable.

supportsAuthentication()

public boolean supportsAuthentication()

The supportsAuthentication() method returns true if your plugin supports the authenticate() method.

IdRepo plugin implementation

Your IdRepo plugin implements operational methods, depending on what you support. These methods perform the operations in your data store.

Create

AM calls create() to provision a new identity in the repository, where name is the new identity’s name, and attrMap holds the attributes names and values.

public String create(SSOToken token, IdType type, String name, Map attrMap)
  throws IdRepoException, SSOException
Read

AM calls the following methods to retrieve identities in the identity repository, and to check account activity. If your data store does not support binary attributes, return an empty Map for getBinaryAttributes().

public boolean isExists(
  SSOToken token,
  IdType type,
  String name
) throws IdRepoException, SSOException

public boolean isActive(
  SSOToken token,
  IdType type,
  String name
) throws IdRepoException, SSOException

public Map getAttributes(
  SSOToken token,
  IdType type,
  String name
) throws IdRepoException, SSOException

public Map getAttributes(
  SSOToken token,
  IdType type,
  String name,
  Set attrNames
) throws IdRepoException, SSOException

public Map getBinaryAttributes(
  SSOToken token,
  IdType type,
  String name,
  Set attrNames
) throws IdRepoException, SSOException

public RepoSearchResults search(
  SSOToken token,
  IdType type,
  String pattern,
  Map avPairs,
  boolean recursive,
  int maxResults,
  int maxTime,
  Set returnAttrs
) throws IdRepoException, SSOException

public RepoSearchResults search(
  SSOToken token,
  IdType type,
  String pattern,
  int maxTime,
  int maxResults,
  Set returnAttrs,
  boolean returnAllAttrs,
  int filterOp,
  Map avPairs,
  boolean recursive
) throws IdRepoException, SSOException
Edit

AM calls the following methods to update a subject in the identity repository.

public void setAttributes(
  SSOToken token,
  IdType type,
  String name,
  Map attributes,
  boolean isAdd
) throws IdRepoException, SSOException

public void setBinaryAttributes(
  SSOToken token,
  IdType type,
  String name,
  Map attributes,
  boolean isAdd
) throws IdRepoException, SSOException

public void removeAttributes(
  SSOToken token,
  IdType type,
  String name,
  Set attrNames
) throws IdRepoException, SSOException

public void modifyMemberShip(
  SSOToken token,
  IdType type,
  String name,
  Set members,
  IdType membersType,
  int operation
) throws IdRepoException, SSOException

public void setActiveStatus(
  SSOToken token,
  IdType type,
  String name,
  boolean active
)
Authenticate

AM calls authenticate() with the credentials from the DataStore authentication module.

public boolean authenticate(Callback[] credentials)
  throws IdRepoException, AuthLoginException
Delete

The delete() method removes the subject from the identity repository. The name specifies the subject.

public void delete(SSOToken token, IdType type, String name)
  throws IdRepoException, SSOException
Service

The IdOperation.SERVICE operation is rarely used in recent AM deployments.

IdRepo plugin deployment

When you build your IdRepo plugin, include openam-core-7.5.1.jar in the classpath. This file is found under WEB-INF/lib/ where AM is deployed.

You can either package your plugin as a .jar file, and add it to WEB-INF/lib/, or add the classes under WEB-INF/classes/.

Register your plugin with AM (PluginTools API)

The steps in this procedure make use of a number of AM API interfaces and annotations. Click the following links to view the AM Public API JavaDoc:

Register your custom IdRepo plugin with the PluginTools interface as follows:

  1. Use the @IdRepoConfig annotation on your configuration interface, as shown below:

    package com.example.custom;
    
    import java.util.Optional;
    
    import org.forgerock.openam.annotations.sm.Attribute;
    import org.forgerock.openam.annotations.sm.IdRepoConfig;
    
    /**
     * Custom IdRepo config.
     */
    @IdRepoConfig(name = "MyIdRepo")
    public interface CustomIdRepoConfig {
    
        /**
         * The IdRepo implementation fully qualified class name.
         *
         * @return The implementation class name.
         */
        @Attribute(order = 10, requiredValue = true)
        default String idRepoClass() {
            return CustomIdRepo.class.getCanonicalName();
        }
    
        /**
         * Sets the connection pool minimum size.
         *
         * @return The connection pool minimum size.
         */
        @Attribute(order = 20)
        default Optional<Integer> connectionPoolMinSize() {
            return Optional.of(1);
        }
    
        /**
         * Sets the connection pool max size.
         *
         * @return The connection pool max size.
         */
        @Attribute(order = 30)
        default Optional<Integer> connectionPoolMaxSize() {
            return Optional.of(10);
        }
    }
  2. Create a .properties file based on the name you provided in the configuration interface; for example, MyIdRepo.properties.

    The contents of the file might resemble the following:

    CustomIdRepoConfig=Custom IdRepo
    idRepoClass=LDAPv3 Repository Plug-in Class Name
    connectionPoolMinSize=LDAP Connection Pool Minimum Size
    connectionPoolMaxSize=LDAP Connection Pool Maximum Size
  3. Create a class that implements AmPlugin, and uses the PluginTools interface to handle the following events:

    • onInstall()

      Call the pluginTools.installIdRepo function with your configuration class as the parameter.

    • onStartup()

      Call the pluginTools.startService function with your configuration class as the parameter.

    • upgrade()

      Call the pluginTools.upgradeIdRepo function with your configuration class as the parameter.

      A sample custom plugin class follows:

      package com.example.custom;
      
      import javax.inject.Inject;
      
      import org.forgerock.openam.plugins.AmPlugin;
      import org.forgerock.openam.plugins.PluginException;
      import org.forgerock.openam.plugins.PluginTools;
      import org.forgerock.openam.plugins.StartupType;
      
      /**
       * A custom identity repository plugin. This uses the plugin framework to install the custom identity repository.
       */
      public class CustomIdRepoPlugin implements AmPlugin {
      
          private static final String CURRENT_VERSION = "1.0.0";
          private PluginTools pluginTools;
      
          /**
           * The constructor.
           *
           * @param pluginTools The PluginTools instance.
           */
          @Inject
          public CustomIdRepoPlugin(PluginTools pluginTools) {
              this.pluginTools = pluginTools;
          }
      
          @Override
          public String getPluginVersion() {
              return CustomIdRepoPlugin.CURRENT_VERSION;
          }
      
          @Override
          public void onInstall() throws PluginException {
              pluginTools.installIdRepo(CustomIdRepoConfig.class);
          }
      
          @Override
          public void onStartup(StartupType startupType) throws PluginException {
              pluginTools.startService(CustomIdRepoConfig.class);
          }
      
          @Override
          public void upgrade(String fromVersion) throws PluginException {
              pluginTools.upgradeIdRepo(CustomIdRepoConfig.class);
          }
      }
  4. Create a file at the path META-INF/services/org.forgerock.openam.plugins.AmPlugin with the following contents:

    com.example.custom.CustomIdRepoPlugin

If you do not create this file, AM will not pick up the custom repository.

Register your plugin with AM (ssoadm)

To create a custom ID repo plugin for your identity stores and register it with the ssoadm command, follow these steps:

  1. Create a SubSchema for your plugin, and register it with AM:

    • Create the SubSchema document, for example customIdRepo.xml, using the following structure:

      <SubSchema i18nKey="x4000" inheritance="multiple" maintainPriority="no"
                 name="CustomRepo" supportsApplicableOrganization="no" validate="yes">
         <AttributeSchema cosQualifier="default" isSearchable="no"
                             name="RequiredValueValidator" syntax="string"
                             type="validator" >
           <DefaultValues>
              <Value>com.sun.identity.sm.RequiredValueValidator</Value>
           </DefaultValues>
         </AttributeSchema>
         <AttributeSchema any="required" cosQualifier="default"
                             i18nKey="x4001" isSearchable="no"
                             name="sunIdRepoClass" syntax="string"
                             type="single" validator="RequiredValueValidator" >
            <DefaultValues>
              <Value>org.test.CustomRepo</Value>
            </DefaultValues>
         </AttributeSchema>
         <AttributeSchema cosQualifier="default" i18nKey="x4002" isSearchable="no"
                             name="sunIdRepoAttributeMapping" syntax="string" type="list">
           <DefaultValues>
              <Value></Value>
           </DefaultValues>
        </AttributeSchema>
      </SubSchema>

      Ensure that you include the AttributeSchema required to configure your IdRepo plugin.

      Notice the i18nKey attributes on SubSchema elements. The i18nKey attribute values correspond to properties in the amIdRepoService.properties file under WEB-INF/classes/ where AM is deployed. The AM admin UI displays the label for the configuration user interface that it retrieves from the value of the i18nKey property in the amIdRepoService.properties file.

    • To make changes to the properties, first extract amIdRepoService.properties and, if necessary, the localized versions of this file from openam-core-7.5.1.jar to WEB-INF/classes/, where AM is deployed.

      For example, if AM is deployed under /path/to/tomcat/webapps/openam, then you could run the following commands:

      $ cd /path/to/tomcat/webapps/openam/WEB-INF/classes/
      $ jar -xvf ../lib/openam-core-7.5.1.jar amIdRepoService.properties
      inflated: amIdRepoService.properties
  2. Create a properties file for your plugin so that it is displayed in the AM admin UI:

    • To create a custom identity store named CustomRepo, where the attributes will be displayed under the Plug-in Configuration tab, create a file named CustomRepo.section.properties, with the following contents:

      ######################################################################################
      # Plug-in Configuration
      ######################################################################################
      # LDAPv3 Repository Plug-in Class Name
      pluginconfig=sunIdRepoClass
      # Attribute Name Mapping
      pluginconfig=sunIdRepoAttributeMapping

      Ensure you include any properties you added to the subschema that need to be displayed in the UI. AM includes a number of section.properties in the /path/to/tomcat/WEB-INF folder that you can use for templates.

    • To make your configuration properties visible in the UI, place the CustomRepo.section.properties into WEB-INF/classes/, where AM is deployed.

  3. Register your plugin using the ssoadm command after you have copied the files into place.

    $ ssoadm \
    add-sub-schema \
    --adminid uid=amAdmin,ou=People,dc=openam,dc=forgerock,dc=org \
    --password-file /tmp/pwd.txt \
    --servicename sunIdentityRepositoryService \
    --schematype Organization \
    --filename customIdRepo.xml

Use your new IdRepo plugin

  1. Restart AM or the container in which it runs.

  2. Configure a new ID repo in AM using your plugin:

    • In the AM admin UI, go to Realms > Realm Name > Identity Stores.

    • Select Add Identity Store, enter an ID, and select the type of identity store corresponding to your custom IdRepo plugin.

    • You can now add values to any custom properties you configured to be visible in the UI.

  3. Go to Realms > Realm Name > Identities, and create a new identity.

    If your plugin supports authentication, users are now able to authenticate using the DataStore module for the realm, by using a URL similar to the following:

    https://openam.example.com:8443/openam/XUI/?realm=/alpha&module=DataStore#login