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

smolnar82 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 6110aea62 KNOX-3374: Skip redundant roles lookup in PreAuth/ExtAuthz 
when the identity-assertion layer already resolved roles (#1306)
6110aea62 is described below

commit 6110aea6251b06eb563b6919192671f6913bb7c7
Author: Sandor Molnar <[email protected]>
AuthorDate: Wed Jul 15 17:36:50 2026 +0200

    KNOX-3374: Skip redundant roles lookup in PreAuth/ExtAuthz when the 
identity-assertion layer already resolved roles (#1306)
---
 .../filter/AbstractIdentityAssertionFilter.java    | 11 ++---
 .../filter/CommonIdentityAssertionFilter.java      |  4 +-
 .../filter/CommonIdentityAssertionFilterTest.java  |  2 +-
 .../filter/ConcatIdentityAssertionFilter.java      |  4 +-
 .../filter/ConcatIdentityAssertionFilterTest.java  |  2 +-
 .../groups/filter/HadoopGroupProviderFilter.java   | 14 +++---
 .../filter/HadoopGroupProviderFilterTest.java      | 41 ++++++++++++-----
 .../filter/NoImpersonationFilter.java              |  2 +-
 .../filter/NoImpersonationFilterTest.java          | 10 ++---
 .../filter/IdentityAsserterFilter.java             |  4 +-
 .../filter/DefaultIdentityAssertionFilterTest.java | 10 ++---
 .../regex/filter/RegexIdentityAssertionFilter.java |  3 +-
 .../filter/RegexIdentityAssertionFilterTest.java   |  2 +-
 .../SwitchCaseIdentityAssertionFilter.java         |  3 +-
 .../SwitchCaseIdentityAssertionFilterTest.java     | 16 +++----
 .../services/ldap/KnoxLDAPServerManager.java       | 13 +++---
 .../gateway/services/ldap/KnoxLDAPService.java     |  4 ++
 .../services/ldap/KnoxLDAPServerManagerTest.java   | 47 -------------------
 .../ConfigurableEntriesTestInterceptor.java        |  2 +-
 .../gateway/service/auth/AbstractAuthResource.java | 13 +++++-
 .../gateway/service/auth/ExtAuthzResource.java     |  9 ++++
 .../knox/gateway/service/auth/PreAuthResource.java |  9 ++++
 .../gateway/service/auth/ExtAuthzResourceTest.java |  9 +++-
 .../gateway/service/auth/PreAuthResourceTest.java  | 52 ++++++++++++++++------
 .../security/AbstractIdentityAssertionBase.java    |  2 +
 25 files changed, 170 insertions(+), 118 deletions(-)

diff --git 
a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java
 
b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java
index 81efb1511..128dd9dc3 100644
--- 
a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java
+++ 
b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java
@@ -54,8 +54,7 @@ import org.apache.knox.gateway.security.SubjectUtils;
 import org.apache.knox.gateway.security.TokenExchangePrincipal;
 import org.apache.knox.gateway.security.TokenIdPrincipal;
 
-public abstract class AbstractIdentityAssertionFilter extends
-  AbstractIdentityAssertionBase implements Filter {
+public abstract class AbstractIdentityAssertionFilter extends 
AbstractIdentityAssertionBase implements Filter {
 
   private IdentityAsserterMessages LOG = 
MessagesFactory.get(IdentityAsserterMessages.class);
 
@@ -70,15 +69,17 @@ public abstract class AbstractIdentityAssertionFilter 
extends
   }
 
   /**
-   * This method returns a Stringp[] of new group principal names to use
+   * This method returns a String[] of new group principal names to use
    * based on implementation specific mapping or lookup mechanisms.
    * Returning null means that whatever set of GroupPrincipals is in the
    * provided Subject is sufficient to use and no additional mapping is 
required.
+   *
    * @param mappedPrincipalName username for the authenticated identity - post 
mapUserPrincipal mapping.
-   * @param subject the existing Subject from the authentication event which 
may or may not contain GroupPrincipals.
+   * @param subject             the existing Subject from the authentication 
event which may or may not contain GroupPrincipals.
+   * @param request             the request which may or may not be decorated 
with extra attributes (e.g. if LDAP roles lookup happened already)
    * @return String[] of new principal names to use as GroupPrincipals or null.
    */
-  public abstract String[] mapGroupPrincipals(String mappedPrincipalName, 
Subject subject);
+  public abstract String[] mapGroupPrincipals(String mappedPrincipalName, 
Subject subject, ServletRequest request);
 
   /**
    * This method is used to map the username of the authenticated identity to 
some other
diff --git 
a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java
 
b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java
index a9a3d154c..51a33de5a 100644
--- 
a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java
+++ 
b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java
@@ -270,7 +270,7 @@ public class CommonIdentityAssertionFilter extends 
AbstractIdentityAssertionFilt
 
     private String[] getGroupsForPrincipal(String mappedPrincipalName, Subject 
subject, ServletRequest request) {
         String[] mappedGroups = mapGroupPrincipalsBase(mappedPrincipalName, 
subject);
-        String[] groups = mapGroupPrincipals(mappedPrincipalName, subject);
+        String[] groups = mapGroupPrincipals(mappedPrincipalName, subject, 
request);
         String[] virtualGroups = 
virtualGroupMapper.mapGroups(mappedPrincipalName, combine(subject, groups), 
request).toArray(new String[0]);
         groups = combineGroupMappings(mappedGroups, groups);
         groups = combineGroupMappings(virtualGroups, groups);
@@ -353,7 +353,7 @@ public class CommonIdentityAssertionFilter extends 
AbstractIdentityAssertionFilt
     }
 
     @Override
-    public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject) {
+    public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject, ServletRequest request) {
         // NOP
         return null;
     }
diff --git 
a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilterTest.java
 
b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilterTest.java
index 942065b8a..92ee96305 100644
--- 
a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilterTest.java
+++ 
b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilterTest.java
@@ -75,7 +75,7 @@ public class CommonIdentityAssertionFilterTest {
             }
 
             @Override
-            public String[] mapGroupPrincipals(String principalName, Subject 
subject) {
+            public String[] mapGroupPrincipals(String principalName, Subject 
subject, ServletRequest request) {
                 String[] groups = new String[4];
                 int i = 0;
                 for(GroupPrincipal p : 
subject.getPrincipals(GroupPrincipal.class)) {
diff --git 
a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
 
b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
index 655fec7f2..6c6f7323c 100644
--- 
a/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
+++ 
b/gateway-provider-identity-assertion-concat/src/main/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilter.java
@@ -20,6 +20,8 @@ package 
org.apache.knox.gateway.identityasserter.concat.filter;
 import javax.security.auth.Subject;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+
 import 
org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
 
 public class ConcatIdentityAssertionFilter extends 
CommonIdentityAssertionFilter {
@@ -41,7 +43,7 @@ public class ConcatIdentityAssertionFilter extends 
CommonIdentityAssertionFilter
   }
 
   @Override
-  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject) {
+  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject, ServletRequest request) {
     return null;
   }
 
diff --git 
a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
 
b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
index 6286158fc..bcac87649 100644
--- 
a/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
+++ 
b/gateway-provider-identity-assertion-concat/src/test/java/org/apache/knox/gateway/identityasserter/concat/filter/ConcatIdentityAssertionFilterTest.java
@@ -55,7 +55,7 @@ public class ConcatIdentityAssertionFilterTest {
 
     filter.init(config);
     String username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(username, subject);
+    String[] groups = filter.mapGroupPrincipals(username, subject, null);
     assertEquals(username, "larry");
     assertNull(groups); // means for the caller to use the existing subject 
groups
 
diff --git 
a/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java
 
b/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java
index ae3936d67..16bf52980 100644
--- 
a/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java
+++ 
b/gateway-provider-identity-assertion-hadoop-groups/src/main/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilter.java
@@ -23,6 +23,7 @@ import java.util.List;
 import javax.security.auth.Subject;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.security.LdapGroupsMapping;
@@ -106,12 +107,11 @@ public class HadoopGroupProviderFilter extends 
CommonIdentityAssertionFilter {
    * provided user.
    */
   @Override
-  public String[] mapGroupPrincipals(final String mappedPrincipalName,
-                                     final Subject subject) {
+  public String[] mapGroupPrincipals(final String mappedPrincipalName, final 
Subject subject, ServletRequest request) {
     /* return the groups as seen by Hadoop */
     String[] groups;
     try {
-      final List<String> groupList = hadoopGroups(mappedPrincipalName);
+      final List<String> groupList = hadoopGroups(mappedPrincipalName, 
request);
       LOG.groupsFound(mappedPrincipalName, groupList.toString());
       groups = groupList.toArray(new String[0]);
 
@@ -128,12 +128,16 @@ public class HadoopGroupProviderFilter extends 
CommonIdentityAssertionFilter {
     return groups;
   }
 
-  protected List<String> hadoopGroups(String mappedPrincipalName) throws 
Exception {
+  protected List<String> hadoopGroups(String mappedPrincipalName, 
ServletRequest request) throws Exception {
     if (ldapService == null) {
       return hadoopGroups == null ? List.of() : 
hadoopGroups.getGroups(mappedPrincipalName);
     } else {
       LOG.useKnoxLDAPService();
-      return ldapService.getUserGroups(mappedPrincipalName);
+      final List<String> groups = 
ldapService.getUserGroups(mappedPrincipalName);
+      if (request != null && ldapService.hasRolesLookupInterceptor()) {
+        request.setAttribute(ROLES_LOOKUP_EXECUTED, Boolean.TRUE.toString());
+      }
+      return groups;
     }
   }
 
diff --git 
a/gateway-provider-identity-assertion-hadoop-groups/src/test/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilterTest.java
 
b/gateway-provider-identity-assertion-hadoop-groups/src/test/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilterTest.java
index 52dad11ad..660bb4dda 100644
--- 
a/gateway-provider-identity-assertion-hadoop-groups/src/test/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilterTest.java
+++ 
b/gateway-provider-identity-assertion-hadoop-groups/src/test/java/org/apache/knox/gateway/identityasserter/hadoop/groups/filter/HadoopGroupProviderFilterTest.java
@@ -34,6 +34,7 @@ import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
@@ -42,6 +43,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.hadoop.security.GroupMappingServiceProvider;
 import org.apache.hadoop.security.LdapGroupsMapping;
 import org.apache.knox.gateway.config.GatewayConfig;
+import 
org.apache.knox.gateway.identityasserter.common.filter.AbstractIdentityAssertionFilter;
 import 
org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
 import org.apache.knox.gateway.security.PrimaryPrincipal;
 import org.apache.knox.gateway.services.GatewayServices;
@@ -99,7 +101,7 @@ public class HadoopGroupProviderFilterTest {
     final String principal = filter.mapUserPrincipal(
         ((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0])
             .getName());
-    final String[] groups = filter.mapGroupPrincipals(principal, subject);
+    final String[] groups = filter.mapGroupPrincipals(principal, subject, 
null);
 
     assertThat(principal, is(username));
     assertThat(
@@ -133,7 +135,7 @@ public class HadoopGroupProviderFilterTest {
     final String principal = filter.mapUserPrincipal(
         ((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0])
             .getName());
-    final String[] groups = filter.mapGroupPrincipals(principal, subject);
+    final String[] groups = filter.mapGroupPrincipals(principal, subject, 
null);
 
     assertThat(principal, is(failUsername));
     assertThat(
@@ -209,7 +211,7 @@ public class HadoopGroupProviderFilterTest {
     final String principal = filter.mapUserPrincipal(
         ((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0])
             .getName());
-    final String[] groups = filter.mapGroupPrincipals(principal, subject);
+    final String[] groups = filter.mapGroupPrincipals(principal, subject, 
null);
 
     assertThat(principal, is(username));
 
@@ -253,7 +255,7 @@ public class HadoopGroupProviderFilterTest {
       }
 
       @Override
-      protected List<String> hadoopGroups(String mappedPrincipalName) {
+      protected List<String> hadoopGroups(String mappedPrincipalName, 
ServletRequest request) {
         return Collections.singletonList("hadoop-group");
       }
     };
@@ -280,7 +282,7 @@ public class HadoopGroupProviderFilterTest {
     subject.getPrincipals().add(new PrimaryPrincipal(username));
 
     // no init() method called -> hadoopGroups is null
-    final String[] groups = filter.mapGroupPrincipals(username, subject);
+    final String[] groups = filter.mapGroupPrincipals(username, subject, null);
 
     assertThat(groups.length, is(0));
   }
@@ -288,15 +290,21 @@ public class HadoopGroupProviderFilterTest {
   @Test
   public void testLdapServiceIntegration() throws Exception {
     KnoxLDAPService ldapService = 
EasyMock.createNiceMock(KnoxLDAPService.class);
-    doTestLdapServiceIntegration(true, Arrays.asList("group1", "group2"), 
ldapService);
+    doTestLdapServiceIntegration(true, Arrays.asList("group1", "group2"), 
ldapService, false);
   }
 
   @Test
   public void testFallbackToHadoopGroupsWhenLdapDisabled() throws Exception {
-    doTestLdapServiceIntegration(false, 
Collections.singletonList("hadoop-group"), null);
+    doTestLdapServiceIntegration(false, 
Collections.singletonList("hadoop-group"), null, false);
   }
 
-  private void doTestLdapServiceIntegration(boolean ldapEnabled, List<String> 
expectedGroups, KnoxLDAPService ldapService) throws Exception {
+  @Test
+  public void testLdapServiceIntegrationWithRolesLookupInterceptor() throws 
Exception {
+    KnoxLDAPService ldapService = 
EasyMock.createNiceMock(KnoxLDAPService.class);
+    doTestLdapServiceIntegration(true, Arrays.asList("group1", "group2"), 
ldapService, true);
+  }
+
+  private void doTestLdapServiceIntegration(boolean ldapEnabled, List<String> 
expectedGroups, KnoxLDAPService ldapService, boolean hasRolesLookupInterceptor) 
throws Exception {
     final String principalName = "test-user";
 
     FilterConfig config = EasyMock.createNiceMock(FilterConfig.class);
@@ -314,6 +322,7 @@ public class HadoopGroupProviderFilterTest {
       
EasyMock.expect(context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE)).andReturn(services).anyTimes();
       
EasyMock.expect(services.getService(ServiceType.LDAP_SERVICE)).andReturn(ldapService).anyTimes();
       
EasyMock.expect(ldapService.getUserGroups(principalName)).andReturn(expectedGroups).anyTimes();
+      
EasyMock.expect(ldapService.hasRolesLookupInterceptor()).andReturn(hasRolesLookupInterceptor).anyTimes();
       EasyMock.replay(services, ldapService);
     } else {
       
EasyMock.expect(config.getInitParameterNames()).andReturn(Collections.emptyEnumeration()).anyTimes();
@@ -323,8 +332,8 @@ public class HadoopGroupProviderFilterTest {
 
     HadoopGroupProviderFilter filter = new HadoopGroupProviderFilter() {
       @Override
-      protected List<String> hadoopGroups(String mappedPrincipalName) throws 
Exception {
-        return ldapEnabled ? super.hadoopGroups(mappedPrincipalName) : 
expectedGroups;
+      protected List<String> hadoopGroups(String mappedPrincipalName, 
ServletRequest request) throws Exception {
+        return ldapEnabled ? super.hadoopGroups(mappedPrincipalName, request) 
: expectedGroups;
       }
     };
     filter.init(config);
@@ -332,11 +341,21 @@ public class HadoopGroupProviderFilterTest {
     Subject subject = new Subject();
     subject.getPrincipals().add(new PrimaryPrincipal(principalName));
 
-    String[] groups = filter.mapGroupPrincipals(principalName, subject);
+    final ServletRequest request = 
EasyMock.createNiceMock(ServletRequest.class);
+    if (hasRolesLookupInterceptor) {
+      
request.setAttribute(AbstractIdentityAssertionFilter.ROLES_LOOKUP_EXECUTED, 
"true");
+      EasyMock.expectLastCall().atLeastOnce();
+    }
+    EasyMock.replay(request);
+
+    String[] groups = filter.mapGroupPrincipals(principalName, subject, 
request);
 
     assertThat(Arrays.asList(groups), is(expectedGroups));
     if (ldapEnabled) {
       EasyMock.verify(ldapService);
+      if (hasRolesLookupInterceptor) {
+        EasyMock.verify(request);
+      }
     }
   }
 }
diff --git 
a/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilter.java
 
b/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilter.java
index b276f5364..c403ce787 100644
--- 
a/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilter.java
+++ 
b/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilter.java
@@ -35,7 +35,7 @@ public class NoImpersonationFilter extends 
CommonIdentityAssertionFilter {
   }
 
   @Override
-  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject) {
+  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject, ServletRequest request) {
     return mapGroupPrincipalsBase(mappedPrincipalName, subject);
   }
 
diff --git 
a/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilterTest.java
 
b/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilterTest.java
index 197af20d3..434141127 100644
--- 
a/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilterTest.java
+++ 
b/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilterTest.java
@@ -63,7 +63,7 @@ public class NoImpersonationFilterTest {
 
     filter.init(config);
     String username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(username, subject);
+    String[] groups = filter.mapGroupPrincipals(username, subject, null);
     assertEquals("lmccay", username);
     assertNull(groups); // means for the caller to use the existing subject 
groups
 
@@ -81,7 +81,7 @@ public class NoImpersonationFilterTest {
     EasyMock.replay( context, config );
     filter.init(config);
     username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    String[] mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
     assertEquals("hdfs", username);
     assertTrue("mrgroup not found in groups: " + 
Arrays.toString(mappedGroups), groupFoundIn("mrgroup", mappedGroups));
     assertTrue("mrducks not found in groups: " + 
Arrays.toString(mappedGroups), groupFoundIn("mrducks", mappedGroups));
@@ -107,7 +107,7 @@ public class NoImpersonationFilterTest {
     EasyMock.replay(context, config );
     filter.init(config);
     username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
     assertEquals("hdfs", username);
     assertTrue("group1 not found in groups: " + Arrays.toString(mappedGroups), 
groupFoundIn("group1", mappedGroups));
   }
@@ -148,7 +148,7 @@ public class NoImpersonationFilterTest {
 
     filter.init(config);
     String username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    String[] groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
 
     assertEquals("lmccay", username);
     assertNull(groups); // means for the caller to use the existing subject 
groups
@@ -165,7 +165,7 @@ public class NoImpersonationFilterTest {
     EasyMock.replay( context );
     filter.init(config);
     username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
     assertEquals("hdfs", username);
     assertTrue("mrgroup not found in groups: " + Arrays.toString(groups), 
groupFoundIn("mrgroup", groups));
     assertTrue("mrducks not found in groups: " + Arrays.toString(groups), 
groupFoundIn("mrducks", groups));
diff --git 
a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/knox/gateway/identityasserter/filter/IdentityAsserterFilter.java
 
b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/knox/gateway/identityasserter/filter/IdentityAsserterFilter.java
index db19c226e..44717c1fe 100644
--- 
a/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/knox/gateway/identityasserter/filter/IdentityAsserterFilter.java
+++ 
b/gateway-provider-identity-assertion-pseudo/src/main/java/org/apache/knox/gateway/identityasserter/filter/IdentityAsserterFilter.java
@@ -21,6 +21,8 @@ package org.apache.knox.gateway.identityasserter.filter;
 import javax.security.auth.Subject;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+
 import 
org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
 
 public class IdentityAsserterFilter extends CommonIdentityAssertionFilter {
@@ -31,7 +33,7 @@ public class IdentityAsserterFilter extends 
CommonIdentityAssertionFilter {
   }
 
   @Override
-  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject) {
+  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject, ServletRequest request) {
     return mapGroupPrincipalsBase(mappedPrincipalName, subject);
   }
 
diff --git 
a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java
 
b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java
index 6ba32b298..f64a8db04 100644
--- 
a/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java
+++ 
b/gateway-provider-identity-assertion-pseudo/src/test/java/org/apache/knox/gateway/identityasserter/filter/DefaultIdentityAssertionFilterTest.java
@@ -63,7 +63,7 @@ public class DefaultIdentityAssertionFilterTest {
 
     filter.init(config);
     String username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(username, subject);
+    String[] groups = filter.mapGroupPrincipals(username, subject, null);
     assertEquals("lmccay", username);
     assertNull(groups); // means for the caller to use the existing subject 
groups
 
@@ -81,7 +81,7 @@ public class DefaultIdentityAssertionFilterTest {
     EasyMock.replay( context, config );
     filter.init(config);
     username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    String[] mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
     assertEquals("hdfs", username);
     assertTrue("mrgroup not found in groups: " + 
Arrays.toString(mappedGroups), groupFoundIn("mrgroup", mappedGroups));
     assertTrue("mrducks not found in groups: " + 
Arrays.toString(mappedGroups), groupFoundIn("mrducks", mappedGroups));
@@ -107,7 +107,7 @@ public class DefaultIdentityAssertionFilterTest {
     EasyMock.replay( context, config );
     filter.init(config);
     username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    mappedGroups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
     assertEquals("hdfs", username);
     assertTrue("group1 not found in groups: " + Arrays.toString(mappedGroups), 
groupFoundIn("group1", mappedGroups));
   }
@@ -148,7 +148,7 @@ public class DefaultIdentityAssertionFilterTest {
 
     filter.init(config);
     String username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    String[] groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
 
     assertEquals("lmccay", username);
     assertNull(groups); // means for the caller to use the existing subject 
groups
@@ -165,7 +165,7 @@ public class DefaultIdentityAssertionFilterTest {
     EasyMock.replay( context );
     filter.init(config);
     username = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject);
+    groups = filter.mapGroupPrincipals(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName(), subject, 
null);
     assertEquals("hdfs", username);
     assertTrue("mrgroup not found in groups: " + Arrays.toString(groups), 
groupFoundIn("mrgroup", groups));
     assertTrue("mrducks not found in groups: " + Arrays.toString(groups), 
groupFoundIn("mrducks", groups));
diff --git 
a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
 
b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
index 3ddc41a1c..d1496ed34 100644
--- 
a/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
+++ 
b/gateway-provider-identity-assertion-regex/src/main/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilter.java
@@ -20,6 +20,7 @@ package org.apache.knox.gateway.identityasserter.regex.filter;
 import javax.security.auth.Subject;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
 
 import 
org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
 import org.apache.knox.gateway.security.principal.PrincipalMappingException;
@@ -57,7 +58,7 @@ public class RegexIdentityAssertionFilter extends
   }
 
   @Override
-  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject) {
+  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject 
subject, ServletRequest request) {
     // Returning null will allow existing Subject group principals to remain 
the same
     return null;
   }
diff --git 
a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
 
b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
index 21d77cc72..5ff263e8e 100644
--- 
a/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
+++ 
b/gateway-provider-identity-assertion-regex/src/test/java/org/apache/knox/gateway/identityasserter/regex/filter/RegexIdentityAssertionFilterTest.java
@@ -58,7 +58,7 @@ public class RegexIdentityAssertionFilterTest {
     // First test is with no config.  Since the output template is the empty 
string that should be the result.
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "" ) );
     assertThat( groups, is( nullValue() ) ); // means for the caller to use 
the existing subject groups
 
diff --git 
a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
 
b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
index 3e83ea02f..0cc2481a0 100644
--- 
a/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
+++ 
b/gateway-provider-identity-assertion-switchcase/src/main/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilter.java
@@ -23,6 +23,7 @@ import org.apache.knox.gateway.security.GroupPrincipal;
 import javax.security.auth.Subject;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
 import java.util.Locale;
 import java.util.Set;
 
@@ -69,7 +70,7 @@ public class SwitchCaseIdentityAssertionFilter extends
   }
 
   @Override
-  public String[] mapGroupPrincipals( String mappedPrincipalName, Subject 
subject ) {
+  public String[] mapGroupPrincipals( String mappedPrincipalName, Subject 
subject, ServletRequest request) {
     String[] groupNames = null;
     if ( groupCase != SwitchCase.NONE ) {
       Set<GroupPrincipal> groups = subject.getPrincipals( GroupPrincipal.class 
);
diff --git 
a/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilterTest.java
 
b/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilterTest.java
index bfb25ea57..d322b1499 100644
--- 
a/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilterTest.java
+++ 
b/gateway-provider-identity-assertion-switchcase/src/test/java/org/apache/knox/gateway/identityasserter/switchcase/SwitchCaseIdentityAssertionFilterTest.java
@@ -57,7 +57,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( arrayContainingInAnyOrder( "admin", "users" ) ) );
 
@@ -86,7 +86,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( arrayContainingInAnyOrder( "ADMIN", "USERS" ) ) );
 
@@ -114,7 +114,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( arrayContainingInAnyOrder( "admin", "users" ) ) );
 
@@ -140,7 +140,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( nullValue() ) );
 
@@ -168,7 +168,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( arrayContainingInAnyOrder( "ADMIN", "USERS" ) ) );
 
@@ -196,7 +196,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( nullValue() ) );
 
@@ -224,7 +224,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( nullValue() ) );
 
@@ -251,7 +251,7 @@ public class SwitchCaseIdentityAssertionFilterTest {
 
     filter.init(config);
     String actual = filter.mapUserPrincipal(((Principal) 
subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
-    String[] groups = filter.mapGroupPrincipals(actual, subject);
+    String[] groups = filter.mapGroupPrincipals(actual, subject, null);
     assertThat( actual, is( "[email protected]" ) );
     assertThat( groups, is( nullValue() ) );
 
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 4f30fa80c..30b6d0d0b 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
@@ -46,8 +46,8 @@ import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.knox.gateway.services.GatewayServices;
 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.ldap.interceptor.LDAPRolesLookupInterceptor;
 import org.apache.knox.gateway.services.security.AliasService;
 
 import java.io.File;
@@ -75,6 +75,7 @@ public class KnoxLDAPServerManager {
     private LdapServer ldapServer;
     private GatewayConfig gatewayConfig;
     private List<Interceptor> interceptors;
+    private boolean hasRolesLookupInterceptor;
     private File workDir;
     private int port;
     private String baseDn;
@@ -126,6 +127,8 @@ public class KnoxLDAPServerManager {
 
         createInterceptors(config);
 
+        hasRolesLookupInterceptor = interceptors.stream().anyMatch(interceptor 
-> interceptor instanceof LDAPRolesLookupInterceptor);
+
         // Clean up previous run if it didn't shut down cleanly
         File lockFile = new File(workDir, "run/instance.lock");
         if (lockFile.exists()) {
@@ -455,10 +458,6 @@ 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()) {
@@ -481,6 +480,10 @@ public class KnoxLDAPServerManager {
         return groups;
     }
 
+    public boolean hasRolesLookupInterceptor() {
+        return hasRolesLookupInterceptor;
+    }
+
     /**
      * Check if the LDAP server is currently running.
      *
diff --git 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPService.java
 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPService.java
index f1ccbb321..25dae6fbf 100644
--- 
a/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPService.java
+++ 
b/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/KnoxLDAPService.java
@@ -144,4 +144,8 @@ public class KnoxLDAPService implements Service, 
GatewayConfigChangeListener {
     public List<String> getUserGroups(String username) throws Exception {
         return ldapServerManager == null ? List.of() : 
ldapServerManager.getUserGroups(username);
     }
+
+    public boolean hasRolesLookupInterceptor() {
+        return ldapServerManager != null && 
ldapServerManager.hasRolesLookupInterceptor();
+    }
 }
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 78631552c..bb7dde208 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,14 +19,11 @@ 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.exception.LdapProtocolErrorException;
 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;
@@ -34,8 +31,6 @@ import org.apache.knox.gateway.util.X509CertificateUtil;
 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;
@@ -60,15 +55,12 @@ import java.security.SecureRandom;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 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;
@@ -435,45 +427,6 @@ 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);
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 a8507c614..27ac17f86 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;
 
-    public ConfigurableEntriesTestInterceptor(String name) {
+    ConfigurableEntriesTestInterceptor(String name) {
         super(name);
     }
 
diff --git 
a/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/AbstractAuthResource.java
 
b/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/AbstractAuthResource.java
index 4e844d643..8ed3aa660 100644
--- 
a/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/AbstractAuthResource.java
+++ 
b/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/AbstractAuthResource.java
@@ -17,6 +17,7 @@
  */
 package org.apache.knox.gateway.service.auth;
 
+import org.apache.knox.gateway.filter.security.AbstractIdentityAssertionBase;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.knox.gateway.security.SubjectUtils;
 import org.apache.knox.gateway.services.GatewayServices;
@@ -26,6 +27,7 @@ import org.apache.knox.gateway.util.GroupUtils;
 
 import javax.security.auth.Subject;
 import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.core.Response;
 import java.util.Collection;
@@ -86,6 +88,8 @@ public abstract class AbstractAuthResource {
   /* Abstract method that gets context instance */
   abstract ServletContext getContext();
 
+  abstract ServletRequest getRequest();
+
   String getInitParameter(String paramName, String defaultValue) {
     final String initParam = getContext().getInitParameter(paramName);
     return initParam == null ? defaultValue : initParam;
@@ -110,7 +114,7 @@ public abstract class AbstractAuthResource {
       final boolean useRoles = !roles.isEmpty();
       final List<String> groupStrings = GroupUtils.getGroupStrings(useRoles ? 
roles : matchingGroupNames, groupHeaderLengthLimit, groupHeaderSizeLimit);
       for (int i = 0; i < groupStrings.size(); i++) {
-        final String headerName = useRoles ? authHeaderActorGroupsPrefix : 
String.format(Locale.ROOT, ACTOR_GROUPS_HEADER_FORMAT, 
authHeaderActorGroupsPrefix, i + 1);
+        final String headerName = useRoles || rolesLookupExecuted() ? 
authHeaderActorGroupsPrefix : String.format(Locale.ROOT, 
ACTOR_GROUPS_HEADER_FORMAT, authHeaderActorGroupsPrefix, i + 1);
         getResponse().addHeader(headerName, groupStrings.get(i));
       }
     }
@@ -120,7 +124,7 @@ public abstract class AbstractAuthResource {
   private Collection<String> lookupRoles(String userName, Collection<String> 
groups) {
     Collection<String> roles = null;
       try {
-        if (ldapRolesLookupService != null && 
ldapRolesLookupService.enabled()) {
+        if (!rolesLookupExecuted() && ldapRolesLookupService != null && 
ldapRolesLookupService.enabled()) {
           roles = ldapRolesLookupService.lookupRoles(userName, groups);
         }
       } catch (Exception e) {
@@ -130,4 +134,9 @@ public abstract class AbstractAuthResource {
       return roles == null ? Collections.emptySet() : roles;
   }
 
+  private boolean rolesLookupExecuted() {
+    final Object rolesLookupExecutedReqAttribute = getRequest() == null ? null 
: 
getRequest().getAttribute(AbstractIdentityAssertionBase.ROLES_LOOKUP_EXECUTED);
+    return rolesLookupExecutedReqAttribute != null && 
Boolean.parseBoolean(rolesLookupExecutedReqAttribute.toString());
+  }
+
 }
diff --git 
a/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/ExtAuthzResource.java
 
b/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/ExtAuthzResource.java
index 5cd90e01e..59318d363 100644
--- 
a/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/ExtAuthzResource.java
+++ 
b/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/ExtAuthzResource.java
@@ -19,6 +19,7 @@ package org.apache.knox.gateway.service.auth;
 
 import javax.annotation.PostConstruct;
 import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -39,6 +40,9 @@ public class ExtAuthzResource extends AbstractAuthResource {
 
   private boolean ignoreAdditionalPath;
 
+  @Context
+  HttpServletRequest request;
+
   @Context
   HttpServletResponse response;
 
@@ -51,6 +55,11 @@ public class ExtAuthzResource extends AbstractAuthResource {
     ignoreAdditionalPath = 
Boolean.parseBoolean(getInitParameter(IGNORE_ADDITIONAL_PATH, 
DEFAULT_IGNORE_ADDITIONAL_PATH));
   }
 
+  @Override
+  public HttpServletRequest getRequest() {
+    return request;
+  }
+
   @Override
   HttpServletResponse getResponse() {
     return response;
diff --git 
a/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/PreAuthResource.java
 
b/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/PreAuthResource.java
index 335a25fd7..6cd9dd98c 100644
--- 
a/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/PreAuthResource.java
+++ 
b/gateway-service-auth/src/main/java/org/apache/knox/gateway/service/auth/PreAuthResource.java
@@ -19,6 +19,7 @@ package org.apache.knox.gateway.service.auth;
 
 import javax.annotation.PostConstruct;
 import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import javax.ws.rs.DELETE;
@@ -34,6 +35,9 @@ public class PreAuthResource extends AbstractAuthResource {
 
   static final String RESOURCE_PATH = "auth/api/v1/pre";
 
+  @Context
+  HttpServletRequest request;
+
   @Context
   HttpServletResponse response;
 
@@ -44,6 +48,11 @@ public class PreAuthResource extends AbstractAuthResource {
     initialize();
   }
 
+  @Override
+  public HttpServletRequest getRequest() {
+    return request;
+  }
+
   @Override
   HttpServletResponse getResponse() {
     return response;
diff --git 
a/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/ExtAuthzResourceTest.java
 
b/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/ExtAuthzResourceTest.java
index 9d093973d..8e5fd90b8 100644
--- 
a/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/ExtAuthzResourceTest.java
+++ 
b/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/ExtAuthzResourceTest.java
@@ -17,6 +17,7 @@
  */
 package org.apache.knox.gateway.service.auth;
 
+import org.apache.knox.gateway.filter.security.AbstractIdentityAssertionBase;
 import org.apache.knox.gateway.security.GroupPrincipal;
 import org.apache.knox.gateway.security.PrimaryPrincipal;
 import org.apache.knox.gateway.security.SubjectUtils;
@@ -64,6 +65,7 @@ public class ExtAuthzResourceTest {
     final ExtAuthzResource extAuthzResource = new ExtAuthzResource();
     extAuthzResource.context = context;
     extAuthzResource.response = response;
+    extAuthzResource.request = request;
     executeResourceWithAdditionalPath(extAuthzResource);
     EasyMock.verify(response);
   }
@@ -75,6 +77,7 @@ public class ExtAuthzResourceTest {
     
EasyMock.expect(context.getInitParameter(ExtAuthzResource.AUTH_ACTOR_GROUPS_HEADER_PREFIX)).andReturn(groupsHeaderPrefix).anyTimes();
     
EasyMock.expect(context.getInitParameter(ExtAuthzResource.IGNORE_ADDITIONAL_PATH)).andReturn("true").anyTimes();
     request = EasyMock.createNiceMock(HttpServletRequest.class);
+    
EasyMock.expect(request.getAttribute(AbstractIdentityAssertionBase.ROLES_LOOKUP_EXECUTED)).andReturn("false").anyTimes();
     response = EasyMock.createNiceMock(HttpServletResponse.class);
 
     if (SubjectUtils.getPrimaryPrincipalName(subject) != null) {
@@ -122,13 +125,17 @@ public class ExtAuthzResourceTest {
     
response.addHeader(EasyMock.eq(AbstractAuthResource.DEFAULT_AUTH_ACTOR_GROUPS_HEADER_PREFIX),
 EasyMock.anyString());
     EasyMock.expectLastCall().anyTimes();
 
-    EasyMock.replay(context, response, mockRolesService, mockGatewayServices);
+    request = EasyMock.createNiceMock(HttpServletRequest.class);
+    
EasyMock.expect(request.getAttribute(AbstractIdentityAssertionBase.ROLES_LOOKUP_EXECUTED)).andReturn("false").anyTimes();
+
+    EasyMock.replay(context, request, response, mockRolesService, 
mockGatewayServices);
 
     groups.forEach(group -> subject.getPrincipals().add(new 
GroupPrincipal(group)));
 
     final ExtAuthzResource extAuthzResource = new ExtAuthzResource();
     extAuthzResource.context = context;
     extAuthzResource.response = response;
+    extAuthzResource.request = request;
     executeResourceWithAdditionalPath(extAuthzResource);
 
     EasyMock.verify(response);
diff --git 
a/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/PreAuthResourceTest.java
 
b/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/PreAuthResourceTest.java
index 78c019d62..5e1496c83 100644
--- 
a/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/PreAuthResourceTest.java
+++ 
b/gateway-service-auth/src/test/java/org/apache/knox/gateway/service/auth/PreAuthResourceTest.java
@@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.core.Response;
 
+import org.apache.knox.gateway.filter.security.AbstractIdentityAssertionBase;
 import org.apache.knox.gateway.security.GroupPrincipal;
 import org.apache.knox.gateway.security.PrimaryPrincipal;
 import org.apache.knox.gateway.security.SubjectUtils;
@@ -48,6 +49,7 @@ public class PreAuthResourceTest {
 
   private static final String USER_NAME = "test-username";
   private ServletContext context;
+  private HttpServletRequest request;
   private HttpServletResponse response;
   private final Subject subject = new Subject();
 
@@ -61,14 +63,15 @@ public class PreAuthResourceTest {
   }
 
   private void configureCommonExpectations(String actorIdHeaderName, String 
groupsHeaderPrefix, Collection<String> groups) throws Exception {
-    configureCommonExpectations(actorIdHeaderName, groupsHeaderPrefix, groups, 
null);
+    configureCommonExpectations(actorIdHeaderName, groupsHeaderPrefix, groups, 
null, false);
   }
 
-  private void configureCommonExpectations(String actorIdHeaderName, String 
groupsHeaderPrefix, Collection<String> groups, GatewayServices gatewayServices) 
throws Exception {
+  private void configureCommonExpectations(String actorIdHeaderName, String 
groupsHeaderPrefix, Collection<String> groups, GatewayServices gatewayServices, 
boolean rolesLookupExecuted) throws Exception {
     context = EasyMock.createNiceMock(ServletContext.class);
     
EasyMock.expect(context.getInitParameter(PreAuthResource.AUTH_ACTOR_ID_HEADER_NAME)).andReturn(actorIdHeaderName).anyTimes();
     
EasyMock.expect(context.getInitParameter(PreAuthResource.AUTH_ACTOR_GROUPS_HEADER_PREFIX)).andReturn(groupsHeaderPrefix).anyTimes();
-    final HttpServletRequest request = 
EasyMock.createNiceMock(HttpServletRequest.class);
+    request = EasyMock.createNiceMock(HttpServletRequest.class);
+    
EasyMock.expect(request.getAttribute(AbstractIdentityAssertionBase.ROLES_LOOKUP_EXECUTED)).andReturn(rolesLookupExecuted).anyTimes();
     response = EasyMock.createNiceMock(HttpServletResponse.class);
 
     if (SubjectUtils.getPrimaryPrincipalName(subject) != null) {
@@ -81,12 +84,12 @@ public class PreAuthResourceTest {
       
EasyMock.expect(context.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE)).andReturn(gatewayServices);
       final LDAPRolesLookupService rolesLookupService = 
gatewayServices.getService(ServiceType.LDAP_ROLES_LOOKUP_SERVICE);
       if (rolesLookupService != null && rolesLookupService.enabled()) {
-        Collection<String> roles = rolesLookupService.lookupRoles(USER_NAME, 
groups);
-        if (roles != null && !roles.isEmpty()) {
           final String expectedGroupsHeaderPrefix = (groupsHeaderPrefix == 
null ? PreAuthResource.DEFAULT_AUTH_ACTOR_GROUPS_HEADER_PREFIX : 
groupsHeaderPrefix);
           response.addHeader(EasyMock.eq(expectedGroupsHeaderPrefix), 
EasyMock.anyString());
-          EasyMock.expectLastCall().anyTimes();
-        }
+          EasyMock.expectLastCall().times(1);
+      }
+      if (rolesLookupExecuted) {
+        groups.forEach(group -> subject.getPrincipals().add(new 
GroupPrincipal(group)));
       }
     } else if (!groups.isEmpty()) {
       groups.forEach(group -> subject.getPrincipals().add(new 
GroupPrincipal(group)));
@@ -117,6 +120,7 @@ public class PreAuthResourceTest {
     final PreAuthResource preAuthResource = new PreAuthResource();
     preAuthResource.context = context;
     preAuthResource.response = response;
+    preAuthResource.request = request;
     final Response response = executeResourceWithSubject(preAuthResource);
     assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
   }
@@ -127,6 +131,7 @@ public class PreAuthResourceTest {
     final PreAuthResource preAuthResource = new PreAuthResource();
     preAuthResource.context = context;
     preAuthResource.response = response;
+    preAuthResource.request = request;
     executeResourceWithSubject(preAuthResource);
     EasyMock.verify(response);
   }
@@ -137,6 +142,7 @@ public class PreAuthResourceTest {
     final PreAuthResource preAuthResource = new PreAuthResource();
     preAuthResource.context = context;
     preAuthResource.response = response;
+    preAuthResource.request = request;
     executeResourceWithSubject(preAuthResource);
     EasyMock.verify(response);
   }
@@ -147,6 +153,7 @@ public class PreAuthResourceTest {
     final PreAuthResource preAuthResource = new PreAuthResource();
     preAuthResource.context = context;
     preAuthResource.response = response;
+    preAuthResource.request = request;
     executeResourceWithSubject(preAuthResource);
     EasyMock.verify(response);
   }
@@ -157,29 +164,47 @@ public class PreAuthResourceTest {
     final PreAuthResource preAuthResource = new PreAuthResource();
     preAuthResource.context = context;
     preAuthResource.response = response;
+    preAuthResource.request = request;
     executeResourceWithSubject(preAuthResource);
     EasyMock.verify(response);
   }
 
   @Test
   public void testPopulatingGroupsWithRoles() throws Exception {
-    final GatewayServices gatewayServices = 
configureLdapRolesLookupExpectations();
-    
configureCommonExpectations(PreAuthResource.DEFAULT_AUTH_ACTOR_ID_HEADER_NAME, 
null, Collections.singleton("engineering"), gatewayServices);
+    final String rolesHeader = "X-Knox-Roles";
+    final GatewayServices gatewayServices = 
configureLdapRolesLookupExpectations(false);
+    
configureCommonExpectations(PreAuthResource.DEFAULT_AUTH_ACTOR_ID_HEADER_NAME, 
rolesHeader, Collections.singleton("engineering"), gatewayServices, false);
     final PreAuthResource preAuthResource = new PreAuthResource();
     preAuthResource.context = context;
     preAuthResource.response = response;
+    preAuthResource.request = request;
     Response preAuthResponse = executeResourceWithSubject(preAuthResource);
     assertEquals(HttpServletResponse.SC_OK, preAuthResponse.getStatus());
     EasyMock.verify(response);
   }
 
-  private GatewayServices configureLdapRolesLookupExpectations() throws 
Exception {
+  @Test
+  public void testRolesAreNotPopulatedTwice() throws Exception {
+    final String rolesHeader = "X-Knox-Roles";
+    final GatewayServices gatewayServices = 
configureLdapRolesLookupExpectations(true);
+    
configureCommonExpectations(PreAuthResource.DEFAULT_AUTH_ACTOR_ID_HEADER_NAME, 
rolesHeader, Collections.singleton("engineering"), gatewayServices, true);
+    final PreAuthResource preAuthResource = new PreAuthResource();
+    preAuthResource.context = context;
+    preAuthResource.response = response;
+    preAuthResource.request = request;
+    Response preAuthResponse = executeResourceWithSubject(preAuthResource);
+    assertEquals(HttpServletResponse.SC_OK, preAuthResponse.getStatus());
+    EasyMock.verify(response);
+  }
+
+  private GatewayServices configureLdapRolesLookupExpectations(boolean 
roleLookupExecuted) throws Exception {
     final String role1 = "platform:admin";
     final String role2 = "ml-workspace:viewer";
-    final Set<String> groups = Collections.singleton("engineering");
-    final LDAPRolesLookupService rolesLookupService = 
EasyMock.createNiceMock(LDAPRolesLookupService.class);
+    final LDAPRolesLookupService rolesLookupService = 
EasyMock.createMock(LDAPRolesLookupService.class);
     EasyMock.expect(rolesLookupService.enabled()).andReturn(true).anyTimes();
-    EasyMock.expect(rolesLookupService.lookupRoles(EasyMock.eq(USER_NAME), 
EasyMock.anyObject())).andReturn(Arrays.asList(role1, role2)).anyTimes();
+    if (!roleLookupExecuted) {
+      EasyMock.expect(rolesLookupService.lookupRoles(EasyMock.eq(USER_NAME), 
EasyMock.anyObject())).andReturn(Arrays.asList(role1, role2)).anyTimes();
+    }
 
     final GatewayServices gatewayServices = 
EasyMock.createNiceMock(GatewayServices.class);
     
EasyMock.expect(gatewayServices.getService(ServiceType.LDAP_ROLES_LOOKUP_SERVICE)).andReturn(rolesLookupService).anyTimes();
@@ -203,6 +228,7 @@ public class PreAuthResourceTest {
     final PreAuthResource preAuthResource = new PreAuthResource();
     preAuthResource.context = context;
     preAuthResource.response = response;
+    preAuthResource.request = request;
     executeResourceWithSubject(preAuthResource);
     EasyMock.verify(response);
   }
diff --git 
a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/security/AbstractIdentityAssertionBase.java
 
b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/security/AbstractIdentityAssertionBase.java
index 0ee186395..25909aff7 100644
--- 
a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/security/AbstractIdentityAssertionBase.java
+++ 
b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/security/AbstractIdentityAssertionBase.java
@@ -23,6 +23,8 @@ import javax.security.auth.Subject;
 
 public class AbstractIdentityAssertionBase {
 
+  public static final String ROLES_LOOKUP_EXECUTED = "ROLES_LOOKUP_EXECUTED";
+
   /**
    * Retrieve the principal to represent the asserted identity from
    * the provided Subject.

Reply via email to