Current File(s): conf/authn/password-authn-config.xml, conf/ldap.properties, conf/authn/authn.properties
Format: Native Spring, Properties
...
Expand |
---|
|
LDAP attributes are returned as part of the authentication process and exposed in the LDAPResponseContext. (As noted in the Properties reference above, this feature is not supported by the adAuthenticator. If you set it, it will result in a WARN message in the logs for each authentication attempt.) 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 easiest way to that is to use the idp.authn.LDAP.resolveEntryWithBindDN=true property. This will configure a separate connection pool using the bind credentials. However, if the attributes you need require different credentials, then 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">
...
<bean id="bindSearchEntryResolver" class="org.ldaptive.auth.SearchEntryResolver" p:connectionFactory-ref="entryResolverPooledConnectionFactory" />
<bean id="entryResolverPooledConnectionFactory" class="org.ldaptive.PooledConnectionFactory" p:connectionConfig-ref="entryResolverConnectionConfig" p:name="entry-resolver-pool" />
<bean id="entryResolverConnectionConfig" parent="connectionConfig" p:connectionInitializers-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. |
Expand |
---|
|
Single Directory with Multiple BranchesExtensible MatchingIf your directory supports extensible matching, this is the 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 |
---|
| <!-- Connection Configuration -->
<bean id="connectionConfig" class="org.ldaptive.ConnectionConfig" abstract="true"
p:ldapUrl="%{idp.authn.LDAP.ldapURL}"
p:useStartTLS="%{idp.authn.LDAP.useStartTLS:true}"
p:connectTimeout="%{idp.authn.LDAP.connectTimeout:PT3S}"
p:responseTimeout="%{idp.authn.LDAP.responseTimeout:PT3S}"
p:sslConfig-ref="sslConfig" />
<alias name="%{idp.authn.LDAP.sslConfig:certificateTrust}" alias="sslConfig" />
<bean id="jvmTrust" class="org.ldaptive.ssl.SslConfig" />
<bean id="certificateTrust" class="org.ldaptive.ssl.SslConfig">
<property name="credentialConfig">
<bean parent="shibboleth.X509ResourceCredentialConfig" p:trustCertificates="%{idp.authn.LDAP.trustCertificates:undefined}" />
</property>
</bean>
<bean id="keyStoreTrust" class="org.ldaptive.ssl.SslConfig">
<property name="credentialConfig">
<bean parent="shibboleth.KeystoreResourceCredentialConfig" p:truststore="%{idp.authn.LDAP.trustStore:undefined}" />
</property>
</bean>
<!-- Pool Configuration -->
<bean id="connectionPool" class="org.ldaptive.PooledConnectionFactory" abstract="true"
p:blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
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:pruneStrategy-ref="pruneStrategy"
p:validator-ref="searchValidator"
p:failFastInitialize="%{idp.pool.LDAP.failFastInitialize:false}" />
<bean id="pruneStrategy" class="org.ldaptive.pool.IdlePruneStrategy"
p:prunePeriod="%{idp.pool.LDAP.prunePeriod:PT5M}"
p:idleTime="%{idp.pool.LDAP.idleTime:PT10M}" />
<bean id="searchValidator" class="org.ldaptive.SearchConnectionValidator" p:validatePeriod="%{idp.pool.LDAP.validatePeriod:PT5M}"/>
<!-- Authentication handler -->
<bean id="authHandler" class="org.ldaptive.auth.SimpleBindAuthenticationHandler" p:connectionFactory-ref="bindPooledConnectionFactory" />
<bean id="bindPooledConnectionFactory" class="org.ldaptive.PooledConnectionFactory" parent="connectionPool"
p:name="bind-pool"
p:connectionConfig-ref="bindConnectionConfig" />
<bean id="bindConnectionConfig" parent="connectionConfig" />
<!-- Anonymous Search Configuration -->
<bean name="anonSearchAuthenticator" class="org.ldaptive.auth.Authenticator" p:resolveEntryOnFailure="%{idp.authn.LDAP.resolveEntryOnFailure:false}">
<constructor-arg index="0" ref="anonSearchDnResolver" />
<constructor-arg index="1" ref="authHandler" />
</bean>
<bean id="anonSearchDnResolver" class="net.shibboleth.idp.authn.TemplateSearchDnResolver"
p:baseDn="#{'%{idp.authn.LDAP.baseDN:undefined}'.trim()}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch:false}"
p:connectionFactory-ref="anonSearchPooledConnectionFactory" >
<constructor-arg index="0" ref="shibboleth.VelocityEngine" />
<constructor-arg index="1" value="#{'%{idp.authn.LDAP.userFilter:undefined}'.trim()}" />
</bean>
<bean id="anonSearchPooledConnectionFactory" class="org.ldaptive.PooledConnectionFactory" parent="connectionPool"
p:name="search-pool"
p:connectionConfig-ref="anonSearchConnectionConfig" />
<bean id="anonSearchConnectionConfig" parent="connectionConfig" />
<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">
<util:map id="dnResolvers">
<entry key="filter1" value-ref="dnResolver1" />
<entry key="filter2" value-ref="dnResolver2" />
</util:map>
</constructor-arg>
</bean>
<bean id="aggregateAuthHandler" class="org.ldaptive.auth.AggregateAuthenticationHandler">
<constructor-arg index="0">
<!-- 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>
</constructor-arg>
</bean>
<!-- Define two DN resolvers that use anonymous search against the same directory -->
<bean id="dnResolver1" class="org.ldaptive.auth.SearchDnResolver" 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.SearchDnResolver" p:baseDn="%{idp.authn.LDAP.baseDN2}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch:false}" p:userFilter="%{idp.authn.LDAP.userFilter2}"
p:connectionFactory-ref="anonSearchPooledConnectionFactory" /> |
Add the idp.authn.LDAP.baseDN[12] and idp.authn.LDAP.userFilter[12] properties to conf/ldap.properties. 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. In addition to these beans, the aggregateAuthenticator bean (in the example above) must be injected into the LDAP credential validator in password-authn-config.xml: Code Block |
---|
<util:list id="shibboleth.authn.Password.Validators">
<!-- Default bean uses the settings defined in ldap.properties -->
<bean parent="shibboleth.LDAPValidator" p:authenticator-ref="aggregateAuthenticator" />
</util:list> |
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">
<util:map id="dnResolvers">
<entry key="directory1" value-ref="dnResolver1" />
<entry key="directory2" value-ref="dnResolver2" />
</util:map>
</constructor-arg>
</bean>
<bean id="aggregateAuthHandler" class="org.ldaptive.auth.AggregateAuthenticationHandler">
<constructor-arg index="0">
<util:map id="authHandlers">
<entry key="directory1" value-ref="authHandler1" />
<entry key="directory2" value-ref="authHandler2" />
</util:map>
</constructor-arg>
</bean>
<!-- 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" p:allowMultipleDns="true">
<constructor-arg index="0">
<util:map id="dnResolvers">
<entry key="directory1" value-ref="bindSearchDnResolver1" />
<entry key="directory2" value-ref="bindSearchDnResolver2" />
</util:map>
</constructor-arg>
</bean>
<!-- DN resolver 1 reusable PooledConnectionFactory parent bean with pool settings -->
<bean id="bindSearchDnResolver1pooledConnectionFactory" class="org.ldaptive.auth.SearchDnResolverPooledConnectionFactory"
p:baseDnblockWaitTime="#{'%{idp.authnpool.LDAP.baseDN1blockWaitTime:undefined}'.trim()}"
PT3S}"
p:pruneStrategy-ref="pruneStrategy"
p:validator-ref="searchValidator"
p:subtreeSearchfailFastInitialize="%{idp.authnpool.LDAP.subtreeSearchfailFastInitialize:false}"
p:userFilterminPoolSize="#{'%{idp.authnpool.LDAP.userFilter1:undefined}'.trim()minSize:3}"
p:connectionFactory-ref="bindSearchPooledConnectionFactory" />
<bean id="bindSearchPooledConnectionFactory1maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
p:validateOnCheckOut="%{idp.pool.LDAP.validateOnCheckout:false}"
p:validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}" />
<!-- DN resolver 1 -->
<bean id="bindSearchDnResolver1" class="net.shibboleth.idp.authn.TemplateSearchDnResolver"
p:baseDn="#{'%{idp.authn.LDAP1.baseDN:undefined}'.trim()}"
p:subtreeSearch="%{idp.authn.LDAP1.subtreeSearch:false}"
p:connectionFactory-ref="bindSearchPooledConnectionFactory1" >
<constructor-arg index="0" ref="shibboleth.VelocityEngine" />
<constructor-arg index="1" value="#{'%{idp.authn.LDAP1.userFilter:undefined}'.trim()}" />
</bean>
<bean id="bindSearchPooledConnectionFactory1" parent="pooledConnectionFactory"
p:connectionConfig-ref="bindSearchConnectionConfig1" />
<bean id="bindSearchConnectionConfig1" parent="connectionConfig1" p:connectionInitializers-ref="bindConnectionInitializer1" />
<bean id="bindConnectionInitializer1" class="org.ldaptive.BindConnectionInitializer"
p:bindDn="#{'%{idp.authn.LDAP1.bindDN:undefined}'.trim()}">
<property name="bindCredential">
<bean class="org.ldaptive.Credential">
<constructor-arg value="%{idp.authn.LDAP1.bindDNCredential:undefined}" />
</bean>
</property>
</bean>
<bean id="connectionConfig1" class="org.ldaptive.PooledConnectionFactory" parent="connectionPool"
.ConnectionConfig" abstract="true" p:ldapUrl="%{idp.authn.LDAP1.ldapURL}"
p:useStartTLS="%{idp.authn.LDAP1.useStartTLS:true}"
p:connectTimeout="%{idp.authn.LDAP.connectTimeout:PT3S}"
p:responseTimeout="%{idp.authn.LDAP.responseTimeout:PT3S}"
p:namesslConfig-ref="search-pool1sslConfig" />
<!-- DN resolver 2 p:connectionConfig-ref="bindSearchConnectionConfig1" /-->
<bean id="bindSearchConnectionConfig1bindSearchDnResolver2" parentclass="connectionConfig"
net.shibboleth.idp.authn.TemplateSearchDnResolver"
p:connectionInitializers-ref="bindConnectionInitializer1"
baseDn="#{'%{idp.authn.LDAP2.baseDN:undefined}'.trim()}"
p:ldapUrlsubtreeSearch="%{idp.authn.LDAPLDAP2.ldapURL1subtreeSearch:false}" />
<bean id="bindConnectionInitializer1" class="org.ldaptive.BindConnectionInitializer"
p:connectionFactory-ref="bindSearchPooledConnectionFactory2" >
<constructor-arg index="0" ref="shibboleth.VelocityEngine" />
<constructor-arg p:bindDnindex="1" value="#{'%{idp.authn.LDAPLDAP2.bindDN1userFilter:undefined}'.trim()}" />
</bean>
<bean <property nameid="bindSearchPooledConnectionFactory2" parent="bindCredentialpooledConnectionFactory">
<bean class="org.ldaptive.Credential" c:password="%{idp.authn.LDAP.bindDNCredential1:undefined}p:connectionConfig-ref="bindSearchConnectionConfig2" />
<bean </property>
</bean>
<!-- DN resolver 2 --id="bindSearchConnectionConfig2" parent="connectionConfig2" p:connectionInitializers-ref="bindConnectionInitializer2" />
<bean id="bindSearchDnResolver2bindConnectionInitializer2" class="org.ldaptive.auth.SearchDnResolverBindConnectionInitializer"
p:baseDnbindDn="#{'%{idp.authn.LDAPLDAP2.baseDN2bindDN:undefined}'.trim()}">
<property name="bindCredential">
<bean p:subtreeSearchclass="%{idporg.authn.LDAP.subtreeSearch:false}"ldaptive.Credential">
p:userFilter <constructor-arg value="#{'%{idp.authn.LDAPLDAP2.userFilter2bindDNCredential:undefined}'.trim()}"" />
p:connectionFactory-ref="bindSearchPooledConnectionFactory" /></bean>
</property>
</bean>
<bean id="bindSearchPooledConnectionFactory2connectionConfig2" class="org.ldaptive.PooledConnectionFactoryConnectionConfig" parentabstract="connectionPooltrue"
p:nameldapUrl="search-pool2"
%{idp.authn.LDAP2.ldapURL}"
p:connectionConfig-refuseStartTLS="bindSearchConnectionConfig2%{idp.authn.LDAP2.useStartTLS:true}"
/> <bean id="bindSearchConnectionConfig2" parent="connectionConfig"
p:connectionInitializers-refconnectTimeout="bindConnectionInitializer2"
%{idp.authn.LDAP.connectTimeout:PT3S}"
p:ldapUrlresponseTimeout="%{idp.authn.LDAP.ldapURL2}responseTimeout:PT3S}"
p:sslConfig-ref="sslConfig" />
<!-- Aggregate authentication -->
<bean id="bindConnectionInitializer2aggregateAuthHandler" class="org.ldaptive.auth.BindConnectionInitializerAggregateAuthenticationHandler">
<constructor-arg index="0">
p<util:bindDn="#{'%{idp.authn.LDAP.bindDN2:undefined}'.trim()}">
<property name="bindCredential"map id="authHandlers">
<entry key="directory1" value-ref="authHandler1" />
<bean <entry classkey="org.ldaptive.Credential" c:password="%{idp.authn.LDAP.bindDNCredential2:undefined}directory2" value-ref="authHandler2" />
</util:map>
</property>constructor-arg>
</bean>
<!-- Authentication Aggregatehandler authentication1 -->
<bean id="aggregateAuthHandlerauthHandler1" class="org.ldaptive.auth.AggregateAuthenticationHandlerSimpleBindAuthenticationHandler">
<constructor-arg index="0">
<util:map id="authHandlers">
<entry key="directory1" value-ref="authHandler1 p:connectionFactory-ref="bindPooledConnectionFactory1" />
<bean id="bindPooledConnectionFactory1" parent="pooledConnectionFactory" p:connectionConfig-ref="bindConnectionConfig1" />
<bean id="bindConnectionConfig1" parent="connectionConfig1" />
<!-- Authentication handler 2 -->
<bean id="authHandler2" class="org.ldaptive.auth.SimpleBindAuthenticationHandler" p:connectionFactory-ref="bindPooledConnectionFactory2" />
<bean <entry key="directory2" valueid="bindPooledConnectionFactory2" parent="pooledConnectionFactory" p:connectionConfig-ref="authHandler2bindConnectionConfig2" />
<bean id="bindConnectionConfig2" parent="connectionConfig2" </util:map>>
</constructor!--arg> </bean>shared definitions <!-->
Authentication handler 1 -->
<alias name="%{idp.authn.LDAP.sslConfig:certificateTrust}" alias="sslConfig" />
<bean id="authHandler1jvmTrust" class="org.ldaptive.auth.SimpleBindAuthenticationHandler"
p:connectionFactory-ref="bindPooledConnectionFactory1ssl.SslConfig" />
<bean id="bindPooledConnectionFactory1certificateTrust" class="org.ldaptive.PooledConnectionFactoryssl.SslConfig">
parent="connectionPool" <property p:name="bind-pool1credentialConfig">
<bean parent="shibboleth.X509ResourceCredentialConfig" p:connectionConfig-reftrustCertificates="bindConnectionConfig1%{idp.authn.LDAP.trustCertificates:undefined}" />
</property>
</bean>
<bean id="bindConnectionConfig1keyStoreTrust" parentclass="connectionConfig"org.ldaptive.ssl.SslConfig">
<property p:ldapUrlname="%{idp.authn.LDAP.ldapURL1}" />
<!-- Authentication handler 2 -->
<bean id="authHandler2" class="org.ldaptive.auth.SimpleBindAuthenticationHandler"
credentialConfig">
<bean parent="shibboleth.KeystoreResourceCredentialConfig" p:truststore="%{idp.authn.LDAP.trustStore:undefined}" />
p:connectionFactory-ref="bindPooledConnectionFactory2" /></property>
</bean>
<bean id="bindPooledConnectionFactory2pruneStrategy" class="org.ldaptive.PooledConnectionFactory" parent="connectionPool.pool.IdlePruneStrategy"
p:nameprunePeriod="bind-pool2"
%{idp.pool.LDAP.prunePeriod:PT5M}"
p:connectionConfig-refidleTime="bindConnectionConfig2%{idp.pool.LDAP.idleTime:PT10M}" />
<bean id="bindConnectionConfig2searchValidator" parentclass="connectionConfigorg.ldaptive.SearchConnectionValidator"
p:ldapUrlvalidatePeriod="%{idp.authnpool.LDAP.ldapURL2validatePeriod:PT5M}" /> |
DN resolvers are invoked asynchronously, so all resolvers will be used for each authentication request. |
...