The following topics describe the architecture and key functionality of the Identity Governance Framework, Identity Directory API, and Identity Directory Service.
The Identity Directory API provides a service for identity management applications to access and manage identity information. The API is flexible and can be fully configured by clients supporting heterogeneous identity stores having standard and specific schemas, and is robust with both high-availability and failover support.
The API uses the Identity Governance Framework and provides all the benefits of Identity Governance for identity information regulation and control. The API can be used in both Java EE and Java SE modes. For more information about the Identity Governance Framework, see Introduction to Identity Governance Framework.
The API supports the following actions:
Create/Read/Update/Delete (CRUD) operations on User, Group, Org, and generic entities
Get operation on User Account State
Identity Directory API configuration sharing
Support for directory servers such as Oracle Internet Directory, Oracle Unified Directory, Oracle Directory Server EE, and Active Directory.
Identity Directory Service consists of the following:
Identity Directory API
The Identity Directory API provide methods for accessing and managing identity information in a directory server that is the domain identity store. Entity definitions, entity relationships, and the physical identity store details can be configured using either the Identity Directory Configuration APIs or Mbeans. Directory service instance capabilities can be queried using getter methods.
Identity Directory API Configuration
Identity Directory API configuration comprises logical entity configuration and physical identity store configuration.
This section contains the following topics:
The Identity Directory API is used to initialize the Identity Directory Service.
The Identity Directory Service is a common service used by identity management products to access and manage an Identity Directory. The Identity Directory Service provides an interface to both access and modify users and group information from different identity stores. An Identity Directory is an instance of the Identity Directory Service having:
a unique name (IDS name)
a logical entity configuration
a physical identity store configuration
For more information about the Identity Directory Service, also referred to as the identity store service, see Oracle® Fusion Middleware Securing Applications with Oracle Platform Security Services.
To use the Identity Directory Service APIs, it is essential to understand how identities are integrated, and how they can be used.
Figure 2-1 shows the logical architecture of the .
Figure 2-1 Identity Directory API Architecture
Figure 2-2 shows the relationship between the components.
Figure 2-2 Identity Directory API Components
The Identify Directory API provides an interface to access and modify users and group information from different identity stores.
The Identity Directory Service configuration is a combination of the logical entity configuration, the physical identity store configuration, and operational configuration.
The logical entity configuration and operational configuration is stored in ids-config.xml. This file is located in the same directory as jps-config.xml. For example, in a Java EE environment the location is:
DOMAIN_HOME/config/fmwconfig/ids-config.xml
The physical identity store configuration is stored in ovd/ids/adapters.os.xml. For example, in a Java EE environment the ovd directory is located in:
DOMAIN_HOME/config/fmwconfig
This section contains the following topics:
The Identity Directory Service configuration is a combination of logical entity configuration, the physical identity store configuration, and operational configuration.
The following topics describe the logical entity configuration information for an Identity Directory Service:
You must keep in mind the properties of a logical entity configuration.
Name | Description |
---|---|
|
Name that uniquely identifies the Identity Directory Service. |
|
Detailed description of the Identity Directory Service. |
|
Valid values are |
|
Optional property to specify the specific application for which the Identity Directory Service is being configured. |
The following table describes the logical entity attributes:
Name | Description |
---|---|
|
Logical attribute name. |
|
Valid data type values are as follows: |
|
Detailed description of the logical attribute. |
|
Default is |
|
Default is |
Note:
Beginning with the 12c (12.1.3) release, the Identity Directory API supports entity attribute pass-through. With pass-through support, you do not need to include each and every attribute in attribute definitions (described in table in Attributes of a Logical Entity Configuration) and in attribute references under the entity definition (described in table in Properties of a Logical Entity Definition).
The IDS API allows any attribute in an add, modify, requested attributes, or search filter operation. The entity definition can hold a minimal set of attributes either to define entity relationships using logical attribute names that are different from the back-end identity store or for the default fetch of attributes.
If an input attribute is not in the identity store schema, the IDS API returns the error thrown by the identity store.
You must keep in mind the properties required in each logical entity definition.
Name | Description |
---|---|
|
Name of the entity. |
|
Valid entity values are as follows: |
|
Logical attribute that uniquely identifies the entity. |
|
Use |
|
Use |
|
Use |
|
Use |
|
List of entity attribute references that contain the following details:
|
You must keep in mind the properties required in each logical entity relationship definition.
Name | Description |
---|---|
|
Name of the entity relationship. |
|
Valid entity values are as follows: |
|
Name of the first entity in the Entity Relationship. |
|
The first entity's attribute. Value of this attribute relates to the second entity in the relationship. |
|
Name of the second entity in the Entity Relationship. |
|
The second entity's attribute. Value of the |
|
Use |
You must keep in mind the physical identity store configuration for an Identity Directory Service.
The following table describes the physical identity store configuration properties:
Name | Description |
---|---|
|
Host and Port information of the Identity Store. Alternate Host and Port details also can be setup for failover. |
|
Type of directory. Valid values are: |
|
Credentials to connect to the directory. |
You must explore the operational configuration for an Identity Directory Service.
The operational configuration contains mainly base
, name attribute
, and objectclass
configuration for each of the entities.
The following table describes the operational configuration entities:
Name | Description |
---|---|
|
Container under which the entity should be searched. |
|
Container where the new entity will be created. |
|
RDN attribute of the entity. |
|
The |
|
The |
You must keep in mind the recommendations while designing a new Identity Directory API.
The following topics describe the recommendations:
You must keep the number of entity attributes to minimal while configuring a new Identity Directory.
The entity attribute is defined by defaultFetch
value. Also, try to have large attributes like jpegphoto
configured with a defaultFetch
value of false. The reason is every time the entity is read from the backend, all the defaultFetch
attributes from backend directory will be retrieved. Too many defaultFetch
attributes will affect the performance.
You must initialize the Identity Directory once.
Initialization of Identity Directory has some overhead to initialize the entire ArisId stack. As a result, applications should initialize the Identity Directory once, preferably on application startup, and use only one handle throughout.
Use the sample codes for performing various operations associated with the Identity Directory API.
The following topics describe operations associated with the Identity Directory API:
Use the code sample to initialize and obtain a handle to the identity directory.
import oracle.igf.ids.UserManager; import oracle.igf.ids.GroupManager; import oracle.igf.ids.config.OperationalConfig; import oracle.igf.ids.IdentityDirectoryFactory; import oracle.igf.ids.IdentityDirectory; import oracle.igf.ids.IDSException; public class IdsSample { private IdentityDirectory ids; private UserManager uMgr; private GroupManager gMgr; public IdsSample() throws IDSException { // Set Operational Config OperationalConfig opConfig = new OperationalConfig(); // Set the application credentials (optional). This overrides the credentials set in // physical ID store configuration opConfig.setApplicationUser("cn=user1,dc=us,dc=example,dc=com"); opConfig.setApplicationPassword("password".toCharArray()); // Set search/crate base, name, objclass, etc. config (optional). This overrides default operational configuration in IDS opConfig.setEntityProperty("User", opConfig.SEARCH_BASE, "dc=us,dc=example,dc=com"); opConfig.setEntityProperty("User", opConfig.CREATE_BASE, "dc=us,dc=example,dc=com"); opConfig.setEntityProperty("User", opConfig.FILTER _OBJCLASSES, "person"); opConfig.setEntityProperty("User", opConfig.CREATE _OBJCLASSES, "inetorgperson"); opConfig.setEntityProperty("Group", opConfig.SEARCH _BASE, "cn=groups,dc=us,dc=example,dc=com"); opConfig.setEntityProperty("Group", opConfig.CREATE _BASE, "cn=groups,dc=us,dc=example,dc=com"); opConfig.setEntityProperty("Group", opConfig.FILTER _OBJCLASSES, "groupofuniquenames"); opConfig.setEntityProperty("Group", opConfig.CREATE _OBJCLASSES, "groupofuniquenames"); // Get IdentityDirectory "ids1" configured in IDS config IdentityDirectoryFactory factory = new IdentityDirectoryFactory(); ids = factory.getIdentityDirectory("ids1", opConfig); // Get UserManager and GroupManager handles uMgr = ids.getUserManager(); gMgr = ids.getGroupManager(); } }
Note:
If you plan to use Tivoli as the authentication provider, then you need to select OPEN_LDAP
as the authentication provider type. This is because Oracle WebLogic Server does not support Tivoli.
When Identity Governance Framework or Identity Directory Service is initialized to obtain the directory handle for Tivoli, then the generated adapters.os_xml file contains the following parameter:
<param name="mapAttribute" value="orclGUID=entryUUID"/>
In this scenario, for Tivoli, you need to map orclGUID
attribute to ibm-entryUUID
as follows:
<param name="mapAttribute" value="orclGUID=ibm-entryUUID"/>
You need to update the adapters.os_xml file manually to reflect these changes. In addition, you must restart the Oracle WebLogic Server for any attribute mapping update to work.
Use the code sample to initialize and obtain the identity directory handle from JPS context.
import oracle.igf.ids.UserManager; import oracle.igf.ids.GroupManager; import oracle.igf.ids.config.OperationalConfig; import oracle.igf.ids.IdentityDirectoryFactory; import oracle.igf.ids.IdentityDirectory; import oracle.igf.ids.IDSException; import oracle.security.jps.JpsContext; import oracle.security.jps.JpsContextFactory; import oracle.security.jps.service.idstore.IdentityStoreService; public class IdsSample { private IdentityDirectory ids; private UserManager uMgr; private GroupManager gMgr; public IdsSample() throws IDSException { // Get IdentityDirectory from JpsContext try { JpsContext context = JpsContextFactory.getContextFactory().getContext(); IdentityStoreService idstore = (IdentityStoreService) context.getServiceInstance(IdentityStoreService.class); ids = idstore.getIdentityStore(); } catch (Exception e) { throw new IDSException(e); } // Get UserManager and GroupManager handles uMgr = ids.getUserManager(); gMgr = ids.getGroupManager(); } }
Use the code sample to initialize and obtain the in-memory identity directory handle.
import java.util.ArrayList; import java.util.List; import oracle.igf.ids.UserManager; import oracle.igf.ids.GroupManager; import oracle.igf.ids.config.AttributeDef; import oracle.igf.ids.config.AttributeRef; import oracle.igf.ids.config.EntityDef; import oracle.igf.ids.config.EntitiesConfig; import oracle.igf.ids.config.EntityRelationship; import oracle.igf.ids.config.IdentityStoreConfig; import oracle.igf.ids.config.OperationalConfig; import oracle.igf.ids.IdentityDirectoryFactory; import oracle.igf.ids.IdentityDirectory; import oracle.igf.ids.IDSException; public class IdsSample { private IdentityDirectory ids; private UserManager uMgr; private GroupManager gMgr; public IdsSample() throws IDSException { // Add Attribute definitions List<AttributeDef> attrDefs = new ArrayList<AttributeDef>(); attrDefs.add(new AttributeDef("cn", AttributeDef.DataType.STRING)); attrDefs.add(new AttributeDef("firstname", AttributeDef.DataType.STRING)); attrDefs.add(new AttributeDef("sn", AttributeDef.DataType.STRING)); attrDefs.add(new AttributeDef("telephonenumber", AttributeDef.DataType.STRING)); attrDefs.add(new AttributeDef("uid", AttributeDef.DataType.STRING)); attrDefs.add(new AttributeDef("uniquemember", AttributeDef.DataType.STRING)); // Add User entity definition List<EntityDef> entityDefs = new ArrayList<EntityDef>(); EntityDef userEntityDef = new EntityDef("User", EntityDef.EntityType.USER, "cn"); userEntityDef.addAttribute(new AttributeRef("cn")); userEntityDef.addAttribute(new AttributeRef("firstname")); userEntityDef.addAttribute(new AttributeRef("sn")); userEntityDef.addAttribute(new AttributeRef("telephonenumber")); userEntityDef.addAttribute(new AttributeRef("uid")); entityDefs.add(userEntityDef); // Add Group entity definition EntityDef groupEntityDef = new EntityDef("Group", EntityDef.EntityType.GROUP, "cn"); groupEntityDef.addAttribute(new AttributeRef("cn")); groupEntityDef.addAttribute(new AttributeRef("uniquemember", false, AttributeRef.FilterType.EQUALS)); entityDefs.add(groupEntityDef); // Add Entity relationship definition List<EntityRelationship> entityRelations = new ArrayList<EntityRelationship>(); entityRelations.add(new EntityRelationship("user_memberOfGroup", EntityRelationship.RelationshipType.MANYTOMANY, "User", "principal", "Group", "uniquemember")); entityRelations.add(new EntityRelationship("group_memberOfGroup", EntityRelationship.RelationshipType.MANYTOMANY, "Group", "principal", "Group", "uniquemember", true)); EntitiesConfig entityCfg = new EntitiesConfig(attrDefs, entityDefs, entityRelations); // Create physical Identity Store configuration IdentityStoreConfig idStoreCfg = new IdentityStoreConfig( "ldap://host1:389,ldap://host2:389", "cn=orcladmin", "password".toCharArray(), IdentityStoreConfig.IdentityStoreType.OID); idStoreCfg.setHighAvailabilityOption(IdentityStoreConfig.HAOption.FAILOVER); idStoreCfg.setProperty(IdentityStoreConfig.HEARTBEAT_INTERVAL, "60"); idStoreCfg.setProperty(IdentityStoreConfig.CONN_TIMEOUT, "30000"); // milli sec idStoreCfg.setProperty(IdentityStoreConfig.MIN_POOLSIZE, "5"); idStoreCfg.setProperty(IdentityStoreConfig.MAX_POOLSIZE, "10"); idStoreCfg.setProperty(IdentityStoreConfig.MAX_POOLWAIT, "1000"); // milli sec idStoreCfg.setProperty(IdentityStoreConfig.MAX_POOLCHECKS, "10"); idStoreCfg.setProperty(IdentityStoreConfig.FOLLOW_REFERRAL, "false"); idStoreCfg.setAttrMapping("firstname", "givenname"); // Set operational config OperationalConfig opConfig = new OperationalConfig(); opConfig.setEntityProperty(opConfig.USER_ENTITY, opConfig.SEARCH_BASE, "cn=users,dc=us,dc=example,dc=com"); opConfig.setEntityProperty(opConfig.USER_ENTITY, opConfig.CREATE_BASE, "cn=users,dc=us,dc=example,dc=com"); opConfig.setEntityProperty(opConfig.USER_ENTITY, opConfig.NAME_ATTR, "cn"); opConfig.setEntityProperty(opConfig.USER_ENTITY, opConfig.FILTER _OBJCLASSES, "inetorgperson"); opConfig.setEntityProperty(opConfig.USER_ENTITY, opConfig.CREATE _OBJCLASSES, "inetorgperson"); opConfig.setEntityProperty(opConfig.GROUP_ENTITY, opConfig.SEARCH_BASE, "cn=groups,dc=us,dc=example,dc=com"); opConfig.setEntityProperty(opConfig.GROUP_ENTITY, opConfig.CREATE_BASE, "cn=groups,dc=us,dc=example,dc=com"); opConfig.setEntityProperty(opConfig.GROUP_ENTITY, opConfig.NAME_ATTR, "cn"); opConfig.setEntityProperty(opConfig.GROUP_ENTITY, opConfig.FILTER _OBJCLASSES, "groupofuniquenames"); opConfig.setEntityProperty(opConfig.GROUP_ENTITY, opConfig.CREATE _OBJCLASSES, "groupofuniquenames"); // Initialize Identity Store Service IdentityDirectoryFactory factory = new IdentityDirectoryFactory(); ids = factory.getIdentityDirectory("ids1", entityCfg, idStoreCfg, opConfig); // Get UserManager and GroupManager handles uMgr = ids.getUserManager(); gMgr = ids.getGroupManager(); } }
You can add a user to the identity store.
The following code sample adds a user to the identity store:
Principal principal = null; List<Attribute> attrs = new ArrayList<Attribute>(); attrs.add(new Attribute("commonname", "test1_user1")); attrs.add(new Attribute("password", "mypassword".toCharArray())); attrs.add(new Attribute("firstname", "test1")); attrs.add(new Attribute("lastname", "user1")); attrs.add(new Attribute("mail", "test1.user1@example.com")); attrs.add(new Attribute("telephone", "1 650 123 0001")); attrs.add(new Attribute("title", "Senior Director")); attrs.add(new Attribute("uid", "tuser1")); try { CreateOptions createOpts = new CreateOptions(); principal = uMgr.createUser(attrs, createOpts); System.out.println("Created user " + principal.getName()); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the sample code to obtain a user for a given principal.
User user = null; try { ReadOptions readOpts = new ReadOptions(); user = uMgr.getUser(principal, readOpts); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the code sample to modify a user in the identity directory.
try { ModifyOptions modifyOpts = new ModifyOptions(); List<ModAttribute> attrs = new ArrayList<ModAttribute>(); attrs.add(new ModAttribute("description", "modified test user 1")); user.modify(attrs, modifyOpts); System.out.println("Modified user " + user.getName()); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the sample code to obtain a user matching the given identity value.
try { ReadOptions readOpts = new ReadOptions(); User user = uMgr.searchUser("tuser1", readOpts); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the code sample to search users using a complex search filter.
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, "test"), new SearchFilter("telephone", SearchFilter.Operator.CONTAINS, "650")), new SearchFilter(SearchFilter.LogicalOp.AND, new SearchFilter("firstname", SearchFilter.Operator.BEGINS_WITH, "demo"), new SearchFilter(SearchFilter.LogicalOp.OR, new SearchFilter("orgunit", SearchFilter.Operator.BEGINS_WITH, "hr"), new SearchFilter("orgunit", SearchFilter.Operator.BEGINS_WITH, "it"), new SearchFilter("telephone", SearchFilter.Operator.CONTAINS, "650"))); // Requesting attributes List<String> reqAttrs = new ArrayList<String>(); reqAttrs.add("jpegphoto"); SearchOptions searchOpts = new SearchOptions(); searchOpts.setPageSize(100); searchOpts.setRequestedAttrs(reqAttrs); searchOpts.setSortAttrs(new String[] {"firstname"}); ResultSet<User> sr = uMgr.searchUsers(filter, searchOpts); while (sr.hasMore()) { User user = sr.getNext(); System.out.println(user.getSubjectName()); } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
The following code sample shows how to change a user password:
ModifyOptions modOpts = new ModifyOptions(); try { user.changePassword("welcome123".toCharArray(), "welcome1".toCharArray(), modOpts); System.out.println("Changed user password"); } catch (Exception e) { System.out.println("Failed to change user password"); e.printStackTrace(); }
Use the sample code to reset a user password.
ModifyOptions modOpts = new ModifyOptions(); try { user.resetPassword("welcome123".toCharArray(), modOpts); System.out.println("Reset user password"); } catch (Exception e) { System.out.println("Failed to reset user password"); e.printStackTrace(); }
You can authenticate a user using APIs.
The following code sample shows how to authenticate a user:
ReadOptions readOpts = new ReadOptions(); try { User user = uMgr.authenticateUser("tuser1", "mypassword".toCharArray(), readOpts); System.out.println("authentication success"); } catch (Exception e) { System.out.println("Authentication failed. " + e.getMessage()); e.printStackTrace(); }
Use the code sample to delete a user.
try { DeleteOptions deleteOpts = new DeleteOptions(); uMgr.deleteUser(principal, deleteOpts); System.out.println("Deleted user " + principal.getName()); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the sample code to create a group.
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(); }
Use the code sample to search 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(); }
Use the code sample to show how to get a management chain.
try { ReadOptions readOpts = new ReadOptions(); User user = uMgr.searchUser("tuser1", readOpts); SearchOptions searchOpts = new SearchOptions(); searchOpts.setPageSize(10); int nLevels = 0; ResultSet<User> sr = user.getManagementChain(nLevels, searchOpts); while (sr.hasMore()) { User u = sr.getNext(); System.out.println(u.getSubjectName()); } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the code sample to show how to get the reportees of user.
// Get Reportees with target search filter public void getReportees() { try { ReadOptions readOpts = new ReadOptions(); User user = uMgr.searchUser("tuser1", readOpts); SearchOptions searchOpts = new SearchOptions(); searchOpts.setPageSize(20); int nLevels = 0; // get all the direct/indirect reporting of tuser1 who are "developers" SearchFilter filter = new SearchFilter("title", SearchFilter.Operator.CONTAINS, "developer"); ResultSet<User> sr = user.getReportees(nLevels, filter, searchOpts); while (sr.hasMore()) { User u = sr.getNext(); System.out.println(u.getSubjectName()); } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
You can add a member to a group.
The following code sample adds a member to a group:
try { ReadOptions readOpts = new ReadOptions(); User user = uMgr.searchUser("tuser1", readOpts); Group group = gMgr.searchGroup("test1_group1", readOpts); ModifyOptions modOpts = new ModifyOptions(); user.addMemberOf(group, modOpts); System.out.println("added tuser1 as a member of test1_group1"); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the code sample to delete a member from a group.
try { ReadOptions readOpts = new ReadOptions(); User user = uMgr.searchUser("tuser1", readOpts); Group group = gMgr.searchGroup("test1_group1", readOpts); ModifyOptions modOpts = new ModifyOptions(); group.deleteMember(user, modOpts); System.out.println("deleted tuser1 from the group test1_group1"); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Note:
Identity Governance Framework/Identity Directory Service group membership search evaluates both static and dynamic groups. However, membership updates (addition/deletion) are not supported for dynamic groups. For instance, if you wish to delete a member from a group and the member is a dynamic member of that group, then the delete operation is not supported for the dynamic group.
Use the code sample to get all the groups in which user is a member.
try { ReadOptions readOpts = new ReadOptions(); User user = uMgr.searchUser("tuser1", readOpts); SearchOptions searchOpts = new SearchOptions(); searchOpts.setPageSize(10); int nLevels = 0; ResultSet<Group> sr = user.getMemberOfGroups(nLevels, null, searchOpts); while (sr.hasMore()) { Group group = sr.getNext(); System.out.println(group.getSubjectName()); } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
Use the code sample that describes how to use the NOT operator in a search filter.
try { SearchFilter f1 = new SearchFilter("firstname", SearchFilter.Operator.BEGINS_WITH, "demo"); SearchFilter f2 = new SearchFilter("orgunit", SearchFilter.Operator.CONTAINS, "myorg"); f2.negate(); SearchFilter filter = new SearchFilter(SearchFilter.LogicalOp.AND, f1, f2); ResultSet<User> sr = uMgr.searchUsers(filter, searchOpts); }