The Shibboleth IdP V3 software has reached its End of Life and is no longer supported. This documentation is available for historical purposes only. See the IDP4 wiki space for current documentation on the supported version.
LDAPAuthnConfiguration
Format: Native Spring
V2 Legacy File(s): conf/handler.xml, conf/login.config
Overview
This back-end for the password authentication login flow uses native LDAP libraries for password-based authentication instead of using a JAAS module. The primary advantages are slightly better performance and more control over the process, such as the ability to extract detailed account status information from the directory during a login.
General Configuration
Configuring LDAP as a back-end requires that the right import is active in authn/password-authn-config.xml:
<import resource="ldap-authn-config.xml" />
The other imports must be commented or removed.
A large number of beans are defined in authn/ldap-authn-config.xml to configure this back-end, but in most cases the properties in ldap.properties can do most of the work needed. The beans can be used for very advanced cases where a higher degree of control is required.
A bean alias is also defined that instantiates the LDAP back-end action as the "ValidateUsernamePassword" step of the web flow. This must not be changed.
Basic Configuration
Authenticator Configuration
The idp.authn.LDAP.authenticator property controls the workflow for how authentication occurs against the LDAP directory:
anonSearchAuthenticator | Performs an anonymous search for the user's DN |
bindSearchAuthenticator | Binds as a configured DN then searches for the user's DN |
directAuthenticator | User DNs are of a known format. i.e. CN=user_name,ou=accounts,dc=domain,dc=edu. No DN search is performed. |
adAuthenticator | Configuration that leverages the AD specific @domain.com format. No DN search is performed since AD supports binding directly with that user name. |
Depending on the choice above, various other properties must be set (see the reference section below).
Connection Configuration
Use the following properties to configure basic connection information for the LDAP directory:
- idp.authn.LDAP.ldapURL
- idp.authn.LDAP.useStartTLS
- idp.authn.LDAP.useSSL
- idp.authn.LDAP.connectTimeout
A connection pool is used, and there are several properties used to configure pool behavior (see the reference below).
SSL Configuration
If StartTLS or SSL are used, a source of trust anchors must be configured to control certificate validation, using the idp.authn.LDAP.sslConfig property:
certificateTrust | Uses the idp.authn.LDAP.trustCertificates property to load a resource containing the trust anchors (such as a file of PEM-format certificates) |
keyStoreTrust | Uses the idp.authn.LDAP.trustStore property to load a keystore containing the trust anchors |
jvmTrust | Uses the default JVM trust anchors (the JVM-wide "cacerts" file) |
Advanced Configuration
Use authn/ldap-authn-config.xml to perform advanced configuration. The beans in this file correspond to properties of the Ldaptive authentication interface (see http://www.ldaptive.org/docs/guide/authentication). If you want to completely alter the LDAP objects used, you may want to consider copying the file to create your own version, and modify the beans used.
Reference
Beans
Some of the most important beans defined in authn/ldap-authn-config.xml follow.
Many other beans are defined in the file subordinate to the beans below. You are free to modify them as you see fit. Only the first two beans below are actually used by the login flow; the rest are injected into the shibboleth.authn.LDAP.authenticator bean to make up its content.
Bean ID | Type | Default | Function |
---|---|---|---|
shibboleth.authn.LDAP.authenticator | org.ldaptive.auth.Authenticator | Must be set to a bean of the appropriate type to configure the LDAP authentication library, normally a property-controlled alias for one of: anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, or adAuthenticator | |
shibboleth.authn.LDAP.returnAttributes | java.util.Collection<String> | The collection of attribute names to return in the LDAP operation, normally set via property | |
shibboleth.X509ResourceCredentialConfig | Resource path | A parent bean for supplying Ldaptive CredentialConfig instances using Spring resources containing X.509 trust anchors | |
shibboleth.KeystoreResourceCredentialConfig | Resource path | A parent bean for supplying Ldaptive CredentialConfig instances using Spring resources containing a Java keystore | |
sslConfig | org.ldaptive.ssl.SslConfig | Must be set to a bean of the appropriate type to configure the TLS trust source, normally a property-controlled alias for one of jvmTrust, certificateTrust, keystoreTrust |
Properties
A number of properties are found in ldap.properties to configure LDAP authentication. Most of the time, this is sufficient to deal with most configurations without having to delve into modifying any beans.
Property | Type | Default | Function |
---|---|---|---|
idp.authn.LDAP.authenticator | Enumeration | anonSearchAuthenticator | Controls the workflow for how authentication occurs against the LDAP, one of: anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator |
idp.authn.LDAP.ldapURL | LDAP URI | Connection URI for LDAP directory | |
idp.authn.LDAP.useStartTLS | Boolean | true | Whether StartTLS should be used after connecting with LDAP alone |
idp.authn.LDAP.useSSL | Boolean | false | Whether SSL should be used directly |
idp.authn.LDAP.connectTimeout | Integer | 3000 (PT3S) 3.3 | Connection timeout in milliseconds |
idp.authn.LDAP.responseTimeout 3.3 | Duration | PT3S | |
idp.authn.LDAP.sslConfig | Enumeration | certificateTrust | How to establish trust in the server's TLS certificate, one of: jvmTrust, certificateTrust, or keyStoreTrust |
idp.authn.LDAP.trustCertificates | Resource path | A resource to load trust anchors from, usually a local file in %{idp.home}/credentials | |
idp.authn.LDAP.trustStore | Resource path | A resource to load a Java keystore containing trust anchors, usually a local file in %{idp.home}/credentials | |
idp.authn.LDAP.returnAttributes | Comma-sep'd Strings | List of attributes to request during authentication | |
idp.authn.LDAP.baseDN | String | Base DN to search against, used by anonSearchAuthenticator, bindSearchAuthenticator | |
idp.authn.LDAP.subtreeSearch | Boolean | false | Whether to search recursively, used by anonSearchAuthenticator, bindSearchAuthenticator |
idp.authn.LDAP.userFilter | String | LDAP search filter, used by anonSearchAuthenticator, bindSearchAuthenticator | |
idp.authn.LDAP.bindDN | String | DN to bind with during search, used by bindSearchAuthenticator | |
idp.authn.LDAP.bindDNCredential | String | Password to bind with during search, used by bindSearchAuthenticator | |
idp.authn.LDAP.dnFormat | String | A formatting string to generate the user DNs to authenticate, used by directAuthenticator, adAuthenticator | |
idp.pool.LDAP.minSize | Integer | 3 | Minimum LDAP connection pool size |
idp.pool.LDAP.maxSize | Integer | 10 | Maximum LDAP connection pool size |
idp.pool.LDAP.validateOnCheckout | Boolean | false | Whether to validate connections when checking them out of the pool |
idp.pool.LDAP.validatePeriodically | Boolean | true | Whether to validate connections in the background |
idp.pool.LDAP.validatePeriod | Integer | 300 (PT5M) 3.3 | Interval in seconds between validation, if idp.pool.LDAP.validatePeriodically is true |
idp.pool.LDAP.prunePeriod | Integer | 300 (PT5M) 3.3 | Interval in seconds between looking for idle connections to reduce the pool back to its minimum size |
idp.pool.LDAP.idleTime | Integer | 600 (PT10M) 3.3 | Time in seconds that connections must be idle to be eligible for pruning |
idp.pool.LDAP.blockWaitTime | Integer | 3000 (PT3S) 3.3 | Time in milliseconds to wait for a free connection in the pool |
idp.pool.LDAP.failFastInitialize | Boolean | false | Whether to fail initialization of the components using the LDAP connection pool if the pool can't be established, or treat as a connection failure later |
Attribute Retrieval
LDAP attributes are returned as part of the authentication process and exposed in the LDAPResponseContext.
Property | Value | Result |
---|---|---|
idp.authn.LDAP.returnAttributes | uid, eduPersonAffiliation | Returns the uid and eduPersonAffiliation attributes. |
idp.authn.LDAP.returnAttributes | * | Returns all user attributes on the entry. |
idp.authn.LDAP.returnAttributes | *,+ | Returns all user and operational attributes on the entry. |
idp.authn.LDAP.returnAttributes | 1.1 | No attribute returned. No search performed. |
By default, attributes will be searched for using the same connection the user authenticated on. Therefore the user must have read on any attributes for those to be returned. If you need access to attributes that user does not have read access to, then you must configure a connection pool that is authorized to read. The following configuration demonstrates how to add a new connection pool for that purpose.
<!-- Modify the authenticator to use the entry resolver --> <bean name="anonSearchAuthenticator" class="org.ldaptive.auth.Authenticator" p:entryResolver-ref="bindSearchEntryResolver"> ... <!-- Add an entry resolver to read attributes --> <bean id="bindSearchEntryResolver" class="org.ldaptive.auth.PooledSearchEntryResolver" p:connectionFactory-ref="entryResolverPooledConnectionFactory" /> <bean id="entryResolverPooledConnectionFactory" class="org.ldaptive.pool.PooledConnectionFactory" p:connectionPool-ref="entryResolverConnectionPool" /> <bean id="entryResolverConnectionPool" class="org.ldaptive.pool.BlockingConnectionPool" parent="connectionPool" p:connectionFactory-ref="entryResolverConnectionFactory" p:name="entry-resolver-pool" /> <bean id="entryResolverConnectionFactory" class="org.ldaptive.DefaultConnectionFactory" p:connectionConfig-ref="entryResolverConnectionConfig" /> <bean id="entryResolverConnectionConfig" parent="connectionConfig" p:connectionInitializer-ref="entryResolverConnectionInitializer" /> <bean id="entryResolverConnectionInitializer" class="org.ldaptive.BindConnectionInitializer" p:bindDn="%{idp.authn.LDAP.entryResolver.bindDN}"> <property name="bindCredential"> <bean class="org.ldaptive.Credential"> <constructor-arg value="%{idp.authn.LDAP.entryResolver.bindDNCredential}" /> </bean> </property> </bean>
Add the idp.authn.LDAP.entryResolver.bindDN and idp.authn.LDAP.entryResolver.bindDNCredential properties to conf/ldap.properties to complete the configuration.
Note: if you're using the bindSearchAuthenticator and those credentials can be reused for entry resolution, then this configuration can be shortened by wiring the bindPooledConnectionFactory to the entry resolver.
DN Resolution
Single Directory with multiple branches
Extensible Matching
If your directory supports extensible matching, this is easiest way to find users that are distributed over multiple branches.
Property | Value | Result |
---|---|---|
idp.authn.LDAP.userFilter | (&(|(ou:dn:=people)(ou:dn:=guests))(uid={user})) | Returns the entry that matches uid on either the people or guests branch. |
idp.authn.LDAP.baseDN | dc=example,dc=org | The branch containing both ou=people and ou=guests. |
idp.authn.LDAP.subtreeSearch | true | Enable subtree searching on the dc=example,dc=org branch. |
Aggregate DN Resolver
This authenticator combines the results of multiple DN resolvers.
<bean name="aggregateAuthenticator" class="org.ldaptive.auth.Authenticator"> <constructor-arg index="0" ref="aggregateDnResolver" /> <constructor-arg index="1" ref="aggregateAuthHandler" /> </bean> <bean id="aggregateDnResolver" class="org.ldaptive.auth.AggregateDnResolver"> <constructor-arg index="0" ref="dnResolvers" /> </bean> <bean id="aggregateAuthHandler" class="org.ldaptive.auth.AggregateDnResolver$AuthenticationHandler" p:authenticationHandlers-ref="authHandlers" /> <util:map id="dnResolvers"> <entry key="filter1" value-ref="dnResolver1" /> <entry key="filter2" value-ref="dnResolver2" /> </util:map> <!-- Define two DN resolvers that use anonymous search against the same directory --> <bean id="dnResolver1" class="org.ldaptive.auth.PooledSearchDnResolver" p:baseDn="%{idp.authn.LDAP.baseDN1}" p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch:false}" p:userFilter="%{idp.authn.LDAP.userFilter1}" p:connectionFactory-ref="anonSearchPooledConnectionFactory" /> <bean id="dnResolver2" class="org.ldaptive.auth.PooledSearchDnResolver" p:baseDn="%{idp.authn.LDAP.baseDN2}" p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch:false}" p:userFilter="%{idp.authn.LDAP.userFilter2}" p:connectionFactory-ref="anonSearchPooledConnectionFactory" /> <!-- Use the same authentication handler for both DN resolvers --> <util:map id="authHandlers"> <entry key="filter1" value-ref="authHandler" /> <entry key="filter2" value-ref="authHandler" /> </util:map>
Add the idp.authn.LDAP.baseDN[12] and idp.authn.LDAP.userFilter[12] properties to conf/ldap.properties to complete the configuration. The key values used in dnResolvers and authHandlers can be anything, but must tie a single DN resolver to a single auth handler. By default an error will occur if more than (1) DN is resolved.
Multiple Directories
Aggregate DN Resolver
This authenticator combines the results of multiple DN resolvers that connect to multiple directories.
<bean name="aggregateAuthenticator" class="org.ldaptive.auth.Authenticator"> <constructor-arg index="0" ref="aggregateDnResolver" /> <constructor-arg index="1" ref="aggregateAuthHandler" /> </bean> <bean id="aggregateDnResolver" class="org.ldaptive.auth.AggregateDnResolver"> <constructor-arg index="0" ref="dnResolvers" /> </bean> <bean id="aggregateAuthHandler" class="org.ldaptive.auth.AggregateDnResolver$AuthenticationHandler" p:authenticationHandlers-ref="authHandlers" /> <util:map id="dnResolvers"> <entry key="directory1" value-ref="dnResolver1" /> <entry key="directory2" value-ref="dnResolver2" /> </util:map> <util:map id="authHandlers"> <entry key="directory1" value-ref="authHandler1" /> <entry key="directory2" value-ref="authHandler2" /> </util:map> <!-- define DN resolvers and authentication handlers for each directory... -->
DN resolvers are invoked asynchronously, so all resolvers will be used for each authentication request.
Account State
The LDAP library used (ldaptive) has the ability to extract detailed account status information from the directory during a login. According to ldaptive documentation, no standard for exposing account state data has been universally adopted by LDAP vendors, but the ldaptive library uses a handler which encapsulates account state information. This state contains Warning and Error types that are common to the most popular policy implementations.
Handling account state with OpenLDAP
The OpenLDAP password policy overlay (ppolicy), provides various password policy features. In some cases it can be desirable to be able to inform users whether a login is failed because of invalid credentials, an expired password, a locked account or give password expiration warning. In that cases, OpenLDAP password policy overlay adds account state information in LDAP responses.
In the IdP, the LDAP authn backend can be configured to handle the account state. The file authn/ldap-authn-config.xml has comments with instructions. The detailed configuration is:
<!-- 1. Add some beans --> <bean id="authenticationResponseHandler" class="org.ldaptive.auth.ext.PasswordPolicyAuthenticationResponseHandler" /> <bean id="authenticationControl" class="org.ldaptive.control.PasswordPolicyControl" /> <!-- 2. Comment out the bean of the handler with the same id, used for Active Directory: --> <!-- <bean id="authenticationResponseHandler" class="org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler" /> --> <!-- 3. In the existing authHandler bean definition, add the attribute p:authenticationControls-ref="authenticationControl": --> <bean id="authHandler" class="org.ldaptive.auth.PooledBindAuthenticationHandler" p:connectionFactory-ref="bindPooledConnectionFactory" p:authenticationControls-ref="authenticationControl" /> <!-- 4. In the authenticator bean definition, add the attribute p:authenticationResponseHandlers-ref="authenticationResponseHandler". Given that there are multiple authenticators, this attribute must be added to the authenticator in use (defined in ldap.properties, in idp.authn.LDAP.authenticator), e.g. if anonSearchAuthenticator is used, the definition could be: --> <bean name="anonSearchAuthenticator" class="org.ldaptive.auth.Authenticator" p:authenticationResponseHandlers-ref="authenticationResponseHandler" >
With that configuration and the default flow definitions, the user can be informed on the login page if the password is expired or is near expiration (messages can be customized in messages/authn-messages.properties).
Locked Accounts:
To inform the user of a locked account, some configuration is needed to detect the error code informed by the LDAP validation action.
In authn/password-authn-config.xml, add an entry to the message clasification rules in <util:map id="shibboleth.authn.Password.ClassifiedMessageMap">
<entry key="AccountLocked"> <list> <value>ACCOUNT_LOCKED</value> </list> </entry>
This maps the error code to a AccountLocked event. It will run the empty user flow authn/conditions/account-locked and then pass control back to the form. With this configuration, the user gets the message "Your account is locked".
Debug information:
Details of the AuthenticationResponse received, including the password policy controls, can be viewed using the TRACE log level in the logger of name "net.shibboleth.idp" (edit logback.xml).
Active Directory Configuration
The file authn/ldap-authn-config.xml comes with definitions to configure Active Directory authentication response handlers against a single directory.
Active Directory does not fully support extensible match rules (https://msdn.microsoft.com/en-us/library/cc223241.aspx).
Active Directory (by default) does not support anonymous queries (https://technet.microsoft.com/en-us/library/Cc755809%28v=WS.10%29.aspx).
Using an entry resolver to generate password expiration warnings
Example for two Active Directories with two DN Resolvers for each
This example uses directed BaseDN's with LDAP filters, and binds the queries.
Add missing Active Directory account state errors
ValidateUsernamePasswordAgainstLDAP authentication response. If adAuthenticator is the authenticator set in the idp.authn.LDAP.authenticator property, Short Description values are contained in the response. If bindSearchAuthenticator is the authenticator set in the idp.authn.LDAP.authenticator property, HEX values are contained in the response. It is possible to use either or both as outlined in the following example. (http://ldapwiki.willeke.com/wiki/Common%20Active%20Directory%20Bind%20Errors)
Notes
TBD