This is an automated email from the ASF dual-hosted git repository.

hanicz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new 7b34b7c98 KNOX-3374: Fix inherited roles missing from auth headers 
when LDAP roles-lookup interceptor is active (#1300)
7b34b7c98 is described below

commit 7b34b7c9861da895af8f178082ed750039c0c889
Author: hanicz <[email protected]>
AuthorDate: Wed Jul 8 15:45:04 2026 +0200

    KNOX-3374: Fix inherited roles missing from auth headers when LDAP 
roles-lookup interceptor is active (#1300)
---
 .../services/ldap/KnoxLDAPServerManager.java       |  5 +++
 .../services/ldap/KnoxLDAPServerManagerTest.java   | 49 +++++++++++++++++++++-
 .../ConfigurableEntriesTestInterceptor.java        |  2 +-
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManager.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManager.java
index 2c2442686..5d58b42e5 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManager.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManager.java
@@ -45,6 +45,7 @@ import 
org.apache.directory.server.protocol.shared.transport.TcpTransport;
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import 
org.apache.knox.gateway.services.ldap.control.RolesLookupBypassControlFactory;
+import 
org.apache.knox.gateway.services.ldap.control.RolesLookupBypassControlImpl;
 import org.apache.knox.gateway.services.ldap.interceptor.InterceptorFactory;
 import org.apache.knox.gateway.services.security.AliasService;
 
@@ -377,6 +378,10 @@ public class KnoxLDAPServerManager {
         searchRequest.setFilter("(uid=" + username + ")");
         searchRequest.addAttributes("*");
 
+        RolesLookupBypassControlImpl bypassControl = new 
RolesLookupBypassControlImpl();
+        bypassControl.setBypassRolesLookup(true);
+        searchRequest.addControl(bypassControl);
+
         List<String> groups = new ArrayList<>();
         try (Cursor<Entry> cursor = 
directoryService.getAdminSession().search(searchRequest)) {
             if (cursor.next()) {
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManagerTest.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManagerTest.java
index 8fc51bcbe..b277cb835 100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManagerTest.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/KnoxLDAPServerManagerTest.java
@@ -19,16 +19,21 @@ package org.apache.knox.gateway.services.ldap;
 
 import org.apache.directory.api.ldap.codec.api.ControlFactory;
 import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
 import 
org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
 import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.Control;
 import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
 import org.apache.directory.server.core.api.interceptor.Interceptor;
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.services.security.AliasService;
 import 
org.apache.knox.gateway.services.ldap.control.RolesLookupBypassControlFactory;
+import 
org.apache.knox.gateway.services.ldap.interceptor.ConfigurableEntriesTestInterceptor;
+import 
org.apache.knox.gateway.services.ldap.interceptor.LDAPRolesLookupInterceptor;
 import org.apache.knox.gateway.services.ldap.model.constants.SchemaConstants;
 import org.easymock.EasyMock;
 import org.apache.directory.api.ldap.model.name.Dn;
@@ -40,12 +45,15 @@ import org.junit.After;
 import java.io.File;
 import java.net.ServerSocket;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.junit.Assert.assertEquals;
@@ -408,6 +416,45 @@ public class KnoxLDAPServerManagerTest {
         
assertTrue(controlFactoryMap.get(SchemaConstants.ROLES_LOOKUP_BYPASS_CONTROL_OID)
 instanceof RolesLookupBypassControlFactory);
     }
 
+    @Test
+    public void 
testGetUserGroupsReturnsRawGroupsEvenWhenRolesInterceptorRewritesMemberOf() 
throws Exception {
+        GatewayConfig mockConfig = 
EasyMock.createNiceMock(GatewayConfig.class);
+        
expect(mockConfig.getGatewayDataDir()).andReturn(tempWorkDir.getParent()).anyTimes();
+        expect(mockConfig.getLDAPPort()).andReturn(port).anyTimes();
+        
expect(mockConfig.getLDAPBaseDN()).andReturn("dc=test,dc=com").anyTimes();
+        
expect(mockConfig.getLDAPInterceptorNames()).andReturn(List.of()).anyTimes();
+        replay(mockConfig);
+
+        serverManager.initialize(mockConfig);
+        serverManager.start();
+
+        SchemaManager schemaManager = 
serverManager.directoryService.getSchemaManager();
+        Entry userEntry = new DefaultEntry(schemaManager);
+        userEntry.setDn("uid=admin,ou=people,dc=test,dc=com");
+        userEntry.add("uid", "admin");
+        userEntry.add("memberOf", 
"cn=me-test-group-a,ou=groups,dc=test,dc=com");
+        userEntry.add("memberOf", 
"cn=me-test-group-b,ou=groups,dc=test,dc=com");
+        ConfigurableEntriesTestInterceptor entriesInterceptor = new 
ConfigurableEntriesTestInterceptor("testEntries");
+        entriesInterceptor.setEntries(List.of(userEntry));
+        entriesInterceptor.init(serverManager.directoryService);
+
+        LDAPRolesLookupService mockRolesService = 
EasyMock.createNiceMock(LDAPRolesLookupService.class);
+        expect(mockRolesService.lookupRoles(anyString(), anyObject()))
+                .andReturn(Arrays.asList("console:admin", "ws-1:viewer", 
"ws-2:user")).anyTimes();
+        replay(mockRolesService);
+        LDAPRolesLookupInterceptor rolesInterceptor = new 
LDAPRolesLookupInterceptor(mockRolesService);
+        rolesInterceptor.init(serverManager.directoryService);
+
+        List<Interceptor> chain = new 
ArrayList<>(serverManager.directoryService.getInterceptors());
+        chain.add(0, rolesInterceptor);
+        chain.add(1, entriesInterceptor);
+        serverManager.directoryService.setInterceptors(chain);
+
+        List<String> groups = serverManager.getUserGroups("admin");
+
+        assertEquals(Arrays.asList("me-test-group-a", "me-test-group-b"), 
groups);
+    }
+
     @Test(expected = LdapException.class)
     public void testBindRequiredRejectsAnonymous() throws Exception {
         useBindPassword(BIND_PASSWORD);
@@ -539,4 +586,4 @@ public class KnoxLDAPServerManagerTest {
         }
         file.delete();
     }
-}
\ No newline at end of file
+}
diff --git 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/interceptor/ConfigurableEntriesTestInterceptor.java
 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/interceptor/ConfigurableEntriesTestInterceptor.java
index 27ac17f86..a8507c614 100644
--- 
a/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/interceptor/ConfigurableEntriesTestInterceptor.java
+++ 
b/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/interceptor/ConfigurableEntriesTestInterceptor.java
@@ -35,7 +35,7 @@ public class ConfigurableEntriesTestInterceptor extends 
BaseInterceptor {
     private List<Entry> entries;
     private EntryFilteringCursor cursor;
 
-    ConfigurableEntriesTestInterceptor(String name) {
+    public ConfigurableEntriesTestInterceptor(String name) {
         super(name);
     }
 

Reply via email to