chap-identity-repo-spi.xml revision acef483d5e01904dda4eefb523fc726a5a378ba9
5394N/A<?xml version="1.0" encoding="UTF-8"?>
5394N/A<!--
5394N/A ! CCPL HEADER START
5394N/A !
5394N/A ! This work is licensed under the Creative Commons
5394N/A ! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
5394N/A ! To view a copy of this license, visit
5394N/A ! http://creativecommons.org/licenses/by-nc-nd/3.0/
5394N/A ! or send a letter to Creative Commons, 444 Castro Street,
5394N/A ! Suite 900, Mountain View, California, 94041, USA.
5394N/A !
5394N/A ! You can also obtain a copy of the license at
5394N/A ! src/main/resources/legal-notices/CC-BY-NC-ND.txt.
5394N/A ! See the License for the specific language governing permissions
5394N/A ! and limitations under the License.
5394N/A !
5394N/A ! If applicable, add the following below this CCPL HEADER, with the fields
5394N/A ! enclosed by brackets "[]" replaced with your own identifying information:
5394N/A ! Portions Copyright [yyyy] [name of copyright owner]
5394N/A !
5394N/A ! CCPL HEADER END
5394N/A !
5394N/A ! Copyright 2011-2013 ForgeRock AS
5394N/A !
5394N/A-->
5394N/A<chapter xml:id='chap-identity-repo-spi'
5394N/A xmlns='http://docbook.org/ns/docbook'
5394N/A version='5.0' xml:lang='en'
5394N/A xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
5394N/A xsi:schemaLocation='http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd'
5394N/A xmlns:xlink='http://www.w3.org/1999/xlink'
5394N/A xmlns:xinclude='http://www.w3.org/2001/XInclude'>
5394N/A <title>Customizing Identity Data Storage</title>
5394N/A <indexterm>
5394N/A <primary>User data</primary>
5394N/A <secondary>Custom repository</secondary>
5394N/A </indexterm>
5394N/A <!-- Another chapter based on Steve Ferris's work on the OpenAM wiki at
5394N/A https://wikis.forgerock.org/confluence/display/openam/Develop+and+Deploy+a+Custom+IdRepo+Plugin -->
5394N/A
5394N/A <para>OpenAM maps user and group identities into a realm using data stores.
5394N/A An OpenAM data store relies on a Java identity repository (IdRepo) plugin to
5394N/A implement interaction with the identity repository where the users and groups
5394N/A are stored.</para>
5394N/A
5394N/A <section xml:id="about-idrepo-plugin">
5394N/A <title>About the Identity Repository Plugin</title>
5394N/A
5394N/A <para>This chapter describes how to create a custom identity repository plugin.
5394N/A OpenAM includes built-in support for LDAP and JDBC identity repositories. For
5394N/A most deployments, you therefore do not need to create your own custom identity
5394N/A repository plugin. Only create custom identity repository plugins for
5394N/A deployments with particular requirements not met by built-in OpenAM
5394N/A functionality.</para>
5394N/A
5394N/A <tip>
5394N/A <para>Before creating your own identity repository plugin, start by reading
5394N/A the OpenAM source code for the <literal>FilesRepo</literal> or
5394N/A <literal>DatabaseRepo</literal> plugins under
5394N/A <literal>com.sun.identity.idm.plugins</literal>.</para>
5394N/A </tip>
5394N/A
5394N/A <section xml:id="idrepo-plugin-inheritance">
5394N/A <title>IdRepo Inheritance</title>
5394N/A
5394N/A <para>Your identity repository plugin class must extend the
5394N/A <literal>com.sun.identity.idm.IdRepo</literal> abstract class, and must
5394N/A include a constructor method that takes no arguments.</para>
5394N/A </section>
5394N/A
5394N/A <section xml:id="idrepo-plugin-lifecycle">
5394N/A <title>IdRepo Lifecycle</title>
5395N/A
5394N/A <para>When OpenAM instantiates your IdRepo plugin, it calls the
5394N/A <literal>initialize()</literal> method.</para>
5394N/A
5394N/A <programlisting language="java">public void initialize(Map configParams)</programlisting>
5394N/A
5394N/A <para>The <literal>configParams</literal> are service configuration
5394N/A parameters for the realm where the IdRepo plugin is configured. The
5394N/A <literal>configParams</literal> normally serve to set up communication with
5394N/A the underlying identity data store. OpenAM calls the
5394N/A <literal>initialize()</literal> method once, and considers the identity
5394N/A repository ready for use.</para>
5394N/A
5394N/A <para>If you encounter errors or exceptions during initialization, catch
5394N/A and store them in your plugin for use later when OpenAM calls other plugin
5394N/A methods.</para>
5394N/A
5394N/A <para>After initialization, OpenAM calls the <literal>addListener()</literal>
5394N/A and <literal>removeListener()</literal> methods to register listeners that
5394N/A inform OpenAM client code of changes to identities managed by your
5394N/A IdRepo.</para>
5394N/A
5394N/A <programlisting language="java">public int addListener(SSOToken token, IdRepoListener listener)
5394N/Apublic void removeListener()</programlisting>
5394N/A
5394N/A <para>You must handle listener registration in your IdRepo plugin, and also
5394N/A return events to OpenAM through the <literal>IdRepoListener</literal>.</para>
5394N/A
5394N/A <para>When stopping, OpenAM calls your IdRepo plugin
5394N/A <literal>shutdown()</literal> method.</para>
5394N/A
5396N/A <programlisting language="java">public void shutdown()</programlisting>
5394N/A
5394N/A <para>You are not required to implement <literal>shutdown()</literal> unless
5394N/A your IdRepo plugin has shut down work of its own to do, such as close
5423N/A connections to the underlying identity data store.</para>
5443N/A </section>
5423N/A
5423N/A <section xml:id="idrepo-plugin-capabilties">
5443N/A <title>IdRepo Plugin Capabilities</title>
5423N/A
5423N/A <para>Your IdRepo plugin provides OpenAM with a generic means to manage
5443N/A subjects&#8212;including users and groups but also special types such as
5443N/A roles, realms, and agents&#8212; and to create, read, update, delete, and
5443N/A search subjects. In order for OpenAM to determine your plugin's capabilities,
5443N/A it calls the methods described in this section.</para>
5423N/A
5423N/A <programlisting language="java">public Set getSupportedTypes()</programlisting>
5423N/A
5443N/A <para>The <literal>getSupportedTypes()</literal> method returns a set of
5443N/A <literal>IdType</literal> objects, such as <literal>IdType.USER</literal>
5423N/A and <literal>IdType.GROUP</literal>. You can either hard-code the supported
5423N/A types into your plugin, or make them configurable through the IdRepo
5423N/A service.</para>
5423N/A
5423N/A <programlisting language="java">public Set getSupportedOperations(IdType type)</programlisting>
5423N/A
5423N/A <para>The <literal>getSupportedOperations()</literal> method returns a set
5423N/A of <literal>IdOperation</literal> objects, such as
5443N/A <literal>IdOperation.CREATE</literal> and
5443N/A <literal>IdOperation.EDIT</literal>. You can also either hard-code these, or
5443N/A make them configurable.</para>
5423N/A
5423N/A <programlisting language="java">public boolean supportsAuthentication()</programlisting>
5423N/A
5394N/A <para>The <literal>supportsAuthentication()</literal> method returns true if
5394N/A your plugin supports the <literal>authenticate()</literal> method.</para>
5394N/A </section>
5394N/A </section>
5394N/A
5394N/A <section xml:id="idrepo-plugin-implementation">
5394N/A <title>Identity Repository Plugin Implementation</title>
5394N/A
5394N/A <para>Your IdRepo plugin implements operational methods depending on what
5394N/A you support. These methods perform the operations in your data store.</para>
5394N/A
5394N/A <variablelist>
5394N/A <varlistentry>
5394N/A <term>Create</term>
5394N/A <listitem>
5394N/A <para>OpenAM calls <literal>create()</literal> to provision a new identity
5394N/A in the repository, where <literal>name</literal> is the new identity's
5394N/A name, and <literal>attrMap</literal> holds the attributes names and
5394N/A values.</para>
5394N/A <programlisting language="java">public String create(SSOToken token, IdType type, String name, Map attrMap)
5394N/A throws IdRepoException, SSOException</programlisting>
5394N/A </listitem>
5394N/A </varlistentry>
5394N/A <varlistentry>
5394N/A <term>Read</term>
<listitem>
<para>OpenAM calls the following methods to retrieve subjects in the
identity repository, and to check account activity. If your data store
does not support binary attributes, return an empty <literal>Map</literal>
for <literal>getBinaryAttributes()</literal>.</para>
<programlisting language="java">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</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Edit</term>
<listitem>
<para>OpenAM calls the following methods to update a subject in the
identity repository.</para>
<programlisting language="java">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
)</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Authenticate</term>
<listitem>
<para>OpenAM calls <literal>authenticate()</literal> with the credentials
from the <literal>DataStore</literal> authentication module.</para>
<programlisting language="java">public boolean authenticate(Callback[] credentials)
throws IdRepoException, AuthLoginException</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Delete</term>
<listitem>
<para>The <literal>delete()</literal> method removes the subject from
the identity repository. The <literal>name</literal> specifies the
subject.</para>
<programlisting language="java">public void delete(SSOToken token, IdType type, String name)
throws IdRepoException, SSOException</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Service</term>
<listitem>
<para>The <literal>IdOperation.SERVICE</literal> operation is rarely used
in recent OpenAM deployments.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="idrepo-plugin-deployment">
<title>Identity Repository Plugin Deployment</title>
<para>
When you build your IdRepo plugin,
include <filename>${coreLibrary}</filename> in the classpath.
This file is found under <filename>WEB-INF/lib/</filename>
where OpenAM is deployed.
</para>
<para>
You can either package your plugin as a .jar,
and then add it to <filename>WEB-INF/lib/</filename>,
or add the classes under <filename>WEB-INF/classes/</filename>.
</para>
<para>To register your plugin with OpenAM, you add a
<literal>SubSchema</literal> to the
<literal>sunIdentityRepositoryService</literal> using the
<command>ssoadm</command> command. First, you create the
<literal>SubSchema</literal> document having the following structure.</para>
<programlisting language="xml">&lt;SubSchema i18nKey=&quot;x4000&quot; inheritance=&quot;multiple&quot; maintainPriority=&quot;no&quot;
name=&quot;CustomRepo&quot; supportsApplicableOrganization=&quot;no&quot; validate=&quot;yes&quot;&gt;
&lt;AttributeSchema cosQualifier=&quot;default&quot; isSearchable=&quot;no&quot;
name=&quot;RequiredValueValidator&quot; syntax=&quot;string&quot;
type=&quot;validator&quot; &gt;
&lt;DefaultValues&gt;
&lt;Value&gt;com.sun.identity.sm.RequiredValueValidator&lt;/Value&gt;
&lt;/DefaultValues&gt;
&lt;/AttributeSchema&gt;
&lt;AttributeSchema any=&quot;required&quot; cosQualifier=&quot;default&quot;
i18nKey=&quot;x4001&quot; isSearchable=&quot;no&quot;
name=&quot;sunIdRepoClass&quot; syntax=&quot;string&quot;
type=&quot;single&quot; validator=&quot;RequiredValueValidator&quot; &gt;
&lt;DefaultValues&gt;
&lt;Value&gt;org.test.CustomRepo&lt;/Value&gt;
&lt;/DefaultValues&gt;
&lt;/AttributeSchema&gt;
&lt;AttributeSchema cosQualifier=&quot;default&quot; i18nKey=&quot;x4002&quot; isSearchable=&quot;no&quot;
name=&quot;sunIdRepoAttributeMapping&quot; syntax=&quot;string&quot; type=&quot;list&quot;&gt;
&lt;DefaultValues&gt;
&lt;Value&gt;&lt;/Value&gt;
&lt;/DefaultValues&gt;
&lt;/AttributeSchema&gt;
&lt;/SubSchema&gt;</programlisting>
<para>Also include the <literal>AttributeSchema</literal> required to
configure your IdRepo plugin.</para>
<para>
Notice the <literal>i18nKey</literal> attributes
on <literal>SubSchema</literal> elements.
The <literal>i18nKey</literal> attribute values correspond to properties in
the <filename>amIdRepoService.properties</filename> file
under <filename>WEB-INF/classes/</filename> where OpenAM is deployed.
OpenAM console displays the label for the configuration user interface
that it retrieves from the value of the <literal>i18nKey</literal> property
in the <filename>amIdRepoService.properties</filename> file.
</para>
<para>
To make changes to the properties,
first extract <filename>amIdRepoService.properties</filename>
and if necessary the localized versions of this file
from <filename>${coreLibrary}</filename>
to <filename>WEB-INF/classes/</filename> where OpenAM is deployed.
For example, if OpenAM is deployed under
<filename>/path/to/tomcat/webapps/openam</filename>,
then you could run the following commands.
</para>
<screen>$ cd /path/to/tomcat/webapps/openam/WEB-INF/classes/
$ jar -xvf /lib/${coreLibrary} amIdRepoService.properties
inflated: amIdRepoService.properties</screen>
<para>Register your plugin using the <command>ssoadm</command> command after
copy the files into place.</para>
<screen>$ ssoadm
add-sub-schema
--adminid amadmin
--password-file /tmp/pwd.txt
--servicename sunIdentityRepositoryService
--schematype Organization
--filename customIdRepo.xml</screen>
<para>Login to OpenAM console as administrator, then then Browse to Access
Control &gt; <replaceable>Realm Name</replaceable> &gt; Data Stores. In the
Data Stores table, click New... to create a Data Store corresponding to your
custom IdRepo plugin. In the first screen of the wizard, name the Data Store
and select the type corresponding to your plugin. In the second screen of the
wizard, add the configuration for your plugin.</para>
<para>After creating the Data Store, create a new subject in the realm to
check that your plugin works as expected. You can do this under Access
Control &gt; <replaceable>Realm Name</replaceable> &gt; Subjects.</para>
<para>If your plugin supports authentication, then users should now be able
to authenticate using the <literal>DataStore</literal> module for the
realm.</para>
<literallayout class="monospaced">http://openam.example.com:8080/openam/UI/Login?realm=test&amp;module=DataStore</literallayout>
</section>
</chapter>