1

I'm testing Keycloak and wanted to integrate it with OpenShift. I'm following these instructions

I got the bit where you configure the client scope and keycloak immediately dies with:

enter image description here

Default install, this is all I've done to it. Refreshing does nothing. To reproduce I just go to:

Clients -> openshift (the name of my client) -> Client Scopes. When I check the logs I see:

2024-07-15 19:32:02,456 ERROR [org.keycloak.storage.ldap.idm.store.ldap.LDAPOperationManager] (executor-thread-27) Could not query server using DN [OU=Users,DC=openshift,DC=lan] and filter [(&(objectclass=person)(objectclass=organizationalPerson)(objectclass=user))]: javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-0310028D, problem 2001 (NO_OBJECT), data 0, best match of:
        'DC=openshift,DC=lan'
]; remaining name 'OU=Users,DC=openshift,DC=lan'
        at java.naming/com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3285)
        at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3206)
        at java.naming/com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2997)
        at java.naming/com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1876)
        at java.naming/com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1799)
        at java.naming/com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:392)
        at java.naming/com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:358)
        at java.naming/javax.naming.directory.InitialDirContext.search(InitialDirContext.java:359)
        at org.keycloak.storage.ldap.idm.store.ldap.LDAPOperationManager$3.execute(LDAPOperationManager.java:258)
        at org.keycloak.storage.ldap.idm.store.ldap.LDAPOperationManager$3.execute(LDAPOperationManager.java:255)
        at org.keycloak.storage.ldap.idm.store.ldap.LDAPOperationManager.execute(LDAPOperationManager.java:729)
        at org.keycloak.storage.ldap.idm.store.ldap.LDAPOperationManager.execute(LDAPOperationManager.java:709)
        at org.keycloak.storage.ldap.idm.store.ldap.LDAPOperationManager.execute(LDAPOperationManager.java:704)
        at org.keycloak.storage.ldap.idm.store.ldap.LDAPOperationManager.search(LDAPOperationManager.java:255)
        at org.keycloak.storage.ldap.idm.store.ldap.LDAPIdentityStore.fetchQueryResults(LDAPIdentityStore.java:278)
        at org.keycloak.storage.ldap.idm.query.internal.LDAPQuery.getResultList(LDAPQuery.java:174)
        at org.keycloak.storage.ldap.LDAPStorageProvider.paginatedSearchLDAP(LDAPStorageProvider.java:1123)
        at org.keycloak.storage.ldap.LDAPStorageProvider.searchLDAPByAttributes(LDAPStorageProvider.java:564)
        at org.keycloak.storage.ldap.LDAPStorageProvider.searchForUserStream(LDAPStorageProvider.java:379)
        at org.keycloak.storage.UserStorageManager.lambda$searchForUserStream$29(UserStorageManager.java:537)
        at org.keycloak.storage.UserStorageManager.lambda$query$13(UserStorageManager.java:331)
        at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
        at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
        at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:261)
        at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:261)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
        at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
        at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.forEachOrdered(ReferencePipeline.java:601)
        at com.fasterxml.jackson.datatype.jdk8.StreamSerializer.serialize(StreamSerializer.java:71)
        at com.fasterxml.jackson.datatype.jdk8.StreamSerializer.serialize(StreamSerializer.java:15)
        at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:502)
        at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:341)
        at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1574)
        at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1275)
        at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1098)
        at io.quarkus.resteasy.reactive.jackson.runtime.serialisers.FullyFeaturedServerJacksonMessageBodyWriter.writeResponse(FullyFeaturedServerJacksonMessageBodyWriter.java:79)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.invokeWriter(ServerSerialisers.java:216)
        at org.jboss.resteasy.reactive.server.core.ServerSerialisers.invokeWriter(ServerSerialisers.java:184)
        at org.jboss.resteasy.reactive.server.core.serialization.FixedEntityWriter.write(FixedEntityWriter.java:28)
        at org.jboss.resteasy.reactive.server.handlers.ResponseWriterHandler.handle(ResponseWriterHandler.java:34)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:147)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:582)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1583)

but as far as I can tell, that's correct based on my lab AD config:

enter image description here

Then one final sanity check in the LDAP config:

enter image description here

I'm not sure what Keycloak is looking for here. Everything is configured correctly.

1
  • FYI In AD, you only need (objectclass=user). Person is an objectCategory, but you don't need it to query users.
    – Greg Askew
    Commented Jul 15 at 22:06

1 Answer 1

2
Could not query server using DN [OU=Users,DC=openshift,DC=lan]

In Active Directory "Users" is not an Organizational Unit, but a container.

You need to reference it using the DN CN=Users,DC=openshift,DC=lan.

The same applies to "Builtin" and "Computers"; "Domain Controllers" is instead an actual OU, thus its DN would be OU=Domain Controllers,DC=openshift,DC=lan.

This is also shown graphically in ADUC by the different icons used for OUs and containers.

Normally you don't have to deal with containers and you can't even create them easily; OUs are the way to go. But some containers (such as those in your image) exist in all Active Directory domains. If you want to reference them in a LDAP query, you need to keep in mind which kind of object you are actually dealing with.

1
  • Thanks! This is quite confusing as my LDAP test in Keycloak passed. Not sure if that test is bugged or it's not checking the DN. Commented Jul 16 at 12:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .