26 Developing with the Identity Directory API

This chapter explains how to access and work with identity stores using the Identity Directory API.

This chapter contains these topics:

26.1 About the Identity Directory API

The Identity Directory API allows applications to access identity information (users and other entities) in a uniform and portable manner regardless of the particular underlying identity repository.

The Identity Directory API:

  • is flexible

  • is fully configurable by clients supporting a variety of identity stores having standard and specific schemas

  • supports retrieving and managing users, groups, and organizations

  • is extensible, supporting new entity types with relationships defined between those entities

  • is robust, with high-availability/fail-over support.

The Identity Directory API uses the Identity Governance framework, providing all the benefits of the framework to enable you to control how identity related information, including Personally Identifiable Information (PII), access entitlements, attributes, and other entities are used, stored, and propagated between organizations.

26.1.1 Feature Overview

This section explains the features supported by the Identity Directory API.

Features for User Entities

The following features are supported for users:

  • Perform Create/Update/Delete (CRUD) operations on users

  • Perform the following actions:

    • get and set user attributes

    • authenticate the user with the identity store's native authentication mechanism

    • get the group to which the user belongs (optionally, including nested groups)

    • make user a member of a group

  • Change user password

  • Force user password change

  • Get and set user state (enable/disable, lockout, password must change)

Features for Group Entities

The following features are supported for groups:

  • Perform CRUD operations on groups

  • Perform the following actions:

    • get and set attributes

    • get and search for members of a group

    • get the groups to which a groups belongs (optionally, including nested groups)

    • determine if the group is a member of another group

  • Support multi-valued attributes

  • Support static and dynamic groups

26.2 Summary of Classes

Table 26-1 lists the classes in the Identity Directory API:

Table 26-1 Classes in the Identity Directory API

Class Description

Capabilities

Contains an entity's capabilities.

CreateOptions

Contains options for entity creation operations.

DeleteOptions

Contains options for entity deletion operations.

Entity

Generic entity class holding the list of attributes of the entity fetched using search or read methods.

EntityAlreadyExistsException

Returned following an attempt to create an existing entity.

EntityCapabilities

 

EntityManager

Handles operations like read, create and search of generic entity.

EntityNotFoundException

Returned when requested entity is not found.

EntityNotUniqueException

Returned when the entity is not uniquely defined.

EntityRelationManager

Handles entity relationship operations like read, create, delete, search relationship.

Group

A generic entity class holding the list of members of the group. It also provides methods to modify group membership.

GroupManager

Handles operations like creating, deleting, and searching for groups.

IDSException

Handles exceptions.

IDSPrincipal

Contains the principal related to the exception.

IdentityDirectory

Represents a handle to IdentityDirectory for creation of IdentityDirectory instance.

The instance provides handles to User, Group, and generic Entity Manager so that operations on the corresponding entities can be performed.

IdentityDirectoryFactory

A factory class for creating IdentityDirectoryService.

IdentityDirectoryInfo

 

InvalidAttributesException

Used for exceptions related to invalid entity attributes.

InvalidFilterException

Used for exceptions generated within Identity Beans

ModAttribute

 

ModifyOptions

Extends OperationOptions containing options for entity modify operation

OperationNotSupportedException

Used for exceptions generated within Identity Beans

ReadOptions

Extends OperationOptions containing options for entity read operation. Read options include Locale and Requested Attributes settings.

ResultSet

An interface for the object returned by search interaction with paged results.

SearchFilter

Used to construct simple or complex nested search filters for searching the entities

SearchOptions

Extends ReadOptions containing options for entity search operation.

User

Generic class for User entities.

UserCapabilities

Contains user capability attributes.

UserManager

Contains methods for creating, deleting, and searching for users by various criteria.


26.3 Identity Directory Configuration

The identity directory configuration is a combination of the logical entity configuration and the physical identity store configuration.

The identity directory with logical entity configuration is stored in:

DOMAIN_HOME/config/fmwconfig/ids-config.xml

The physical identity store configuration for the default identity directory is located at:

DOMAIN_HOME/config/fmwconfig/ovd/default

The default identity directory uses the same identity store properties (namely host, port, credentials, search base, create base, name attribute, and so on) configured in OPSS (weblogic authenticator or in jps-config.xml). For more information, see Section F.2.3, "LDAP Identity Store Properties".

26.4 Working with the Identity Directory API

This section explains how applications can use the Identity Directory API to view and manage identity store data. It contains these sections:

26.4.1 Getting an Identity Directory API Instance

You can obtain the identity directory handle from the jps-context and get a directory instance as follows:

JpsContextFactory ctxFactory = JpsContextFactory.getContextFactory();
JpsContext ctx = ctxFactory.getContext();
       
//find the JPS IdentityStore service instance
IdentityStoreService idstoreService =   ctx.getServiceInstance(IdentityStoreService.class)
 
//get the Identity Directory instance
oracle.igf.ids.IdentityDirectory ids = idstoreService.getIdentityStore();

26.4.2 Performing CRUD Operations on Users and Groups

You can perform Create, Retrieve, Update, and Delete (CRUD) operations on users and groups.

26.4.2.1 User Operations

Basic CRUD operations on users are as follows:

Create User

Principal UserManager.createUser(List<Attribute> attrVals, CreateOptions opts)

Get User

User UserManager.getUser(Principal principal, ReadOptions opts)

Search for User

User UserManager.searchUser(String id, ReadOptions opts)

Delete User

void UserManager.deleteUser(String id, DeleteOtions opts)

Update User

void UserManager.modify(List<ModAttribute> attrVals, ModifyOptions opts)

Retrieve List of Users

ResultSet UserManager.searchUsers(SearchFilter filter, SearchOptions opts)

26.4.2.2 Group Operations

Basic CRUD operations on groups are as follows:

Create Group

Principal GroupManager.createGroup(List<Attribute> attrVals, CreateOptions opts)

Get Group

User GroupManager.getGroup(Principal principal, ReadOptions opts)

Search for Group

User GroupManager.searchGroup(String id, ReadOptions opts)

Delete Group

void GroupManager.deleteGroup(String id, DeleteOtions opts)

Modify Group Attributes

void GroupManager.modify(List<ModAttribute> attrVals, ModifyOptions opts)

Retrieve List of Groups

ResultSet GroupManager.searchGroups(SearchFilter filter, SearchOptions opts)

26.5 Examples of Identity Directory API

This section contains the following examples of using the Identity Directory API:

26.5.1 Initialize and Obtain Identity Directory Handle

This sample code initializes and obtains a handle to the identity directory:

/**
 * This is a sample program for initializing Identity Directory Service with the configuration
 * that is already persisted in IDS config location.
 * Basic User and Group CRUDS are performed using this IDS instance
 */
 
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.Map;
 
import java.security.Principal;
 
import oracle.igf.ids.Entity;
import oracle.igf.ids.User;
import oracle.igf.ids.UserManager;
import oracle.igf.ids.Group;
import oracle.igf.ids.GroupManager;
import oracle.igf.ids.config.OperationalConfig;
import oracle.igf.ids.IdentityDirectoryFactory;
import oracle.igf.ids.IdentityDirectoryInfo;
import oracle.igf.ids.IdentityDirectory;
import oracle.igf.ids.IDSException;
import oracle.igf.ids.ReadOptions;
import oracle.igf.ids.CreateOptions;
import oracle.igf.ids.ModifyOptions;
import oracle.igf.ids.DeleteOptions;
import oracle.igf.ids.SearchOptions;
import oracle.igf.ids.SearchFilter;
import oracle.igf.ids.ResultSet;
import oracle.igf.ids.Attribute;
import oracle.igf.ids.ModAttribute;
 
import oracle.dms.context.ExecutionContext;
 
 
public class Ids1Test {
 
    private IdentityDirectory ids;
    private UserManager uMgr;
    private GroupManager gMgr;
 
 
    /**
     * Get Identity Store Service
     */
    public Ids1Test() throws IDSException {
 
        // Set Operational Config
        OperationalConfig opConfig = new OperationalConfig();
 
        // Set the application credentials: this overrides the credentials 
        // set in physical ID store configuration
        //opConfig.setApplicationUser("cn=venkat_medam,l=amer,dc=oracle,dc=com");
        //opConfig.setApplicationPassword("welcome123".toCharArray());
 
        // Set search/crate base, name, objclass, etc. config.  
        // This overrides default operational configuration in IDS
        opConfig.setEntityProperty("User", opConfig.SEARCH_BASE,          "l=amer,dc=oracle,dc=com");
        opConfig.setEntityProperty("User", opConfig.CREATE_BASE,          "l=amer,dc=oracle,dc=com");
        opConfig.setEntityProperty("User", opConfig.FILTER_OBJCLASSES, "person");
        opConfig.setEntityProperty("User", opConfig.CREATE_OBJCLASSES,          "inetorgperson");
        opConfig.setEntityProperty("Group", opConfig.SEARCH_BASE,          "cn=dlcontainerOCS,dc=oracle,dc=com");
        opConfig.setEntityProperty("Group", opConfig.CREATE_BASE,          "cn=dlcontainerOCS,dc=oracle,dc=com");
        opConfig.setEntityProperty("Group", opConfig.FILTER_OBJCLASSES,          "groupofuniquenames");
        opConfig.setEntityProperty("Group", opConfig.CREATE_OBJCLASSES,          "groupofuniquenames,orclgroup");
 
        // Get IdentityDirectoryService "userrole" configured in IDS config
        IdentityDirectoryFactory factory = new IdentityDirectoryFactory();
        //ids = factory.getDefaultIdentityDirectory(opConfig);
        ids = factory.getIdentityDirectory("userrole", opConfig);
 
        // Get UserManager and GroupManager handles
        uMgr = ids.getUserManager();
        gMgr = ids.getGroupManager();
    }
 

26.5.2 Create a User

This sample code creates a user in the identity store:

 public Principal createUser() {
        Principal principal = null;
        
        List<Attribute> attrs = new ArrayList<Attribute>();
        attrs.add(new Attribute("commonname", "test1_user1"));
        attrs.add(new Attribute("password", "welcome123".toCharArray()));
        attrs.add(new Attribute("firstname", "test1"));
        attrs.add(new Attribute("lastname", "user1"));
        attrs.add(new Attribute("mail", "test1.user1@oracle.com"));
        attrs.add(new Attribute("telephone", "1 650 123 0001"));
        attrs.add(new Attribute("title", "Senior Director"));
        attrs.add(new Attribute("uid", "tuser1"));
        // Adding locale specific value
        attrs.add(new Attribute("description", "created test user 1", 
         new java.util.Locale("us", "en")));
        try {
            CreateOptions createOpts = new CreateOptions();
            createOpts.setCreateBase("l=apac,dc=oracle,dc=com");
 
            principal = uMgr.createUser(attrs, createOpts);
 
            System.out.println("Created user " + principal.getName());
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
 
        return principal;
    }

26.5.3 Get a User

This sample code obtains a user from the identity store:

 public User getUser(Principal principal) {
        User user = null;
 
        try {
            ReadOptions readOpts = new ReadOptions();
            // Getting specific locale values
            readOpts.setLocale("us-en");
 
            user = uMgr.getUser(principal, readOpts);
            
            printEntity(user);
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
 
        return user;
    }

26.5.4 Modify a User

This sample code modifies an existing user by adding a new user attribute:

 public void modifyUser(User user) {
 
        try {
            ModifyOptions modifyOpts = new ModifyOptions();
 
            List<ModAttribute> attrs = new ArrayList<ModAttribute>();
            attrs.add(new ModAttribute("description", "modified test user 1"));
            //attrs.add(new ModAttribute("uid", "venkatmedam"));
 
            user.modify(attrs, modifyOpts);
            
            System.out.println("Modified user " + user.getName());
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

26.5.5 Simple Search for a User

This sample code performs a basic user search:

 try {
            ReadOptions readOpts = new ReadOptions();
            readOpts.setSearchBase("l=apac");
 
            User user = uMgr.searchUser("tuser1", readOpts);
            
            printEntity(user);
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

26.5.6 Complex Search for Users

This sample code uses a complex search filter to return matching users:

public void searchUsers() {
 
   try {
      // Complex search filter with nested AND and OR conditiions
      SearchFilter filter = new SearchFilter(
         SearchFilter.LogicalOp.OR,
         new SearchFilter(SearchFilter.LogicalOp.AND,
         new SearchFilter("firstname", SearchFilter.Operator.BEGINS_WITH, "ve"),
         new SearchFilter("telephone", SearchFilter.Operator.CONTAINS, "506")),
         new SearchFilter(SearchFilter.LogicalOp.AND,
         new SearchFilter("firstname", SearchFilter.Operator.BEGINS_WITH, "ra"),
         new SearchFilter(SearchFilter.LogicalOp.OR,
         new SearchFilter("orgunit", SearchFilter.Operator.BEGINS_WITH, "ldap"),
         new SearchFilter("orgunit", SearchFilter.Operator.BEGINS_WITH, "sun"),
         new SearchFilter("orgunit", SearchFilter.Operator.BEGINS_WITH,           "access")),
         new SearchFilter("telephone", SearchFilter.Operator.CONTAINS, "506")));
 
      // Requesting attributes
      List<String> reqAttrs = new ArrayList<String>();
      reqAttrs.add("jpegphoto");
 
      SearchOptions searchOpts = new SearchOptions();
      searchOpts.setPageSize(3);
      searchOpts.setRequestedPage(1);
      searchOpts.setRequestedAttrs(reqAttrs);
      searchOpts.setSearchBase("l=amer");
 
      ResultSet<User> sr = uMgr.searchUsers(filter, searchOpts);
         while (sr.hasMore()) {
            User user = sr.getNext();
            //printEntity(user);
            //System.out.println(" ");
            System.out.println(user.getSubjectName());
            System.out.println("    " + user.getAttributeValue("commonname"));
         }
 
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }
    }

26.5.7 Create a Group

This sample code creates a group:

 public Principal createGroup() {
        Principal principal = null;
        
        List<Attribute> attrs = new ArrayList<Attribute>();
        attrs.add(new Attribute("name", "test1_group1"));
        attrs.add(new Attribute("description", "created test group 1"));
        attrs.add(new Attribute("displayname", "test1 group1"));
        try {
            CreateOptions createOpts = new CreateOptions();
 
            principal = gMgr.createGroup(attrs, createOpts);
 
            System.out.println("Created group " + principal.getName());
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
 
        return principal;
    }

26.5.8 Get a Group

This sample code returns a specific group:

 public Group getGroup(Principal principal) {
        Group group = null;
 
        try {
            ReadOptions readOpts = new ReadOptions();
 
            group = gMgr.getGroup(principal, readOpts);
            
            printEntity(group);
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
 
        return group;
    }

26.5.9 Get Group Using a Search Filter

This sample code uses a search filter to return groups:

 public void searchGroups() {
 
        try {
            SearchFilter filter = new SearchFilter("name",
                                SearchFilter.Operator.BEGINS_WITH, "test");
 
            SearchOptions searchOpts = new SearchOptions();
            searchOpts.setPageSize(10);
 
            ResultSet<Group> sr = gMgr.searchGroups(filter, searchOpts);
            while (sr.hasMore()) {
                Group group = sr.getNext();
                System.out.println(group.getSubjectName());
            }
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

26.5.10 Delete a Group

This sample code deletes a group from the store:

 public void deleteGroup(Principal principal) {
 
        try {
            DeleteOptions deleteOpts = new DeleteOptions();
 
            gMgr.deleteGroup(principal, deleteOpts);
            
            System.out.println("Deleted group " + principal.getName());
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

26.5.11 Add a Member to a Group

This sample code adds a member to a group:

 public void addMember() {
        try {
            ReadOptions readOpts = new ReadOptions();
            User user = uMgr.searchUser("amsharma", readOpts);
            Group group = gMgr.searchGroup("test1_group1", readOpts);
 
            ModifyOptions modOpts = new ModifyOptions();
            user.addMemberOf(group, modOpts);
 
            System.out.println("added amsharma as member of test1_group1");
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

26.5.12 Delete a Member from a Group

This sample code deletes a member from a group:

 public void deleteMember() {
        try {
            ReadOptions readOpts = new ReadOptions();
            User user = uMgr.searchUser("amsharma", readOpts);
            Group group = gMgr.searchGroup("test1_group1", readOpts);
 
            ModifyOptions modOpts = new ModifyOptions();
            group.deleteMember(user, modOpts);
 
            System.out.println("deleted amsharma from the group test1_group1");
 
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

26.6 SSL Configuration

For details about SSL configuration when using the Identity Directory API, see Section 7.5, "SSL for the Identity Store Service".