Localtab live |
---|
active | true |
---|
title | Attribute Retrieval |
---|
|
LDAP attributes are returned as part of the authentication process and exposed in the LDAPResponseContext. Property | Sample | Result |
---|
idp.authn.LDAP.returnAttributes | uid, eduPersonAffiliation | Returns the uid and eduPersonAffiliation attributes. | * | Returns all user attributes on the entry. | *,+ | Returns all user and operational attributes on the entry. | 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 that data. The following configuration demonstrates how to add a new connection pool for that purpose.
Spring Configuration Code Block |
---|
| <!-- 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 and credentials/secrets.properties respectively. Then set idp.authn.LDAP.authenticator to anonSearchAuthenticator. 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. Single Directory with multiple branchesExtensible MatchingIf 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 ResolverThis authenticator combines the results of multiple DN resolvers. Spring Configuration Code Block |
---|
| <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. Then set idp.authn.LDAP.authenticator to aggregateAuthenticator 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 DirectoriesAggregate DN ResolverThis authenticator combines the results of multiple DN resolvers that connect to multiple directories. Spring Configuration Code Block |
---|
| <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... --> |
Complete example with DN resolvers and authentication handlers for bindSearch Code Block |
---|
| <!-- Properties:
- idp.authn.LDAP.authenticator = aggregateAuthenticator
- idp.authn.LDAP.ldapURL1
- idp.authn.LDAP.ldapURL2
- idp.authn.LDAP.baseDN1
- idp.authn.LDAP.baseDN2
- idp.authn.LDAP.userFilter1
- idp.authn.LDAP.userFilter2
- idp.authn.LDAP.bindDN1
- idp.authn.LDAP.bindDN2
- idp.authn.LDAP.bindDNCredential1
- idp.authn.LDAP.bindDNCredential2
-->
<bean id="aggregateAuthenticator" class="org.ldaptive.auth.Authenticator"
c:resolver-ref="aggregateDnResolver"
c:handler-ref="aggregateAuthHandler" />
<!-- Aggregate DN resolution -->
<bean id="aggregateDnResolver" class="org.ldaptive.auth.AggregateDnResolver"
c:resolvers-ref="dnResolvers"
p:allowMultipleDns="true" />
<util:map id="dnResolvers">
<entry key="directory1" value-ref="bindSearchDnResolver1" />
<entry key="directory2" value-ref="bindSearchDnResolver2" />
</util:map>
<!-- DN resolver 1 -->
<bean id="bindSearchDnResolver1" class="org.ldaptive.auth.PooledSearchDnResolver"
p:baseDn="#{'%{idp.authn.LDAP.baseDN1:undefined}'.trim()}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch:false}"
p:userFilter="#{'%{idp.authn.LDAP.userFilter1:undefined}'.trim()}"
p:connectionFactory-ref="bindSearchPooledConnectionFactory" />
<bean id="bindSearchPooledConnectionFactory1" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="bindSearchConnectionPool1" />
<bean id="bindSearchConnectionPool1" class="org.ldaptive.pool.BlockingConnectionPool" parent="connectionPool"
p:connectionFactory-ref="bindSearchConnectionFactory1"
p:name="search-pool1" />
<bean id="bindSearchConnectionFactory1" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="bindSearchConnectionConfig1" />
<bean id="bindSearchConnectionConfig1" parent="connectionConfig"
p:connectionInitializer-ref="bindConnectionInitializer1"
p:ldapUrl="%{idp.authn.LDAP.ldapURL1}" />
<bean id="bindConnectionInitializer1" class="org.ldaptive.BindConnectionInitializer"
p:bindDn="#{'%{idp.authn.LDAP.bindDN1:undefined}'.trim()}">
<property name="bindCredential">
<bean class="org.ldaptive.Credential" c:password="%{idp.authn.LDAP.bindDNCredential1:undefined}" />
</property>
</bean>
<!-- DN resolver 2 -->
<bean id="bindSearchDnResolver2" class="org.ldaptive.auth.PooledSearchDnResolver"
p:baseDn="#{'%{idp.authn.LDAP.baseDN2:undefined}'.trim()}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch:false}"
p:userFilter="#{'%{idp.authn.LDAP.userFilter2:undefined}'.trim()}"
p:connectionFactory-ref="bindSearchPooledConnectionFactory" />
<bean id="bindSearchPooledConnectionFactory2" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="bindSearchConnectionPool2" />
<bean id="bindSearchConnectionPool2" class="org.ldaptive.pool.BlockingConnectionPool" parent="connectionPool"
p:connectionFactory-ref="bindSearchConnectionFactory2"
p:name="search-pool2" />
<bean id="bindSearchConnectionFactory2" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="bindSearchConnectionConfig2" />
<bean id="bindSearchConnectionConfig2" parent="connectionConfig"
p:connectionInitializer-ref="bindConnectionInitializer2"
p:ldapUrl="%{idp.authn.LDAP.ldapURL2}" />
<bean id="bindConnectionInitializer2" class="org.ldaptive.BindConnectionInitializer"
p:bindDn="#{'%{idp.authn.LDAP.bindDN2:undefined}'.trim()}">
<property name="bindCredential">
<bean class="org.ldaptive.Credential" c:password="%{idp.authn.LDAP.bindDNCredential2:undefined}" />
</property>
</bean>
<!-- Aggregate authentication -->
<bean id="aggregateAuthHandler" class="org.ldaptive.auth.AggregateDnResolver$AuthenticationHandler"
p:authenticationHandlers-ref="authHandlers" />
<util:map id="authHandlers">
<entry key="directory1" value-ref="authHandler1" />
<entry key="directory2" value-ref="authHandler2" />
</util:map>
<!-- Authentication handler 1 -->
<bean id="authHandler1" class="org.ldaptive.auth.PooledBindAuthenticationHandler"
p:connectionFactory-ref="bindPooledConnectionFactory1" />
<bean id="bindPooledConnectionFactory1" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="bindConnectionPool1" />
<bean id="bindConnectionPool1" class="org.ldaptive.pool.BlockingConnectionPool" parent="connectionPool"
p:connectionFactory-ref="bindConnectionFactory1"
p:name="bind-pool1" />
<bean id="bindConnectionFactory1" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="bindConnectionConfig1" />
<bean id="bindConnectionConfig1" parent="connectionConfig"
p:ldapUrl="%{idp.authn.LDAP.ldapURL1}" />
<!-- Authentication handler 2 -->
<bean id="authHandler2" class="org.ldaptive.auth.PooledBindAuthenticationHandler"
p:connectionFactory-ref="bindPooledConnectionFactory2" />
<bean id="bindPooledConnectionFactory2" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="bindConnectionPool2" />
<bean id="bindConnectionPool2" class="org.ldaptive.pool.BlockingConnectionPool" parent="connectionPool"
p:connectionFactory-ref="bindConnectionFactory2"
p:name="bind-pool2" />
<bean id="bindConnectionFactory2" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="bindConnectionConfig2" />
<bean id="bindConnectionConfig2" parent="connectionConfig"
p:ldapUrl="%{idp.authn.LDAP.ldapURL2}" /> |
DN resolvers are invoked asynchronously, so all resolvers will be used for each authentication request. The ldaptive LDAP library has the ability to extract detailed account status information from the directory during authentication. According to the Ldaptive documentation, no standard for exposing account state data has been universally adopted by LDAP vendors, but the 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. Password Policy ControlThe Password Policy for LDAP Directories (draft) standard is implemented by several LDAP directories, including OpenLDAP and Oracle DSEE. The Password Policy Control is used during an LDAP bind operation to request information about the user's account state. To enable the Password Policy Control handlers in ldaptive, add the following to conf/ldap.properties: conf/ldap.properties Code Block |
---|
| # Use password policy control
idp.authn.LDAP.usePasswordPolicy = true
|
The user will be informed on the login page if there are any Password Policy warnings or errors (messages can be customized in messages/messages.properties). Password expiration warnings have been confirmed to work with Oracle DSEE. Please notify us or edit this page if you test successfully with other directory products. Locked AccountsTo inform the user of a locked account, some configuration is needed to detect the error code returned by the LDAP bind request. In authn/password-authn-config.xml, add an entry to the message clasification rules defined by shibboleth.authn.Password.ClassifiedMessageMap password-authn-config.xml Code Block |
---|
| <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". 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 ConfigurationThe system 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 warningsSpring Configuration Code Block |
---|
| <!-- authenticator with entry resolver-->
<bean id="adAuthenticator" class="org.ldaptive.auth.Authenticator" p:entryResolver-ref="bindSearchEntryResolver" p:authenticationResponseHandlers-ref="authenticationResponseHandler" p:resolveEntryOnFailure="false">
<constructor-arg index="0" ref="formatDnResolver" />
<constructor-arg index="1" ref="authHandler" />
</bean>
<!-- authentication response handler that defines a password expiration period and warning period -->
<!-- expiration period is the amount of time since a password was set that it will expire in period notation -->
<!-- expiration period is only used if the msDS-UserPasswordExpiryTimeComputed attributes cannot be read and pwdLastSet can be read -->
<!-- warning period is the amount of time before expiration to produce a warning in period notation. Warning period is only applied if an expiration period can be resolved. -->
<!-- note that this response handler has a default constructor without these properties if you don't want to override the defaults -->
<bean id="authenticationResponseHandler" class="org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler" >
<constructor-arg index="0">
<bean factory-method="parse" class="java.time.Period">
<constructor-arg value="%{idp.authn.LDAP.expirationPeriod}" />
</bean>
</constructor-arg>
<constructor-arg index="1">
<bean factory-method="parse" class="java.time.Period">
<constructor-arg value="%{idp.authn.LDAP.warningPeriod}" />
</bean>
</constructor-arg>
</bean>
<!-- Add an entry resolver to read the pwdLastSet, must be included in idp.authn.LDAP.returnAttributes -->
<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>
|
Example for two Active Directories with two DN Resolvers for eachThis example uses directed BaseDN's with LDAP filters, and binds the queries. Spring Configuration Code Block |
---|
| <!-- Define Directory1 connection pool -->
<bean id="adConnectionPool1" class="org.ldaptive.pool.BlockingConnectionPool" abstract="true"
p:blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
p:poolConfig-ref="adPoolConfig1"
p:pruneStrategy-ref="adPruneStrategy1"
p:validator-ref="adSearchValidator1"
p:failFastInitialize="%{idp.pool.LDAP.failFastInitialize:false}" />
<bean id="adPoolConfig1" class="org.ldaptive.pool.PoolConfig"
p:minPoolSize="%{idp.pool.LDAP.minSize:3}"
p:maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
p:validateOnCheckOut="%{idp.pool.LDAP.validateOnCheckout:false}"
p:validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}"
p:validatePeriod="%{idp.pool.LDAP.validatePeriod:PT5M}" />
<bean id="adPruneStrategy1" class="org.ldaptive.pool.IdlePruneStrategy"
p:prunePeriod="%{idp.pool.LDAP.prunePeriod:PT5M}"
p:idleTime="%{idp.pool.LDAP.idleTime:PT10M}" />
<bean id="adSearchValidator1" class="org.ldaptive.pool.SearchValidator" />
<!-- Directory1 connection pool settings -->
<bean id="adConnectionConfig1" class="org.ldaptive.ConnectionConfig" abstract="true"
p:ldapUrl="%{idp.authn.LDAP.ldapURL1}"
p:useStartTLS="%{idp.authn.LDAP.useStartTLS1:true}"
p:connectTimeout="%{idp.authn.LDAP.connectTimeout1:PT3S}"
p:sslConfig-ref="adSslConfig1" />
<alias name="%{idp.authn.LDAP.sslConfig:certificateTrust}" alias="adSslConfig1" />
<!-- Define Directory2 connection pool -->
<bean id="adConnectionPool2" class="org.ldaptive.pool.BlockingConnectionPool" abstract="true"
p:blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
p:poolConfig-ref="adPoolConfig2"
p:pruneStrategy-ref="adPruneStrategy2"
p:validator-ref="adSearchValidator2"
p:failFastInitialize="%{idp.pool.LDAP.failFastInitialize:false}" />
<bean id="adPoolConfig2" class="org.ldaptive.pool.PoolConfig"
p:minPoolSize="%{idp.pool.LDAP.minSize:3}"
p:maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
p:validateOnCheckOut="%{idp.pool.LDAP.validateOnCheckout:false}"
p:validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}"
p:validatePeriod="%{idp.pool.LDAP.validatePeriod:PT5M}" />
<bean id="adPruneStrategy2" class="org.ldaptive.pool.IdlePruneStrategy"
p:prunePeriod="%{idp.pool.LDAP.prunePeriod:PT5M}"
p:idleTime="%{idp.pool.LDAP.idleTime:PT10M}" />
<bean id="adSearchValidator2" class="org.ldaptive.pool.SearchValidator" />
<!-- Directory2 connection pool settings -->
<bean id="adConnectionConfig2" class="org.ldaptive.ConnectionConfig" abstract="true"
p:ldapUrl="%{idp.authn.LDAP.ldapURL3}"
p:useStartTLS="%{idp.authn.LDAP.useStartTLS3:true}"
p:connectTimeout="%{idp.authn.LDAP.connectTimeout3:PT3S}"
p:sslConfig-ref="adSslConfig2" />
<alias name="%{idp.authn.LDAP.sslConfig:certificateTrust}" alias="adSslConfig2" />
<!-- ldap.properties "idp.authn.LDAP.authenticator = adAggregateAuthenticator" -->
<bean id="adAggregateAuthenticator" class="org.ldaptive.auth.Authenticator"
p:authenticationResponseHandlers-ref="adAuthenticationResponseHandler">
<constructor-arg index="0" ref="adAggregateDnResolver" />
<constructor-arg index="1" ref="adAggregateAuthHandler" />
</bean>
<bean id="adAuthenticationResponseHandler" class="org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler" />
<bean id="adAggregateDnResolver" class="org.ldaptive.auth.AggregateDnResolver">
<constructor-arg index="0" ref="adDnResolvers" />
</bean>
<bean id="adAggregateAuthHandler" class="org.ldaptive.auth.AggregateDnResolver$AuthenticationHandler"
p:authenticationHandlers-ref="adAuthHandlers" />
<util:map id="adDnResolvers">
<entry key="directory1_filter1" value-ref="adDnResolver1" />
<entry key="directory1_filter2" value-ref="adDnResolver2" />
<entry key="directory2_filter3" value-ref="adDnResolver3" />
<entry key="directory2_filter4" value-ref="adDnResolver4" />
</util:map>
<!-- Define two DN resolvers that use bind search against the Directory1 directory -->
<bean id="adDnResolver1" class="org.ldaptive.auth.PooledSearchDnResolver"
p:baseDn="%{idp.authn.LDAP.baseDN1}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch1:false}"
p:userFilter="%{idp.authn.LDAP.userFilter1}"
p:connectionFactory-ref="adBindSearchPooledConnectionFactory1" />
<bean id="adDnResolver2" class="org.ldaptive.auth.PooledSearchDnResolver"
p:baseDn="%{idp.authn.LDAP.baseDN2}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch2:false}"
p:userFilter="%{idp.authn.LDAP.userFilter2}"
p:connectionFactory-ref="adBindSearchPooledConnectionFactory1" />
<!-- Define two DN resolvers that use bind search against the Directory2 directory -->
<bean id="adDnResolver3" class="org.ldaptive.auth.PooledSearchDnResolver"
p:baseDn="%{idp.authn.LDAP.baseDN3}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch3:false}"
p:userFilter="%{idp.authn.LDAP.userFilter3}"
p:connectionFactory-ref="adBindSearchPooledConnectionFactory2" />
<bean id="adDnResolver4" class="org.ldaptive.auth.PooledSearchDnResolver"
p:baseDn="%{idp.authn.LDAP.baseDN4}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch4:false}"
p:userFilter="%{idp.authn.LDAP.userFilter4}"
p:connectionFactory-ref="adBindSearchPooledConnectionFactory2" />
<!-- Define Directory1 Search-pool -->
<bean id="adBindSearchPooledConnectionFactory1" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="adBindSearchConnectionPool1" />
<bean id="adBindSearchConnectionPool1" class="org.ldaptive.pool.BlockingConnectionPool"
parent="adConnectionPool1"
p:connectionFactory-ref="adBindSearchConnectionFactory1"
p:name="adSearch-pool1" />
<bean id="adBindSearchConnectionFactory1" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="adBindSearchConnectionConfig1" />
<bean id="adBindSearchConnectionConfig1"
parent="adConnectionConfig1"
p:connectionInitializer-ref="adBindConnectionInitializer1" />
<bean id="adBindConnectionInitializer1" class="org.ldaptive.BindConnectionInitializer"
p:bindDn="%{idp.authn.LDAP.bindDN1}">
<property name="bindCredential">
<bean class="org.ldaptive.Credential">
<constructor-arg value="%{idp.authn.LDAP.bindDNCredential1}" />
</bean>
</property>
</bean>
<!-- Define Directory2 Search-pool -->
<bean id="adBindSearchPooledConnectionFactory2" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="adBindSearchConnectionPool2" />
<bean id="adBindSearchConnectionPool2" class="org.ldaptive.pool.BlockingConnectionPool"
parent="adConnectionPool2"
p:connectionFactory-ref="adBindSearchConnectionFactory2"
p:name="adSearch-pool2" />
<bean id="adBindSearchConnectionFactory2" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="adBindSearchConnectionConfig2" />
<bean id="adBindSearchConnectionConfig2"
parent="adConnectionConfig2"
p:connectionInitializer-ref="adBindConnectionInitializer2" />
<bean id="adBindConnectionInitializer2" class="org.ldaptive.BindConnectionInitializer"
p:bindDn="%{idp.authn.LDAP.bindDN3}">
<property name="bindCredential">
<bean class="org.ldaptive.Credential">
<constructor-arg value="%{idp.authn.LDAP.bindDNCredential3}" />
</bean>
</property>
</bean>
<util:map id="adAuthHandlers">
<entry key="directory1_filter1" value-ref="adAuthHandler1" />
<entry key="directory1_filter2" value-ref="adAuthHandler1" />
<entry key="directory2_filter3" value-ref="adAuthHandler2" />
<entry key="directory2_filter4" value-ref="adAuthHandler2" />
</util:map>
<!-- Use the same authentication handler for both Directory1 DN resolvers -->
<bean id="adAuthHandler1" class="org.ldaptive.auth.PooledBindAuthenticationHandler"
p:connectionFactory-ref="adBindPooledConnectionFactory1" />
<bean id="adBindPooledConnectionFactory1" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="adBindConnectionPool1" />
<bean id="adBindConnectionPool1" class="org.ldaptive.pool.BlockingConnectionPool"
parent="adConnectionPool1"
p:connectionFactory-ref="adBindConnectionFactory1"
p:name="adBind-pool1" />
<bean id="adBindConnectionFactory1" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="adBindConnectionConfig1" />
<bean id="adBindConnectionConfig1"
parent="adConnectionConfig1" />
<!-- Use the same authentication handler for both Directory2 DN resolvers -->
<bean id="adAuthHandler2" class="org.ldaptive.auth.PooledBindAuthenticationHandler"
p:connectionFactory-ref="adBindPooledConnectionFactory2" />
<bean id="adBindPooledConnectionFactory2" class="org.ldaptive.pool.PooledConnectionFactory"
p:connectionPool-ref="adBindConnectionPool2" />
<bean id="adBindConnectionPool2" class="org.ldaptive.pool.BlockingConnectionPool"
parent="adConnectionPool2"
p:connectionFactory-ref="adBindConnectionFactory2"
p:name="adBind-pool2" />
<bean id="adBindConnectionFactory2" class="org.ldaptive.DefaultConnectionFactory"
p:connectionConfig-ref="adBindConnectionConfig2" />
<bean id="adBindConnectionConfig2"
parent="adConnectionConfig2" /> |
Add missing Active Directory account state errorsIf 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) password-authn-config.xml Code Block |
---|
| ...
<entry key="AccountDisabled">
<list>
<value>ACCOUNT_DISABLED</value>
<value>533</value>
</list>
</entry>
<entry key="AccountExpired">
<list>
<value>ACCOUNT_EXPIRED</value>
</list>
</entry>
<entry key="AccountLocked">
<list>
<value>ACCOUNT_LOCKED_OUT</value>
<value>775</value>
</list>
</entry>
<entry key="ChangePassword">
<list>
<value>PASSWORD_EXPIRED</value>
<value>PASSWORD_MUST_CHANGE</value>
<value>532</value>
</list>
</entry>
... |
messages/messages.properties Code Block |
---|
...
AccountDisabled = account-disabled
AccountExpired = account-expired
AccountLocked = account-locked
ChangePassword = change-password
account-disabled.message = Your account is disabled.
account-expired.message = Your account has expired.
account-locked.message = Your account is locked.
change-password.message = You must change your password before authenticating here.
... |
|