Oracle Access Management Identity Federation (Identity Federation) leverages the Access Manager plug-in framework to facilitate the provisioning of users. A standard user provisioning plug-in is provided or you can develop a custom plug-in, which is discussed here. This chapter provides the following sections:
See Also:
For more information about using the default user provisioning plug-in, see Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.
When Identity Federation is acting in Service Provider (SP) mode, the user assertion is mapped to a local store to complete the federated single sign-on. However, in some cases when a Service Provider is performing user assertion, a user may not be found. The default user provisioning plug-in (LDAPProvisioningPlugin
) will provision the user in the LDAP store configured as the Access Manager identity store.
All the information collected at runtime is passed to any user provisioning plug-in, standard or custom. The custom user provisioning plug-in must decide, based on this information, what user information it needs to retrieve and use. Additionally, each custom plug-in can include its own configuration designed to perform extra processing of the user to be provisioned.
When Identity Federation is acting in SP mode and fails to map assertion to a user, it will look for a configuration property to check if the missing user should be provisioned. If the user provisioning flag is set to true, Identity Federation will look up the plug-in name that needs invoking. The stand plug-in (LDAPProvisioningPlugin
) is invoked by default if a custom plug-in is not being used. The GenricPluginFactory
is used to locate the plug-in defined and executes the provisioning logic.
Identity Federation retrieves the property associated with the partner nameideattrname
to populate the nameid
value in the attribute list sent to the plug-in. If Identity Federation is configured to use the standard plug-in, the options for data store selection is as follows:
If Identity Federation is using the partner specific data store (multi-store), then Identity Federation will pass the identify store name to the plug-in.
If Identity Federation uses the default user identity store, the standard plug-in will use the User Provisioning APIs to provision user data in the data store.
If no partner specific store is configured, the default identity store is used.
The User Provisioning API used to provision a user is the same regardless whether a default identity store or a partner specific store is used.
The main class a custom user provisioning plug-in extends is OIFUserProvisioningPlugin
. The following interfaces are exposed to custom plug-ins:
oracle.security.fed.plugins.fed.provisioning.OIFUserProvisioningPlugin.java
(extends oracle.security.am.plugin.AbstractAMPlugin
)
oracle.security.fed.plugins.fed.provisioning.UserContext.java
oracle.security.fed.plugins.fed.provisioning.UserProvisioningException.java
oracle.security.fed.plugins.fed.provisioning.UserProvisioningConstants.java
For more information about these interfaces, see Oracle Fusion Middleware User Provisioning Plug-in Java API Reference for Oracle Access Management Identity Federation.
The custom user provisioning plug-in jar file structure must conform to an Access Manager custom authentication plug-in structure. Namely, it requires the following files: plugin.class, plugin.xml, and MANIFEST.MF. For more information about this structure, see Section 3.4, "Sample Code: Custom Database User Authentication Plug-in".
This section provides the following user provisioning plug-in code samples:
Example 13-1 Sample UserProvisioning.java
package oif.test; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import oracle.security.am.plugin.ExecutionStatus; import oracle.security.am.plugin.MonitoringData; import oracle.security.am.plugin.PluginConfig; import oracle.security.fed.plugins.fed.provisioning.OIFUserProvisioningPlugin; import oracle.security.fed.plugins.fed.provisioning.UserContext; import oracle.security.fed.plugins.fed.provisioning.UserProvisioningConstants; import oracle.security.fed.plugins.fed.provisioning.UserProvisioningException; /* * Sample OIF User proisioning plugin */ public class ProvisioningPlugin extends OIFUserProvisioningPlugin { private boolean monitoringStatus = false; private Map paramMap ; private String userRecordAttrList = null; private String useridAssertionAttr = null; /* (non-Javadoc) */ @Override public ExecutionStatus process(UserContext context) throws UserProvisioningException { /* * Execute method for plugin */ boolean provisioningStatus = false; try{ Map<String, Object> attrs = context.getAttributes(); Map<String, Object> attrsMapping = context.getAttributesUsedInMapping(); if (useridAssertionAttr == null) { System.out.println("User id attribute to create user is not found in the attributes list"); return ExecutionStatus.ABORT; } String userid = null; if (attrs.containsKey(useridAssertionAttr)) { Object valueObj = attrs.get(useridAssertionAttr); if (valueObj instanceof String) userid = (String) valueObj; else { userid = (String)((Set) valueObj).iterator().next(); } } DirContext ctx = getContext(); // creating the user record Attributes record = new BasicAttributes(); // Create the objectclass to add Attribute objClasses = new BasicAttribute("objectClass"); objClasses.add("top"); objClasses.add("person"); String objectClass = "inetOrgPerson"; objClasses.add(objectClass); objClasses.add("organizationalPerson"); record.put(objClasses); String userIDAttr = "uid"; // Set the attributes record.put(new BasicAttribute(userIDAttr, userid)); StringTokenizer st = new StringTokenizer(userRecordAttrList, ","); while (st.hasMoreTokens()) { String key = (String) st.nextToken(); record.put(new BasicAttribute(key, attrs.get(key))); } Set keys = attrsMapping.keySet(); Iterator itr = keys.iterator(); while (itr.hasNext()) { String key = (String) itr.next(); if (!attrs.containsKey(key)) { record.put(new BasicAttribute(key, attrsMapping.get(key))); } String ldapUserBaseDN = "dc=iplanet,dc=com"; // Create the record ctx.createSubcontext("cn=" + userid + "," + ldapUserBaseDN, record); provisioningStatus = true; } catch(Exception e){ /* * If exception abort the authentication. */ e.printStackTrace(); return ExecutionStatus.ABORT; } if( provisioningStatus){ /* * Success */ return ExecutionStatus.SUCCESS; }else{ /* * Failure. */ return ExecutionStatus.FAILURE; } } /* (non-Javadoc) * @see oracle.security.am.plugin.GenericPluginService#initialize(java.util.Map) */ @Override public ExecutionStatus initialize(PluginConfig config) { //success for the execution status userRecordAttrList = (String)config.getParameter(UserProvisioningConstants.KEY_USER_RECORD_ATTRIBUTE_LIST); useridAssertionAttr = (String)config.getParameter(UserProvisioningConstants.KEY_USERID_ATTRIBUTE_NAME); return ExecutionStatus.SUCCESS; } /* (non-Javadoc) * @see oracle.security.am.plugin.GenericPluginService#getDescription() */ @Override public String getDescription() { return "Ldap Provisioning Plugin"; } /* (non-Javadoc) * @see oracle.security.am.plugin.GenericPluginService#getMonitoringData() */ @Override public Map < String, MonitoringData > getMonitoringData() { // TODO Auto-generated method stub return null; } /* (non-Javadoc) * @see oracle.security.am.plugin.GenericPluginService#getMonitoringStatus() */ @Override public boolean getMonitoringStatus() { return monitoringStatus; } /* (non-Javadoc) * @see oracle.security.am.plugin.GenericPluginService#getName() */ @Override public String getPluginName() { return "LDAP_Provisioning_plugin"; } /* (non-Javadoc) * @see oracle.security.am.plugin.GenericPluginService#getVersion() */ @Override public int getRevision() { return 10; } /* (non-Javadoc) * @see oracle.security.am.plugin.GenericPluginService#setMonitoringStatus(boolean) */ @Override public void setMonitoringStatus(boolean status) { monitoringStatus = status; } private DirContext getContext() { try { DirContext context = null; String ldapURL = "ldap://myldap.oracle.com:389"; String ldapUserBaseDN = "dc=iplanet,dc=com"; Hashtable<String, String> env = new Hashtable <String, String> (); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, ldapURL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.REFERRAL, "follow"); String credential = "password"; String secPrincipal = "cn=Directory Manager"; env.put(Context.SECURITY_PRINCIPAL, secPrincipal); env.put(Context.SECURITY_CREDENTIALS, credential); context = new InitialDirContext (env); return context; } catch (NamingException ne) { throw new UserProvisioningException(ne); } catch (Throwable e) { throw new UserProvisioningException(e); } } }
Example 13-2 Sample UserPlugin.xml
<Plugin type="User Provisioning"> <author>uid=User1</author> <email>User1@mycompany</email> <creationDate>09:32:20,2012-06-15</creationDate> <description>User provisioning</description> <configuration> <AttributeValuePair> <Attribute type="string" length="100">KEY_USERID_ATTRIBUTE_NAME</Attribute> <mandatory>false</mandatory> <instanceOverride>false</instanceOverride> <globalUIOverride>true</globalUIOverride> <value>uid</value> </AttributeValuePair> <AttributeValuePair> <Attribute type="string" length="200">KEY_USER_RECORD_ATTRIBUTE_LIST</Attribute> <mandatory>true</mandatory> <instanceOverride>false</instanceOverride> <globalUIOverride>true</globalUIOverride> <value>mail,uid</value> </AttributeValuePair> </configuration> </Plugin>
Example 13-3 Sample MANIFEST.MF
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: ProvisioningPlugin Bundle-SymbolicName: ProvisioningPlugin Bundle-Version: 10 Bundle-Activator: oif.test.ProvisioningPlugin Import-Package: org.osgi.framework;version="1.3.0",oracle.security.fed.plugins.fed.provisioning Bundle-RequiredExecutionEnvironment: JavaSE-1.6
This section provides steps to write a custom Identity Federation user provisioning plug-in. The following describes the actions a developer must take after the system architect identifies the business requirements for the custom plug-in and considers the user provisioning flow when a user is not mapped to a local user store.
This section contains the following topics:
As Identity Federation leverages the Access Manager plug-in framework, the process is similar for both. For more information, see Section 3.1.2, "About Planning, the Authentication Model, and Plug-ins".
Extend OIFUserProvisioningPlugin
class and implement the following methods. For more information, see Section 3.5.1, "About Writing a Custom Authentication Plug-in".
Implement initialize
method
Implement process
method
Develop plug-in code using appropriate Access Manager 11g interfaces and packages. For more information, see:
Prepare metadata for the custom plug-in. For more information, see Section 3.4.2, "Sample Plug-in Configuration Metadata Requirements".
Prepare the plug-in jar file and manifest and deliver to your deployment team. For more information, see:
Proceed to Section 13.4.2, "Files Required for Compiling a Plug-in".
For information about deploying and managing custom authentication plug-ins, see Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.
The following jar files are needed for compiling the custom user provisioning plug-in:
felix.jar
oam-plugin.jar
fed.jar
The file are located in DOMAIN_HOME/servers/managed_instance_name/tmp/_WL_user/oam_server_11.1.2.0.0/RANDOM_STRING/APP-INF/lib.