]
Chao Wang updated ELY-1851:
---------------------------
    Git Pull Request: 
 Elytron ldaps realm fails if a referral is returned inside a search
 -------------------------------------------------------------------
                 Key: ELY-1851
                 URL: 
https://issues.redhat.com/browse/ELY-1851
             Project: WildFly Elytron
          Issue Type: Bug
    Affects Versions: 1.6.3.Final, 1.10.8.Final
            Reporter: Chao Wang
            Assignee: Chao Wang
            Priority: Major
 Elytron LdapRealm fails to follow a referral when ldaps is used (the
{{ThreadLocalSSLSocketFactory}} is not set).
 With a configuration similar to this one ({{memberOf}} is used to locate groups):
 {code:xml}
 <ldap-realm name="ldap-realm" dir-context="ldap-dir-context"
direct-verification="true">
      <identity-mapping rdn-identifier="sAMAccountName"
use-recursive-search="true" search-base-dn="DC=redhat,DC=com">
         <attribute-mapping>
             <attribute reference="memberOf" from="cn"
to="Roles" role-recursion="3"/>
         </attribute-mapping>
     </identity-mapping>
 </ldap-realm>
 ...
 <dir-context name="ldap-dir-context"
url="ldaps://ldap.redhat.com:636"
principal="cn=Administrator,cn=Users,DC=redhat,DC=com"
referral-mode="FOLLOW" ssl-context="ldaps-context">
     <credential-reference store="credstore"
alias="ldap_password"/>
 </dir-context>
 {code}
 If we have a group (or user) which contains a {{memberOf}} of another ldap, something
like the following:
 {noformat}
 dn: CN=group-with-external-members,OU=Groups,DC=redhat,DC=com
 ...
 memberOf: CN=group-in-another-domain,OU=Groups,DC=lab,DC=redhat,DC=com
 {noformat}
 The following exception is thrown when a referral is returned for a group that is inside
another ldapserver of the forest:
 {noformat}
 TRACE [org.jboss.remoting.remote.server] (management task-1) Server sending
authentication rejected: java.lang.RuntimeException: ELY01079: ldap-realm realm failed to
obtain attributes for entry [CN=group-with-external-members,OU=Groups,DC=redhat,DC=com]
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.extractFilteredAttributesFromSearch(LdapSecurityRealm.java:808)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.lambda$null$4(LdapSecurityRealm.java:768)
     at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
     at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
     at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
     at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
     at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
     at
java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
     at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
     at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.forEachAttributeValue(LdapSecurityRealm.java:841)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.lambda$extractFilteredAttributes$6(LdapSecurityRealm.java:766)
     at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1321)
     at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
     at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
     at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
     at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
     at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
     at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
     at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.extractAttributes(LdapSecurityRealm.java:828)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.extractFilteredAttributes(LdapSecurityRealm.java:754)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.getAttributes(LdapSecurityRealm.java:516)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.getAuthorizationIdentity(LdapSecurityRealm.java:497)
     at
org.wildfly.security.auth.server.ServerAuthenticationContext$NameAssignedState.doAuthorization(ServerAuthenticationContext.java:1923)
     at
org.wildfly.security.auth.server.ServerAuthenticationContext$NameAssignedState.authorize(ServerAuthenticationContext.java:1952)
     at
org.wildfly.security.auth.server.ServerAuthenticationContext.authorize(ServerAuthenticationContext.java:509)
     at
org.wildfly.security.auth.server.ServerAuthenticationContext.authorize(ServerAuthenticationContext.java:489)
     at
org.wildfly.security.auth.server.ServerAuthenticationContext$1.handleOne(ServerAuthenticationContext.java:872)
     at
org.wildfly.security.auth.server.ServerAuthenticationContext$1.handle(ServerAuthenticationContext.java:839)
     at
org.wildfly.security.sasl.util.SSLQueryCallbackHandler.handle(SSLQueryCallbackHandler.java:60)
     at
org.wildfly.security.sasl.util.TrustManagerSaslServerFactory.lambda$createSaslServer$0(TrustManagerSaslServerFactory.java:96)
     at
org.wildfly.security.sasl.plain.PlainSaslServer.evaluateResponse(PlainSaslServer.java:146)
     at
org.wildfly.security.sasl.util.AuthenticationCompleteCallbackSaslServerFactory$1.evaluateResponse(AuthenticationCompleteCallbackSaslServerFactory.java:58)
     at
org.wildfly.security.sasl.util.AuthenticationTimeoutSaslServerFactory$DelegatingTimeoutSaslServer.evaluateResponse(AuthenticationTimeoutSaslServerFactory.java:106)
     at
org.wildfly.security.sasl.util.SecurityIdentitySaslServerFactory$1.evaluateResponse(SecurityIdentitySaslServerFactory.java:59)
     at org.xnio.sasl.SaslUtils.evaluateResponse(SaslUtils.java:245)
     at org.xnio.sasl.SaslUtils.evaluateResponse(SaslUtils.java:217)
     at
org.jboss.remoting3.remote.ServerConnectionOpenListener$AuthStepRunnable.run(ServerConnectionOpenListener.java:486)
     at
org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:942)
     at
org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
     at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
     at
org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
     at
org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
     at java.lang.Thread.run(Thread.java:748)
 Caused by: org.wildfly.security.auth.server.RealmUnavailableException: ELY01108:
ldap-realm realm identity search failed
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapSearch.search(LdapSecurityRealm.java:1141)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapRealmIdentity.extractFilteredAttributesFromSearch(LdapSecurityRealm.java:797)
     ... 46 more
 Caused by: javax.naming.CommunicationException: ldap.lab.redhat.com:636 [Root exception
is java.lang.IllegalStateException: ELY04025: DirContext tries to connect without
ThreadLocalSSLSocketFactory thread local setting]
     at com.sun.jndi.ldap.LdapReferralContext.<init>(LdapReferralContext.java:96)
     at
com.sun.jndi.ldap.LdapReferralException.getReferralContext(LdapReferralException.java:151)
     at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1861)
     at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1769)
     at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1786)
     at
com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:418)
     at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:396)
     at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:297)
     at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:297)
     at
org.wildfly.security.auth.realm.ldap.DelegatingLdapContext.search(DelegatingLdapContext.java:335)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapSearch.searchWithPagination(LdapSecurityRealm.java:1161)
     at
org.wildfly.security.auth.realm.ldap.LdapSecurityRealm$LdapSearch.search(LdapSecurityRealm.java:1038)
     ... 47 more
 Caused by: java.lang.IllegalStateException: ELY04025: DirContext tries to connect without
ThreadLocalSSLSocketFactory thread local setting
     at
org.wildfly.security.auth.realm.ldap.ThreadLocalSSLSocketFactory.getDefault(ThreadLocalSSLSocketFactory.java:46)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at com.sun.jndi.ldap.Connection.createSocket(Connection.java:296)
     at com.sun.jndi.ldap.Connection.<init>(Connection.java:215)
     at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)
     at com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1609)
     at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2749)
     at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
     at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
     at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:151)
     at
com.sun.jndi.url.ldap.ldapURLContextFactory.getObjectInstance(ldapURLContextFactory.java:52)
     at
org.jboss.as.naming.context.ObjectFactoryBuilder$ReferenceUrlContextFactoryWrapper.getObjectInstance(ObjectFactoryBuilder.java:293)
     at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:300)
     at com.sun.jndi.ldap.LdapReferralContext.<init>(LdapReferralContext.java:119)
     ... 58 more
 {noformat}
 The reason seems to be that the {{ThreadLocalSSLSocketFactory}} is not set when doing a
search, so, if a referral is returned the new search created inside the current one has no
access to the {{SSLSocketFactory}} in the thread local.