<?xml version="1.0" encoding="UTF-8"?>
|
<!--
|
! CCPL HEADER START
|
!
|
! This work is licensed under the Creative Commons
|
! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
|
! To view a copy of this license, visit
|
! http://creativecommons.org/licenses/by-nc-nd/3.0/
|
! or send a letter to Creative Commons, 444 Castro Street,
|
! Suite 900, Mountain View, California, 94041, USA.
|
!
|
! You can also obtain a copy of the license at
|
! trunk/opendj3/legal-notices/CC-BY-NC-ND.txt.
|
! See the License for the specific language governing permissions
|
! and limitations under the License.
|
!
|
! If applicable, add the following below this CCPL HEADER, with the fields
|
! enclosed by brackets "[]" replaced with your own identifying information:
|
! Portions Copyright [yyyy] [name of copyright owner]
|
!
|
! CCPL HEADER END
|
!
|
! Copyright 2013 ForgeRock AS
|
!
|
-->
|
<appendix xml:id='appendix-rest2ldap'
|
xmlns='http://docbook.org/ns/docbook' version='5.0' xml:lang='en'
|
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
|
xsi:schemaLocation='http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd'
|
xmlns:xlink='http://www.w3.org/1999/xlink'
|
xmlns:xinclude='http://www.w3.org/2001/XInclude'>
|
<title>REST LDAP Configuration</title>
|
<indexterm><primary>REST</primary></indexterm>
|
<indexterm><primary>HTTP</primary></indexterm>
|
<!-- This belongs in an OpenDJ reference. Ultimately this doc should
|
be generated, too, rather than written by hand. CREST-71? -->
|
|
<itemizedlist>
|
<para>OpenDJ offers two alternatives for RESTful access to directory
|
data.</para>
|
|
<listitem>
|
<para>OpenDJ directory server has an HTTP connection handler that exposes
|
the RESTful API over HTTP (or HTTPS). You configure the mapping between
|
JSON resources and LDAP entries by editing the configuration file for the
|
HTTP connection handler, by default
|
<filename>/path/to/opendj/config/http-config.json</filename>.</para>
|
</listitem>
|
|
<listitem>
|
<para>The OpenDJ REST LDAP gateway runs as a Servlet independent from your
|
directory service. You configure the gateway to access your directory service
|
by editing <filename>opendj-rest2ldap-servlet.json</filename> where you
|
deploy the gateway web application.</para>
|
</listitem>
|
</itemizedlist>
|
|
<!-- To be updated, pending OPENDJ-828 -->
|
<variablelist>
|
<para>The JSON format configuration can hold the following configuration
|
objects.</para>
|
|
<varlistentry>
|
<term>"primaryLDAPServers" (required)</term>
|
<listitem>
|
<para>The gateway accesses this array of LDAP servers before failing over
|
to the secondary LDAP servers. These might be LDAP servers in the same
|
data center for example.</para>
|
|
<programlisting language="javascript">{
|
"primaryLDAPServers": [
|
{
|
"hostname": "local1.example.com",
|
"port": 1389
|
},
|
{
|
"hostname": "local2.example.com",
|
"port": 1389
|
}
|
]
|
}</programlisting>
|
|
<para>By default, the gateway connects to the directory server listening
|
on port 1389 on the local host.</para>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<!-- TODO: change when we get more authentication options. -->
|
<term>"authentication" (required)</term>
|
<listitem>
|
<para>The gateway authenticates by simple bind using the credentials
|
specified.</para>
|
|
<programlisting language="javascript">{
|
"authentication": {
|
"bindDN": "cn=Directory Manager",
|
"password": "password"
|
}
|
}</programlisting>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"mappings"</term>
|
<listitem>
|
<para>For each gateway collection URI such as <literal>/users</literal> and
|
<literal>/groups</literal>, you configure a mapping between the JSON
|
resource returned by the gateway, and the LDAP entry returned by the
|
directory service.</para>
|
|
<variablelist>
|
<para>Each mapping has a number of configuration elements.</para>
|
|
<varlistentry>
|
<term>"baseDN" (required)</term>
|
<listitem>
|
<para>The base DN where LDAP entries are found for this mapping.</para>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"attributes" (required)</term>
|
<listitem>
|
<para>How the JSON resource fields map to attributes on LDAP
|
entries, each taking the form "<replaceable>field-name</replaceable>":
|
<replaceable>mapping-object</replaceable>. A number of
|
<replaceable>mapping-object</replaceable>s are supported.</para>
|
|
<variablelist>
|
<varlistentry>
|
<term>"constant"</term>
|
<listitem>
|
<para>Maps a single JSON attribute to a fixed value.</para>
|
|
<para>This can be useful as in the default case where each JSON
|
resource "schemas" takes the SCIM URN, and so the value is not related
|
to the underlying LDAP entries.</para>
|
|
<programlisting language="javascript">{
|
"schemas": {
|
"constant": [
|
"urn:scim:schemas:core:1.0"
|
]
|
}
|
}</programlisting>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"simple"</term>
|
<listitem>
|
<para>Maps a JSON field to an LDAP attribute.</para>
|
|
<para>Simple mappings are used where the correspondence between JSON
|
fields and LDAP attributes is one-to-one.</para>
|
|
<programlisting language="javascript">{
|
"userName": {
|
"simple": {
|
"ldapAttribute": "mail",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
}
|
}</programlisting>
|
|
<itemizedlist>
|
<para>Simple mappings can take a number of fields.</para>
|
|
<listitem>
|
<para>(Required) "ldapAttribute": the name of LDAP attribute.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "defaultValue": the JSON value if no LDAP attribute
|
is available on the entry.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "isBinary": true means the LDAP attribute is
|
binary and the JSON field gets the base64-encoded value.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "isRequired": true means the LDAP attribute is
|
mandatory and must be provided to create the resource; false means
|
it is optional.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "isSingleValued": true means represent a possibly
|
multi-valued LDAP attribute as a single value; false means represent
|
it as an array of values.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "writability": indicates whether the LDAP attribute
|
supports updates. This field can take the following values.</para>
|
|
<itemizedlist>
|
<listitem>
|
<para>"createOnly": This attribute can be set only when the
|
entry is created. Attempts to update this attribute thereafter
|
result in errors.</para>
|
</listitem>
|
<listitem>
|
<para>"createOnlyDiscardWrites": This attribute can be set only
|
when the entry is created. Attempts to update this attribute
|
thereafter do not result in errors. Instead the update value
|
is discarded.</para>
|
</listitem>
|
<listitem>
|
<para>"readOnly": This attribute cannot be updated. Attempts to
|
update this attribute result in errors.</para>
|
</listitem>
|
<listitem>
|
<para>"readOnlyDiscardWrites": This attribute cannot be updated.
|
Attempts to update this attribute do not result in errors. Instead
|
the update value is discarded.</para>
|
</listitem>
|
<listitem>
|
<para>"readWrite": This attribute can be set at creation and
|
updated thereafter.</para>
|
</listitem>
|
</itemizedlist>
|
</listitem>
|
</itemizedlist>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"object"</term>
|
<listitem>
|
<para>Maps a JSON object to LDAP attributes.</para>
|
|
<para>This mapping lets you create JSON objects whose fields themselves
|
have mappings to LDAP attributes.</para>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"reference"</term>
|
<listitem>
|
<para>Maps a JSON field to an LDAP entry found by reference.</para>
|
|
<para>This mapping works for LDAP attributes whose values reference
|
other entries. This is shown in the following example from the default
|
configuration. The LDAP <literal>manager</literal> attribute values
|
are user entry DNs. Here, the JSON <literal>manager</literal> field
|
takes the user ID and name from the entry referenced by the LDAP
|
attribute. On updates, changes to the JSON manager
|
<literal>_id</literal> affect which manager entry is referenced, yet
|
any changes to the manager's name are discarded, because changing
|
managers only affects which user entry to point to, not the referenced
|
user's name.</para>
|
|
<programlisting language="javascript">{
|
"manager": {
|
"reference": {
|
"ldapAttribute": "manager",
|
"baseDN": "ou=people,dc=example,dc=com",
|
"primaryKey": "uid",
|
"mapper": {
|
"object": {
|
"_id": {
|
"simple": {
|
"ldapAttribute": "uid",
|
"isSingleValued": true,
|
"isRequired": true
|
}
|
},
|
"displayName": {
|
"simple": {
|
"ldapAttribute": "cn",
|
"isSingleValued": true,
|
"writability": "readOnlyDiscardWrites"
|
}
|
}
|
}
|
}
|
}
|
}
|
}</programlisting>
|
|
<para>Babs Jensen's manager in the sample LDAP data is Torrey Rigden,
|
who has user ID <literal>trigden</literal>. Babs's entry has
|
<literal>manager: uid=trigden,ou=People,dc=example,dc=com</literal>.
|
With this mapping, the resulting JSON field is the following.</para>
|
|
<programlisting language="javascript">{
|
"manager": [
|
{
|
"_id": "trigden",
|
"displayName": "Torrey Rigden"
|
}
|
]
|
}</programlisting>
|
|
<itemizedlist>
|
<para>Reference mapping objects have the following fields.</para>
|
|
<listitem>
|
<para>(Required) "baseDN": indicates the base LDAP DN under which
|
to find entries referenced by the JSON resource.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Required) "ldapAttribute": specifies the LDAP attribute in
|
the entry underlying the JSON resource whose value points to the
|
referenced entry.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Required) "mapper": describes how the referenced entry
|
content maps to the content of this JSON field.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Required) "primaryKey": indicates which LDAP attribute in
|
the mapper holds the primary key to the referenced entry.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "filter": specifies the LDAP filter to use to
|
search for the referenced entry. The default is
|
<literal>"(objectClass=*)"</literal>.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "isRequired": true means the LDAP attribute is
|
mandatory and must be provided to create the resource; false means
|
it is optional.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "isSingleValued": true means represent a possibly
|
multi-valued LDAP attribute as a single value; false means represent
|
it as an array of values.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "scope": indicates the scope of the LDAP search to
|
find the referenced entry. The default is
|
<literal>"SearchScope.WHOLE_SUBTREE"</literal>.</para>
|
</listitem>
|
|
<listitem>
|
<para>(Optional) "writability": indicates whether the mapping
|
supports updates, as described above for the simple mapping. The
|
default is "readWrite".</para>
|
</listitem>
|
</itemizedlist>
|
</listitem>
|
</varlistentry>
|
|
</variablelist>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"namingStrategy" (required)</term>
|
<listitem>
|
<para>The approach used to map LDAP entry names to JSON resources. One
|
of the following.</para>
|
|
<itemizedlist>
|
<listitem>
|
<para>RDN and resource ID are both derived from a single user attribute
|
in the LDAP entry, as in the following example, where the
|
<literal>uid</literal> attribute is the RDN and its value is the
|
JSON resource ID.</para>
|
|
<programlisting language="javascript">{
|
"namingStrategy": {
|
"strategy": "clientDNNaming",
|
"dnAttribute": "uid"
|
}
|
}</programlisting>
|
</listitem>
|
|
<listitem>
|
<para>RDN and resource ID are derived from separate user attributes in
|
the LDAP entry, as in the following example where the RDN attribute is
|
<literal>uid</literal> but the JSON resource ID is the value of the
|
<literal>mail</literal> attribute.</para>
|
|
<programlisting language="javascript">{
|
"namingStrategy": {
|
"strategy": "clientNaming",
|
"dnAttribute": "uid",
|
"idAttribute": "mail"
|
}
|
}</programlisting>
|
</listitem>
|
|
<listitem>
|
<para>RDN is derived from a user attribute and the resource ID from an
|
operational attribute in the LDAP entry, as in the following example,
|
where the RDN attribute is <literal>uid</literal> but the JSON resource
|
ID is the value of the <literal>entryUUID</literal> operational
|
attribute.</para>
|
|
<programlisting language="javascript">{
|
"namingStrategy": {
|
"strategy": "serverNaming",
|
"dnAttribute": "uid",
|
"idAttribute": "entryUUID"
|
}
|
}</programlisting>
|
</listitem>
|
</itemizedlist>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"additionalLDAPAttributes" (optional, but necessary)</term>
|
<listitem>
|
<para>LDAP attributes to include during LDAP add operations as an
|
array of type-value lists, such as the following example.</para>
|
|
<programlisting language="javascript">{
|
"additionalLDAPAttributes": [
|
{
|
"type": "objectClass",
|
"values": [
|
"top",
|
"person",
|
"organizationalPerson",
|
"inetOrgPerson"
|
]
|
}
|
]
|
}</programlisting>
|
|
<para>This configuration element is useful to set LDAP object classes
|
for example, which are not present in JSON resources.</para>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"etagAttribute" (optional)</term>
|
<listitem>
|
<para>The LDAP attribute to use for multi-version concurrency control
|
(MVCC).</para>
|
|
<para>Default: "etag"</para>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"readOnUpdatePolicy" (optional)</term>
|
<listitem>
|
<para>The policy used to read an entry before it is deleted, or to
|
read an entry after it is added or modified. One of the following.</para>
|
|
<itemizedlist>
|
<listitem>
|
<para>"controls": use RFC 4527 read-entry controls to reflect the
|
state of the resource at the time the update was performed.</para>
|
<para>The directory service must support RFC 4527.</para>
|
<para>This is the default if no policy is specified.</para>
|
</listitem>
|
|
<listitem>
|
<para>"disabled": do not read the entry or return the resource on
|
update.</para>
|
</listitem>
|
|
<listitem>
|
<para>"search": perform an LDAP search to retrieve the entry before
|
deletion or after it is added or modified.</para>
|
<para>The JSON resource returned might differ from the LDAP entry that
|
was updated.</para>
|
</listitem>
|
</itemizedlist>
|
</listitem>
|
</varlistentry>
|
</variablelist>
|
|
<para>The default mappings expose a SCIM view of user and group data.</para>
|
|
<programlisting language="javascript">{
|
"/users": {
|
"baseDN": "ou=people,dc=example,dc=com",
|
"readOnUpdatePolicy": "controls",
|
"additionalLDAPAttributes": [
|
{
|
"type": "objectClass",
|
"values": [
|
"top",
|
"person",
|
"organizationalPerson",
|
"inetOrgPerson"
|
]
|
}
|
],
|
"namingStrategy": {
|
"strategy": "clientDNNaming",
|
"dnAttribute": "uid"
|
},
|
"etagAttribute": "etag",
|
"attributes": {
|
"schemas": {
|
"constant": [
|
"urn:scim:schemas:core:1.0"
|
]
|
},
|
"_id": {
|
"simple": {
|
"ldapAttribute": "uid",
|
"isSingleValued": true,
|
"isRequired": true,
|
"writability": "createOnly"
|
}
|
},
|
"_rev": {
|
"simple": {
|
"ldapAttribute": "etag",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
},
|
"userName": {
|
"simple": {
|
"ldapAttribute": "mail",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
},
|
"displayName": {
|
"simple": {
|
"ldapAttribute": "cn",
|
"isSingleValued": true,
|
"isRequired": true
|
}
|
},
|
"name": {
|
"object": {
|
"givenName": {
|
"simple": {
|
"ldapAttribute": "givenName",
|
"isSingleValued": true
|
}
|
},
|
"familyName": {
|
"simple": {
|
"ldapAttribute": "sn",
|
"isSingleValued": true,
|
"isRequired": true
|
}
|
}
|
}
|
},
|
"manager": {
|
"reference": {
|
"ldapAttribute": "manager",
|
"baseDN": "ou=people,dc=example,dc=com",
|
"primaryKey": "uid",
|
"mapper": {
|
"object": {
|
"_id": {
|
"simple": {
|
"ldapAttribute": "uid",
|
"isSingleValued": true,
|
"isRequired": true
|
}
|
},
|
"displayName": {
|
"simple": {
|
"ldapAttribute": "cn",
|
"isSingleValued": true,
|
"writability": "readOnlyDiscardWrites"
|
}
|
}
|
}
|
}
|
}
|
},
|
"groups": {
|
"reference": {
|
"ldapAttribute": "isMemberOf",
|
"baseDN": "ou=groups,dc=example,dc=com",
|
"writability": "readOnly",
|
"primaryKey": "cn",
|
"mapper": {
|
"object": {
|
"_id": {
|
"simple": {
|
"ldapAttribute": "cn",
|
"isSingleValued": true
|
}
|
}
|
}
|
}
|
}
|
},
|
"contactInformation": {
|
"object": {
|
"telephoneNumber": {
|
"simple": {
|
"ldapAttribute": "telephoneNumber",
|
"isSingleValued": true
|
}
|
},
|
"emailAddress": {
|
"simple": {
|
"ldapAttribute": "mail",
|
"isSingleValued": true
|
}
|
}
|
}
|
},
|
"meta": {
|
"object": {
|
"created": {
|
"simple": {
|
"ldapAttribute": "createTimestamp",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
},
|
"lastModified": {
|
"simple": {
|
"ldapAttribute": "modifyTimestamp",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
}
|
}
|
}
|
}
|
},
|
"/groups": {
|
"baseDN": "ou=groups,dc=example,dc=com",
|
"readOnUpdatePolicy": "controls",
|
"additionalLDAPAttributes": [
|
{
|
"type": "objectClass",
|
"values": [
|
"top",
|
"groupOfUniqueNames"
|
]
|
}
|
],
|
"namingStrategy": {
|
"strategy": "clientDNNaming",
|
"dnAttribute": "cn"
|
},
|
"etagAttribute": "etag",
|
"attributes": {
|
"schemas": {
|
"constant": [
|
"urn:scim:schemas:core:1.0"
|
]
|
},
|
"_id": {
|
"simple": {
|
"ldapAttribute": "cn",
|
"isSingleValued": true,
|
"isRequired": true,
|
"writability": "createOnly"
|
}
|
},
|
"_rev": {
|
"simple": {
|
"ldapAttribute": "etag",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
},
|
"displayName": {
|
"simple": {
|
"ldapAttribute": "cn",
|
"isSingleValued": true,
|
"isRequired": true,
|
"writability": "readOnly"
|
}
|
},
|
"members": {
|
"reference": {
|
"ldapAttribute": "uniqueMember",
|
"baseDN": "dc=example,dc=com",
|
"primaryKey": "uid",
|
"mapper": {
|
"object": {
|
"_id": {
|
"simple": {
|
"ldapAttribute": "uid",
|
"isSingleValued": true,
|
"isRequired": true
|
}
|
},
|
"displayName": {
|
"simple": {
|
"ldapAttribute": "cn",
|
"isSingleValued": true,
|
"writability": "readOnlyDiscardWrites"
|
}
|
}
|
}
|
}
|
}
|
},
|
"meta": {
|
"object": {
|
"created": {
|
"simple": {
|
"ldapAttribute": "createTimestamp",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
},
|
"lastModified": {
|
"simple": {
|
"ldapAttribute": "modifyTimestamp",
|
"isSingleValued": true,
|
"writability": "readOnly"
|
}
|
}
|
}
|
}
|
}
|
}
|
}</programlisting>
|
</listitem>
|
</varlistentry>
|
|
<!--
|
<varlistentry>
|
<term>"useSSL" (optional)</term>
|
<listitem>
|
<para>If the gateway connects with StartTLS or SSL to the directory
|
service, then you must specify how it uses SSL.</para>
|
<para>TODO: Not yet implemented.</para>
|
</listitem>
|
</varlistentry>
|
-->
|
|
<varlistentry>
|
<term>"secondaryLDAPServers" (optional)</term>
|
<listitem>
|
<para>The gateway accesses this array of LDAP servers if primary LDAP
|
servers cannot be contacted. These might be LDAP servers in the same
|
data center for example.</para>
|
|
<programlisting language="javascript">{
|
"secondaryLDAPServers": [
|
{
|
"hostname": "remote1.example.com",
|
"port": 1389
|
},
|
{
|
"hostname": "remote2.example.com",
|
"port": 1389
|
}
|
]
|
}</programlisting>
|
|
<para>No secondary LDAP servers are configured by default.</para>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"connectionPoolSize" (optional)</term>
|
<listitem>
|
<para>The gateway creates connection pools to the primary and secondary
|
LDAP servers that maintain up to <literal>connectionPoolSize</literal>
|
connections to the servers.</para>
|
|
<para>Default: 10</para>
|
|
<programlisting language="javascript">"connectionPoolSize": 10</programlisting>
|
</listitem>
|
</varlistentry>
|
|
<varlistentry>
|
<term>"heartBeatIntervalSeconds" (optional)</term>
|
<listitem>
|
<para>The gateway tests its connections every
|
<literal>heartBeatIntervalSeconds</literal> seconds to detect whether the
|
connection is still alive.</para>
|
|
<para>Default: 30 (seconds)</para>
|
|
<programlisting language="javascript">"heartBeatIntervalSeconds": 30</programlisting>
|
</listitem>
|
</varlistentry>
|
</variablelist>
|
</appendix>
|