ResolverLDAPDataConnector
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:
- id - A unique, within the resolver configuration, ID for this data connector
- ldapURL - The base URL used to contact the directory. This is a space separated list. Each listed host is tried in turn until one accepts the connection.
- baseDN - This is the base DN from which the LDAP search will be executed
- principal - The user name (service DN) that the connector will use to bind to the LDAP directory
- principalCredential - The password used to authenticate as the principal (service DN)
You may also wish to use the optional attribute:
- lowercaseAttributeNames - boolean flag which causes all attribute IDs from the LDAP to be lower-cased. This can be important since Shibboleth attribute IDs are case-sensitive while LDAP attribute IDs are not. Default value: false
<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:
- connectionStrategy- The strategy used by the data connector to determine which LDAP URL, from a list, will be used when a connection needs to be made. If you are pooling connections, note that these values only apply when a new connection is opened. Acceptable values are:
- DEFAULT - Indicates that the default JNDI provider behavior will be used
- ACTIVE_PASSIVE (default value) - Indicates that the first LDAP URL will be used for every request until it fails and then the next LDAP URL will be used.
- ROUND_ROBIN - Indicates that for each new connection the next LDAP url in the list (circling back to the start of the list when the end is reached) will be used
- RANDOM - Indicates that for each new connection a random LDAP url will be selected
<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.
- minPoolSize: The minimum number of connections to keep available, default value is 0
- maxPoolSize: The maximum number of connections to keep available, default value is 3
- blockWhenEmpty: Whether to wait for an available connection when the entire pool is in use, default is true. If set to false then the number of connections can grow beyond maxPoolSize.
- blockWaitTime: Length of time to wait, given in XML duration notation, on the pool if
blockWhenEmpty
is true and the pool is empty. Default value is to wait indefinitely. - validatePeriodically: Whether each LDAP connection should be periodically checked. Default value is false.
- validateTimerPeriod: Interval, given in XML duration notation, between pool validation runs. Used in conjunction with expirationTime to remove connections from the pool. The pool will not be pruned below the minimum size. Default value is 30 minutes.
- validateDN: LDAP DN to use for connection validation. Used in conjunction with validateFilter to perform a compare.
- validateFilter: LDAP filter for connection validation. Used in conjunction with validateDN to perform a compare. Default value is objectClass=*.
- expirationTime: Amount of time, given in XML duration notation, after which a connection should be consider stale and ready for removal.
<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:
- searchScope: This parameter determines how recursively the connector will search the LDAP directory for attributes. Defaults to SUBTREE.
- SUBTREE: The entire LDAP directory subtree below the search baseDN will be searched.
- ONELEVEL: Only the immediate children of LDAP object corresponding to the search baseDN will be searched.
- maxResultSize: This parameter gives the directory a cap on the number of results that the connector is willing to receive from a given query. Defaults to 1.
- searchTimeLimit: The maximum duration in milliseconds that the connector will wait for search results before timing out. Defaults to 3000.
Result Processing Options
Several options influence how the results returned by the LDAP query are processed:
- mergeResults: Indicates that if there are multiple results from the LDAP query, all the names and values will be merged by union into a single set. If this is false and the number of results is greater than one, an error will result. Defaults to false.
- noResultIsError: If this is true, the connector will throw an error on a search that yields no results. When false, it will simply return a null set of attributes and values. Defaults to false.
- cacheResults: If false, search results won't be cached by the connector. Defaults to false. Deprecated in favor of the
<ResultCache>
element (see below).
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:
- elementTimeToLive - amount of time, in duration notation, that a result will be cached (Default value: 4 hours)
- maximumCachedElements - maximum number of results that will be cached at any one time, if this is exceeded the oldest entries will be discard first. (Default value: 500)
<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>