Skip to content

Instantly share code, notes, and snippets.

@SpComb
Last active December 20, 2018 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SpComb/b290113a3cd2359e14e28f004db92913 to your computer and use it in GitHub Desktop.
Save SpComb/b290113a3cd2359e14e28f004db92913 to your computer and use it in GitHub Desktop.
Shibboleth IDP 3.4 custom LDAP authentication XML for AD return attributes

The default idp.authn.LDAP.authenticator=adAuthenticator with idp.authn.LDAP.dnFormat=%s fails to resolve the LDAP entry or return any attributes, because it incorrectly uses the user@domain principal as a base DN for the search:

2018-12-20 11:09:07,543 - 127.0.0.1 - DEBUG [org.ldaptive.auth.SearchEntryResolver:415] - resolve criteria=[org.ldaptive.auth.AuthenticationCriteria@889474363::dn=user@example.com, authenticationRequest=[org.ldaptive.auth.AuthenticationRequest@2125852170::user=[org.ldaptive.auth.User@1891586491::identifier=user@example.com, context=org.apache.velocity.VelocityContext@1bbd991a], retAttrs=[cn, userPrincipalName, mail], controls=null]]
2018-12-20 11:09:07,544 - 127.0.0.1 - DEBUG [org.ldaptive.SearchOperation:138] - execute request=[org.ldaptive.SearchRequest@-1882291035::baseDn=user@example.com, searchFilter=[org.ldaptive.SearchFilter@1642584434::filter=(objectClass=*), parameters={}], returnAttributes=[cn, userPrincipalName, mail], searchScope=OBJECT, timeLimit=0, sizeLimit=0, derefAliases=null, typesOnly=false, binaryAttributes=null, sortBehavior=UNORDERED, searchEntryHandlers=null, searchReferenceHandlers=null, controls=null, followReferrals=false, intermediateResponseHandlers=null] with connection=[org.ldaptive.DefaultConnectionFactory$DefaultConnection@217658279::config=[org.ldaptive.ConnectionConfig@274532411::ldapUrl=ldap://localhost, connectTimeout=3000, responseTimeout=3000, sslConfig=[org.ldaptive.ssl.SslConfig@1291623111::credentialConfig=net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig@36c8248f, trustManagers=null, hostnameVerifier=null, hostnameVerifierConfig=null, enabledCipherSuites=null, enabledProtocols=null, handshakeCompletedListeners=null], useSSL=false, useStartTLS=false, connectionInitializer=null], providerConnectionFactory=[org.ldaptive.provider.jndi.JndiConnectionFactory@653082835::metadata=[ldapUrl=ldap://localhost, count=1], environment={com.sun.jndi.ldap.connect.timeout=3000, java.naming.ldap.version=3, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.read.timeout=3000}, providerConfig=[org.ldaptive.provider.jndi.JndiProviderConfig@712778254::operationExceptionResultCodes=[PROTOCOL_ERROR, SERVER_DOWN], properties={}, connectionStrategy=org.ldaptive.provider.ConnectionStrategies$DefaultConnectionStrategy@4469bc70, controlProcessor=org.ldaptive.provider.ControlProcessor@568a7985, environment=null, tracePackets=null, removeDnUrls=true, searchIgnoreResultCodes=[TIME_LIMIT_EXCEEDED, SIZE_LIMIT_EXCEEDED, PARTIAL_RESULTS], sslSocketFactory=null, hostnameVerifier=null]], providerConnection=org.ldaptive.provider.jndi.JndiConnection@1a2d505f]
2018-12-20 11:09:07,558 - 127.0.0.1 - DEBUG [org.ldaptive.provider.jndi.NamingExceptionUtils:358] - naming exception class javax.naming.InvalidNameException is ambiguous, maps to multiple result codes: [INVALID_DN_SYNTAX, NAMING_VIOLATION]
2018-12-20 11:09:07,561 - 127.0.0.1 - DEBUG [org.ldaptive.auth.Authenticator:469] - entry resolution failed for resolver=[org.ldaptive.auth.SearchEntryResolver@1351280079::factory=null, baseDn=, userFilter=null, userFilterParameters=null, allowMultipleEntries=false, subtreeSearch=false, derefAliases=null, followReferrals=false, searchEntryHandlers=null]
org.ldaptive.LdapException: javax.naming.InvalidNameException: user@example.com: [LDAP: error code 34 - 0000208F: NameErr: DSID-03100225, problem 2006 (BAD_NAME), data 8350, best match of:
    'user@example.com'
]; remaining name 'user@example.com'
    at org.ldaptive.provider.ProviderUtils.throwOperationException(ProviderUtils.java:77)
Caused by: javax.naming.InvalidNameException: user@example.com: [LDAP: error code 34 - 0000208F: NameErr: DSID-03100225, problem 2006 (BAD_NAME), data 8350, best match of:
    'user@example.com'
]
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3093)

This custom entryResolver uses the authenticated LDAP connection to search for the user entry based on a configurable filter instead, correctly returning the user entry and any return attributes.

2018-12-20 12:14:18,282 - 127.0.0.1 - DEBUG [org.ldaptive.auth.FormatDnResolver:176] - Formatting DN for user@example.com with %s
2018-12-20 12:14:18,283 - 127.0.0.1 - DEBUG [org.ldaptive.auth.Authenticator:285] - authenticate dn=user@example.com with request=[org.ldaptive.auth.AuthenticationRequest@327262862::user=[org.ldaptive.auth.User@1579013448::identifier=user@example.com, context=org.apache.velocity.VelocityContext@4ac97401], retAttrs=[cn, userPrincipalName, mail], controls=null]
2018-12-20 12:14:18,285 - 127.0.0.1 - DEBUG [org.ldaptive.auth.PooledBindAuthenticationHandler:68] - authenticate criteria=[org.ldaptive.auth.AuthenticationCriteria@1139872637::dn=user@example.com, authenticationRequest=[org.ldaptive.auth.AuthenticationRequest@327262862::user=[org.ldaptive.auth.User@1579013448::identifier=user@example.com, context=org.apache.velocity.VelocityContext@4ac97401], retAttrs=[cn, userPrincipalName, mail], controls=null]]
2018-12-20 12:14:18,286 - 127.0.0.1 - DEBUG [org.ldaptive.BindOperation:138] - execute request=[org.ldaptive.BindRequest@1576684639::bindDn=user@example.com, saslConfig=null, controls=null] with connection=[org.ldaptive.DefaultConnectionFactory$DefaultConnection@104517785::config=[org.ldaptive.ConnectionConfig@1530764635::ldapUrl=ldap://localhost, connectTimeout=3000, responseTimeout=3000, sslConfig=[org.ldaptive.ssl.SslConfig@55970400::credentialConfig=net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig@394b16ee, trustManagers=null, hostnameVerifier=null, hostnameVerifierConfig=null, enabledCipherSuites=null, enabledProtocols=null, handshakeCompletedListeners=null], useSSL=false, useStartTLS=false, connectionInitializer=null], providerConnectionFactory=[org.ldaptive.provider.jndi.JndiConnectionFactory@1423692956::metadata=[ldapUrl=ldap://localhost, count=1], environment={com.sun.jndi.ldap.connect.timeout=3000, java.naming.ldap.version=3, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.read.timeout=3000}, providerConfig=[org.ldaptive.provider.jndi.JndiProviderConfig@1493333664::operationExceptionResultCodes=[PROTOCOL_ERROR, SERVER_DOWN], properties={}, connectionStrategy=org.ldaptive.provider.ConnectionStrategies$DefaultConnectionStrategy@2f68af46, controlProcessor=org.ldaptive.provider.ControlProcessor@3139d30d, environment=null, tracePackets=null, removeDnUrls=true, searchIgnoreResultCodes=[TIME_LIMIT_EXCEEDED, SIZE_LIMIT_EXCEEDED, PARTIAL_RESULTS], sslSocketFactory=null, hostnameVerifier=null]], providerConnection=org.ldaptive.provider.jndi.JndiConnection@3bcc9e82]
2018-12-20 12:14:18,295 - 127.0.0.1 - DEBUG [org.ldaptive.BindOperation:168] - execute response=[org.ldaptive.Response@657781243::result=null, resultCode=SUCCESS, message=null, matchedDn=null, responseControls=null, referralURLs=null, messageId=-1] for request=[org.ldaptive.BindRequest@1576684639::bindDn=user@example.com, saslConfig=null, controls=null] with connection=[org.ldaptive.DefaultConnectionFactory$DefaultConnection@104517785::config=[org.ldaptive.ConnectionConfig@1530764635::ldapUrl=ldap://localhost, connectTimeout=3000, responseTimeout=3000, sslConfig=[org.ldaptive.ssl.SslConfig@55970400::credentialConfig=net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig@394b16ee, trustManagers=null, hostnameVerifier=null, hostnameVerifierConfig=null, enabledCipherSuites=null, enabledProtocols=null, handshakeCompletedListeners=null], useSSL=false, useStartTLS=false, connectionInitializer=null], providerConnectionFactory=[org.ldaptive.provider.jndi.JndiConnectionFactory@1423692956::metadata=[ldapUrl=ldap://localhost, count=1], environment={com.sun.jndi.ldap.connect.timeout=3000, java.naming.ldap.version=3, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.read.timeout=3000}, providerConfig=[org.ldaptive.provider.jndi.JndiProviderConfig@1493333664::operationExceptionResultCodes=[PROTOCOL_ERROR, SERVER_DOWN], properties={}, connectionStrategy=org.ldaptive.provider.ConnectionStrategies$DefaultConnectionStrategy@2f68af46, controlProcessor=org.ldaptive.provider.ControlProcessor@3139d30d, environment=null, tracePackets=null, removeDnUrls=true, searchIgnoreResultCodes=[TIME_LIMIT_EXCEEDED, SIZE_LIMIT_EXCEEDED, PARTIAL_RESULTS], sslSocketFactory=null, hostnameVerifier=null]], providerConnection=org.ldaptive.provider.jndi.JndiConnection@3bcc9e82]
2018-12-20 12:14:18,296 - 127.0.0.1 - DEBUG [org.ldaptive.auth.PooledBindAuthenticationHandler:86] - authenticate response=[org.ldaptive.auth.AuthenticationHandlerResponse@673438198::connection=[org.ldaptive.DefaultConnectionFactory$DefaultConnection@104517785::config=[org.ldaptive.ConnectionConfig@1530764635::ldapUrl=ldap://localhost, connectTimeout=3000, responseTimeout=3000, sslConfig=[org.ldaptive.ssl.SslConfig@55970400::credentialConfig=net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig@394b16ee, trustManagers=null, hostnameVerifier=null, hostnameVerifierConfig=null, enabledCipherSuites=null, enabledProtocols=null, handshakeCompletedListeners=null], useSSL=false, useStartTLS=false, connectionInitializer=null], providerConnectionFactory=[org.ldaptive.provider.jndi.JndiConnectionFactory@1423692956::metadata=[ldapUrl=ldap://localhost, count=1], environment={com.sun.jndi.ldap.connect.timeout=3000, java.naming.ldap.version=3, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.read.timeout=3000}, providerConfig=[org.ldaptive.provider.jndi.JndiProviderConfig@1493333664::operationExceptionResultCodes=[PROTOCOL_ERROR, SERVER_DOWN], properties={}, connectionStrategy=org.ldaptive.provider.ConnectionStrategies$DefaultConnectionStrategy@2f68af46, controlProcessor=org.ldaptive.provider.ControlProcessor@3139d30d, environment=null, tracePackets=null, removeDnUrls=true, searchIgnoreResultCodes=[TIME_LIMIT_EXCEEDED, SIZE_LIMIT_EXCEEDED, PARTIAL_RESULTS], sslSocketFactory=null, hostnameVerifier=null]], providerConnection=org.ldaptive.provider.jndi.JndiConnection@3bcc9e82], result=true, resultCode=SUCCESS, message=null, controls=null] for criteria=[org.ldaptive.auth.AuthenticationCriteria@1139872637::dn=user@example.com, authenticationRequest=[org.ldaptive.auth.AuthenticationRequest@327262862::user=[org.ldaptive.auth.User@1579013448::identifier=user@example.com, context=org.apache.velocity.VelocityContext@4ac97401], retAttrs=[cn, userPrincipalName, mail], controls=null]]
2018-12-20 12:14:18,297 - 127.0.0.1 - DEBUG [org.ldaptive.auth.SearchEntryResolver:415] - resolve criteria=[org.ldaptive.auth.AuthenticationCriteria@1139872637::dn=user@example.com, authenticationRequest=[org.ldaptive.auth.AuthenticationRequest@327262862::user=[org.ldaptive.auth.User@1579013448::identifier=user@example.com, context=org.apache.velocity.VelocityContext@4ac97401], retAttrs=[cn, userPrincipalName, mail], controls=null]]
2018-12-20 12:14:18,298 - 127.0.0.1 - DEBUG [org.ldaptive.auth.SearchEntryResolver:318] - searching for entry using userFilter
2018-12-20 12:14:18,299 - 127.0.0.1 - DEBUG [org.ldaptive.SearchOperation:138] - execute request=[org.ldaptive.SearchRequest@478362943::baseDn=OU=Examples,DC=example,DC=com, searchFilter=[org.ldaptive.SearchFilter@369197871::filter=(userPrincipalName={user}), parameters={dn=user@example.com, user=user@example.com}], returnAttributes=[cn, userPrincipalName, mail], searchScope=SUBTREE, timeLimit=0, sizeLimit=0, derefAliases=null, typesOnly=false, binaryAttributes=null, sortBehavior=UNORDERED, searchEntryHandlers=null, searchReferenceHandlers=null, controls=null, followReferrals=false, intermediateResponseHandlers=null] with connection=[org.ldaptive.DefaultConnectionFactory$DefaultConnection@104517785::config=[org.ldaptive.ConnectionConfig@1530764635::ldapUrl=ldap://localhost, connectTimeout=3000, responseTimeout=3000, sslConfig=[org.ldaptive.ssl.SslConfig@55970400::credentialConfig=net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig@394b16ee, trustManagers=null, hostnameVerifier=null, hostnameVerifierConfig=null, enabledCipherSuites=null, enabledProtocols=null, handshakeCompletedListeners=null], useSSL=false, useStartTLS=false, connectionInitializer=null], providerConnectionFactory=[org.ldaptive.provider.jndi.JndiConnectionFactory@1423692956::metadata=[ldapUrl=ldap://localhost, count=1], environment={com.sun.jndi.ldap.connect.timeout=3000, java.naming.ldap.version=3, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.read.timeout=3000}, providerConfig=[org.ldaptive.provider.jndi.JndiProviderConfig@1493333664::operationExceptionResultCodes=[PROTOCOL_ERROR, SERVER_DOWN], properties={}, connectionStrategy=org.ldaptive.provider.ConnectionStrategies$DefaultConnectionStrategy@2f68af46, controlProcessor=org.ldaptive.provider.ControlProcessor@3139d30d, environment=null, tracePackets=null, removeDnUrls=true, searchIgnoreResultCodes=[TIME_LIMIT_EXCEEDED, SIZE_LIMIT_EXCEEDED, PARTIAL_RESULTS], sslSocketFactory=null, hostnameVerifier=null]], providerConnection=org.ldaptive.provider.jndi.JndiConnection@3bcc9e82]
2018-12-20 12:14:18,326 - 127.0.0.1 - DEBUG [org.ldaptive.SearchOperation:168] - execute response=[org.ldaptive.Response@65005203::result=[org.ldaptive.SearchResult@1303241389::entries=[[dn=CN=Example User,OU=Staff,OU=Examples,DC=example,DC=com[[userPrincipalName[user@example.com]], [mail[user@example.com]], [cn[Example User]]], responseControls=null, messageId=-1]], references=[]], resultCode=SUCCESS, message=null, matchedDn=null, responseControls=null, referralURLs=null, messageId=-1] for request=[org.ldaptive.SearchRequest@478362943::baseDn=OU=Examples,DC=example,DC=com, searchFilter=[org.ldaptive.SearchFilter@369197871::filter=(userPrincipalName={user}), parameters={dn=user@example.com, user=user@example.com}], returnAttributes=[cn, userPrincipalName, mail], searchScope=SUBTREE, timeLimit=0, sizeLimit=0, derefAliases=null, typesOnly=false, binaryAttributes=null, sortBehavior=UNORDERED, searchEntryHandlers=null, searchReferenceHandlers=null, controls=null, followReferrals=false, intermediateResponseHandlers=null] with connection=[org.ldaptive.DefaultConnectionFactory$DefaultConnection@104517785::config=[org.ldaptive.ConnectionConfig@1530764635::ldapUrl=ldap://localhost, connectTimeout=3000, responseTimeout=3000, sslConfig=[org.ldaptive.ssl.SslConfig@55970400::credentialConfig=net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig@394b16ee, trustManagers=null, hostnameVerifier=null, hostnameVerifierConfig=null, enabledCipherSuites=null, enabledProtocols=null, handshakeCompletedListeners=null], useSSL=false, useStartTLS=false, connectionInitializer=null], providerConnectionFactory=[org.ldaptive.provider.jndi.JndiConnectionFactory@1423692956::metadata=[ldapUrl=ldap://localhost, count=1], environment={com.sun.jndi.ldap.connect.timeout=3000, java.naming.ldap.version=3, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.read.timeout=3000}, providerConfig=[org.ldaptive.provider.jndi.JndiProviderConfig@1493333664::operationExceptionResultCodes=[PROTOCOL_ERROR, SERVER_DOWN], properties={}, connectionStrategy=org.ldaptive.provider.ConnectionStrategies$DefaultConnectionStrategy@2f68af46, controlProcessor=org.ldaptive.provider.ControlProcessor@3139d30d, environment=null, tracePackets=null, removeDnUrls=true, searchIgnoreResultCodes=[TIME_LIMIT_EXCEEDED, SIZE_LIMIT_EXCEEDED, PARTIAL_RESULTS], sslSocketFactory=null, hostnameVerifier=null]], providerConnection=org.ldaptive.provider.jndi.JndiConnection@3bcc9e82]
2018-12-20 12:14:18,328 - 127.0.0.1 - DEBUG [org.ldaptive.auth.SearchEntryResolver:418] - resolved result=[org.ldaptive.SearchResult@1303241389::entries=[[dn=CN=Example User,OU=Staff,OU=Examples,DC=example,DC=com[[userPrincipalName[user@example.com]], [mail[user@example.com]], [cn[Example User]]], responseControls=null, messageId=-1]], references=[]] for criteria=[org.ldaptive.auth.AuthenticationCriteria@1139872637::dn=user@example.com, authenticationRequest=[org.ldaptive.auth.AuthenticationRequest@327262862::user=[org.ldaptive.auth.User@1579013448::identifier=user@example.com, context=org.apache.velocity.VelocityContext@4ac97401], retAttrs=[cn, userPrincipalName, mail], controls=null]]
2018-12-20 12:14:18,328 - 127.0.0.1 - INFO [org.ldaptive.auth.Authenticator:311] - Authentication succeeded for dn: user@example.com
2018-12-20 12:14:18,329 - 127.0.0.1 - DEBUG [org.ldaptive.auth.Authenticator:336] - authenticate response=[org.ldaptive.auth.AuthenticationHandlerResponse@673438198::connection=[org.ldaptive.DefaultConnectionFactory$DefaultConnection@104517785::config=[org.ldaptive.ConnectionConfig@1530764635::ldapUrl=ldap://localhost, connectTimeout=3000, responseTimeout=3000, sslConfig=[org.ldaptive.ssl.SslConfig@55970400::credentialConfig=net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig@394b16ee, trustManagers=null, hostnameVerifier=null, hostnameVerifierConfig=null, enabledCipherSuites=null, enabledProtocols=null, handshakeCompletedListeners=null], useSSL=false, useStartTLS=false, connectionInitializer=null], providerConnectionFactory=[org.ldaptive.provider.jndi.JndiConnectionFactory@1423692956::metadata=[ldapUrl=ldap://localhost, count=1], environment={com.sun.jndi.ldap.connect.timeout=3000, java.naming.ldap.version=3, java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory, com.sun.jndi.ldap.read.timeout=3000}, providerConfig=[org.ldaptive.provider.jndi.JndiProviderConfig@1493333664::operationExceptionResultCodes=[PROTOCOL_ERROR, SERVER_DOWN], properties={}, connectionStrategy=org.ldaptive.provider.ConnectionStrategies$DefaultConnectionStrategy@2f68af46, controlProcessor=org.ldaptive.provider.ControlProcessor@3139d30d, environment=null, tracePackets=null, removeDnUrls=true, searchIgnoreResultCodes=[TIME_LIMIT_EXCEEDED, SIZE_LIMIT_EXCEEDED, PARTIAL_RESULTS], sslSocketFactory=null, hostnameVerifier=null]], providerConnection=org.ldaptive.provider.jndi.JndiConnection@3bcc9e82], result=true, resultCode=SUCCESS, message=null, controls=null] for dn=user@example.com with request=[org.ldaptive.auth.AuthenticationRequest@327262862::user=[org.ldaptive.auth.User@1579013448::identifier=user@example.com, context=org.apache.velocity.VelocityContext@4ac97401], retAttrs=[cn, userPrincipalName, mail], controls=null]
<!-- Active Directory Configuration -->
<bean id="adSearchDnResolver" class="org.ldaptive.auth.SearchEntryResolver"
p:baseDn="#{'%{idp.authn.LDAP.baseDN:undefined}'.trim()}"
p:subtreeSearch="%{idp.authn.LDAP.subtreeSearch:false}"
p:userFilter="#{'%{idp.authn.LDAP.userFilter:undefined}'.trim()}">
</bean>
<bean id="adAuthenticator" class="org.ldaptive.auth.Authenticator" p:authenticationResponseHandlers-ref="authenticationResponseHandler"
p:resolveEntryOnFailure="%{idp.authn.LDAP.resolveEntryOnFailure:false}"
p:entryResolver-ref="adSearchDnResolver">
<constructor-arg index="0" ref="formatDnResolver" />
<constructor-arg index="1" ref="authHandler" />
</bean>
<bean id="authenticationResponseHandler" class="org.ldaptive.auth.ext.ActiveDirectoryAuthenticationResponseHandler" />
idp.authn.LDAP.authenticator = adAuthenticator
## Connection properties ##
idp.authn.LDAP.ldapURL = ldap://localhost
idp.authn.LDAP.useStartTLS = false
idp.authn.LDAP.useSSL = false
## Return attributes during authentication
idp.authn.LDAP.returnAttributes = cn,userPrincipalName,mail
## DN resolution properties ##
# Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator
# for AD: CN=Users,DC=example,DC=org
idp.authn.LDAP.baseDN = OU=Examples,DC=example,DC=com
idp.authn.LDAP.subtreeSearch = true
idp.authn.LDAP.userFilter = (userPrincipalName={user})
# Format DN resolution, used by directAuthenticator, adAuthenticator
# for AD use idp.authn.LDAP.dnFormat=%s@domain.com
idp.authn.LDAP.dnFormat = %s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment