LDAP Data Connector

The LDAP data connector allows the attribute authority to pull attributes from an LDAP v3 directory. These attributes are then available for use in other attribute definitions and data connectors.

You should also check out the collected idiosyncrasies of different LDAP products that have been found by deployers.

1. Define the Connector

To define a new LDAP data connector, create a <DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc" with the following attributes:

You may also wish to use the optional attribute:

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL"
                        lowercaseAttributeNames="true">

     <!-- Remaining configuration from the next steps go here -->

</resolver:DataConnector>

If your LDAP returns attributes whose values are binary data you must provide the LDAP property to identify these attributes.

2. Define Dependencies

This step is optional.

It is very common for one component, like data connectors, within the attribute resolver to depend on information retrieved or constructed from another component. The values from these dependencies may then be used within the filter template in the next step.

Dependencies are expressed by the <resolver:Dependency> with a ref attribute whose value is the unique ID of the attribute definition or the data connector that this connector depends on.

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL">

    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <!-- Remaining configuration from the next steps go here -->

</resolver:DataConnector>

3. Define the Search Parameters

The search filter used when searching the LDAP directory employs the IdPs template engine to construct the filter from a template. The filter template is provided by the <FilterTemplate> within the data connector definition. It is recommended that you wrap your filter in a CDATA section to ensure the proper processing of the resolver configuration file.

In addition to the filter template you may also expressly indicate which attributes may be returned from a search. Use the <ReturnAttributes> element and provide a space separated list of the returned attribute names as its content. This is optional but may help the LDAP server respond more quickly.

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL">


    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <FilterTemplate>
        <![CDATA[
            (uid=${requestContext.principalName})
        ]]>
    </FilterTemplate>

    <ReturnAttributes>ATTRIBUTE_1 ATTRIBUTE_2 ATTRIBUTE_3</ReturnAttributes>

     <!-- Remaining configuration from the next steps go here -->

</resolver:DataConnector>

Advanced Configuration Options

In order to handle more advanced use cases, additional options are available for the data connector related to SSL/TLS, connection pool behavior, query behavior and attribute result set processing. Except where noted, these options are declared as additional attributes on the <DataConnector> element.

LDAP SSL/TLS Support

The LDAP data connector supports both LDAPS (LDAP over SSL, for which no formal specification exists) and LDAP with StartTLS (as per RFC 4513).

To enable LDAPS support ensure that the LDAP connection URL starts with ldaps:// (note the "s") and that the CA that signed your LDAP server's digital certificate is in the JVM's cacert file. If it is not you may add it (or the LDAP server's certificate itself, and again each time it changes) with the following command:

keytool -import -trustcacerts -alias "sensible-name-for-ca" -file ca-for-directory-server.crt -keystore $JAVA_HOME/lib/security/cacerts

To enable LDAP with StartTLS add the attribute useStartTLS="true" to the data connector definition. If your LDAP server's digital certificate is not trusted by the JVM and you do not wish, or are unable, to add the CA that signed your LDAP server's digital certificate to your keystore, you may provide the LDAP server's certificate itself within this connector's configuration or provide the certificate of the CA that generated and signed the server certificate.  This is an X.509 credential defined in the same manner as all other X.509 security credentials.  To trust the server or CA X.509 certificate, use the <StartTLSTrustCredential> to point to the trusted certificate in line in the data connector or in a file you point to containing the certificate.  The login module in login.config can point to the same file (assuming you use the same LDAP directory for user authentication and to retrieve attributes) eliminating the need to import and maintain multiple copies of the certificate.

If you import the server certificate itself, you will have to track changes to the LDAP server's certificate and change your DataConnector configuration each time the LDAP server's certificate changes.  If you import the CA certificate, it is often longer lived, and the same CA certificate can enable trust of multiple servers for redundancy or fail-over (e.g., "Multiple LDAP Replicas" on this page, below).

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL"
                        useStartTLS="true">

    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <FilterTemplate>
        <![CDATA[
            (uid=${requestContext.principalName})
        ]]>
    </FilterTemplate>

    <StartTLSTrustCredential xsi:type="security:X509Inline" xmlns:security="urn:mace:shibboleth:2.0:security" id="LDAPtoIdPCredential">
        <security:Certificate>
        <!-- PEM-encoded certificate goes here -->
        </security:Certificate>
    </StartTLSTrustCredential>
</resolver:DataConnector>

Data Connector Trusting Private CA's Certificate in File System

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="••••••••"
                        useStartTLS="true">

    <FilterTemplate>
        <![CDATA[
            (|(sAMAccountName=$requestContext.principalName)(uaIdentifier=$requestContext.principalName))
        ]]>
    </FilterTemplate>

    <StartTLSTrustCredential xsi:type="security:X509Filesystem"
        	xmlns:security="urn:mace:shibboleth:2.0:security"
			id="UA_AD_CA_Certificate">
        	<security:Certificate>/opt/shibboleth-idp/trustedservercerts/UA_AD_CA.pem</security:Certificate>
    </StartTLSTrustCredential>
</resolver:DataConnector>

Client Certificate Authentication to the LDAP directory

Also, if you wish to use a client certificate when connecting to the LDAP, you may provide that along with the corresponding private key by means of the <StartTLSAuthenticationCredential> element.  This is also an X.509 credential defined in the same manner as all other X.509 security credentials.

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        useStartTLS="true">

    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <FilterTemplate>
        <![CDATA[
            (uid=${requestContext.principalName})
        ]]>
    </FilterTemplate>

    <StartTLSTrustCredential xsi:type="security:X509Filesystem" xmlns:security="urn:mace:shibboleth:2.0:security" id="LDAPtoIdPCredential">
        <security:Certificate>/opt/shibboleth-idp/credentials/ldapserver.crt</security:Certificate>
    </StartTLSTrustCredential>
    <StartTLSAuthenticationCredential xsi:type="security:X509Filesystem" xmlns:security="urn:mace:shibboleth:2.0:security" id="IdPtoLDAPCredential">
        <security:PrivateKey>/opt/shibboleth-idp/credentials/idpforldap.key</security:PrivateKey>
        <security:Certificate>/opt/shibboleth-idp/credentials/idpforldap.crt</security:Certificate>
    </StartTLSAuthenticationCredential>
</resolver:DataConnector>

Multiple LDAP Replicas

The ldapUrl property can take a space-delimited list of LDAP URLs. The way in which the data connector chooses to determine which LDAP URL to use for any given request is determined by the following attribute:

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL"
                        connectionStrategy="RANDOM">

    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <!-- Remaining configuration from the next steps go here -->

</resolver:DataConnector>

Connection Pool Options

Several options are available which determine how the connector manages its connection pool.  By default, the resolver does not pool connections.

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL">

    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <ConnectionPool minPoolSize="3"
                    maxPoolSize="8"
                    blockWhenEmpty="true"
                    blockWaitTime="PT5S"
                    validatePeriodically="true"
                    validateTimerPeriod="PT30M"
                    validateDN="ou=people,dc=vt,dc=edu"
                    validateFilter="(ou=people)"
                    expirationTime="PT10M"/>

</resolver:DataConnector>

Query Options

Several options are available which influence how the query to the LDAP directory is performed:

Result Processing Options

Several options influence how the results returned by the LDAP query are processed:

Result Caching

The data connector may cache query results for a period of time or until too many results are in memory.

To enable and configuration result caching add the <ResultCache> element as the last element in the data connector. The element has the following attributes:

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL"
                        connectionStrategy="RANDOM">

    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <!-- Remaining configuration from the next steps go here -->

    <ResultCache elementTimeToLive="PT1H" />

</resolver:DataConnector>

Other Connection Properties

Additional configuration properties which aren't handled explicitly by the options above, and which are supported by the underlying LDAP provider used by the connector, may be added as simple key/value pairs via the inclusion of <LDAPProperty name="option" value="value"/> elements within the <DataConnector> element. These elements are added after the <FilterTemplate> and <ReturnAttributes>, but before <StartTLSTrustCredential> and <StartTLSAuthenticationCredential>.

Only options not represented by the configuration settings described above can be set with this mechanism.

Information on the properties supported by Sun's Java 6 SE JDK is here. In particular the java.naming.ldap.attributes.binary attribute is used to tell the system which attribute have binary data as values.

The provider used with Shibboleth also supports a number of properties, which are described in its documentation.

<resolver:DataConnector xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
                        id="UNIQUE_ID"
                        ldapURL="LDAP_URL"
                        baseDN="BASE_DN"
                        principal="PRINCIPAL_NAME"
                        principalCredential="PRINCIPAL_CREDENTIAL">

    <resolver:Dependency ref="DEFINITION_ID_1" />
    <resolver:Dependency ref="DEFINITION_ID_2" />
    <resolver:Dependency ref="CONNECTOR_ID_3" />
    <resolver:Dependency ref="CONNECTOR_ID_4" />

    <FilterTemplate>
        <![CDATA[
            (uid=${requestContext.principalName})
        ]]>
    </FilterTemplate>

    <ReturnAttributes>ATTRIBUTE_1 ATTRIBUTE_2 ATTRIBUTE_3</ReturnAttributes>

    <LDAPProperty name="PROPERTY_NAME_1" value="VALUE"/>
    <LDAPProperty name="PROPERTY_NAME_2" value="VALUE"/>

</resolver:DataConnector>