You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by mo...@apache.org on 2022/03/11 11:37:53 UTC

[knox] branch master updated: KNOX-2710 - Support for identityassertion filter with no doAs query param (#544)

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

more 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 cbae31d  KNOX-2710 - Support for identityassertion filter with no doAs query param (#544)
cbae31d is described below

commit cbae31d384f2343f9af4f1851f2fae60c82b8e56
Author: Sandeep Moré <mo...@gmail.com>
AuthorDate: Fri Mar 11 06:37:47 2022 -0500

    KNOX-2710 - Support for identityassertion filter with no doAs query param (#544)
---
 .../IdentityAsserterHttpServletRequestWrapper.java |   8 +-
 .../pom.xml                                        |  88 +++++++++++
 ...ImpersonationAsserterDeploymentContributor.java |  53 +++++++
 .../NoImpersonationAsserterRequestWrapper.java     |  64 ++++++++
 .../filter/NoImpersonationFilter.java              |  54 +++++++
 ...ox.gateway.deploy.ProviderDeploymentContributor |  19 +++
 .../filter/NoImpersonationFilterTest.java          | 167 ++++++++++++++++++++
 ...ImpersonationHttpServletRequestWrapperTest.java | 169 +++++++++++++++++++++
 .../UsernameFunctionProcessorTest/rewrite.xml      |  24 +++
 gateway-release/pom.xml                            |   4 +
 pom.xml                                            |   6 +
 11 files changed, 652 insertions(+), 4 deletions(-)

diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java
index de844ca..ba72fd1 100644
--- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java
+++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/IdentityAsserterHttpServletRequestWrapper.java
@@ -46,7 +46,7 @@ import java.util.Map;
 
 public class IdentityAsserterHttpServletRequestWrapper extends HttpServletRequestWrapper {
 
-private static SpiGatewayMessages log = MessagesFactory.get( SpiGatewayMessages.class );
+  protected static final SpiGatewayMessages log = MessagesFactory.get( SpiGatewayMessages.class );
 
   private static final String PRINCIPAL_PARAM = "user.name";
   private static final String DOAS_PRINCIPAL_PARAM = "doAs";
@@ -143,7 +143,7 @@ private static SpiGatewayMessages log = MessagesFactory.get( SpiGatewayMessages.
     return params;
   }
 
-  private Map<String, List<String>> getParams()
+  protected Map<String, List<String>> getParams()
       throws UnsupportedEncodingException {
     return getParams( super.getQueryString() );
   }
@@ -181,7 +181,7 @@ private static SpiGatewayMessages log = MessagesFactory.get( SpiGatewayMessages.
     return q;
   }
 
-  private List<String> getImpersonationParamNames() {
+  protected List<String> getImpersonationParamNames() {
     // TODO: let's have service definitions register their impersonation
     // params in a future release and get this list from a central registry.
     // This will provide better coverage of protection by removing any
@@ -192,7 +192,7 @@ private static SpiGatewayMessages log = MessagesFactory.get( SpiGatewayMessages.
     return principalParamNames;
   }
 
-  private Map<String, List<String>> scrubOfExistingPrincipalParams(
+  protected Map<String, List<String>> scrubOfExistingPrincipalParams(
       Map<String, List<String>> params, List<String> principalParamNames) {
     HashSet<String> remove = new HashSet<>();
     for (String paramKey : params.keySet()) {
diff --git a/gateway-provider-identity-assertion-no-doas/pom.xml b/gateway-provider-identity-assertion-no-doas/pom.xml
new file mode 100644
index 0000000..2fbba2b
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.knox</groupId>
+        <artifactId>gateway</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>gateway-provider-identity-assertion-no-doas</artifactId>
+    <name>gateway-provider-identity-assertion-no-doas</name>
+    <description>An extension to the gateway that asserts identity to Hadoop clusters that excludes doAs parameter.</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-i18n</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-provider-identity-assertion-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-provider-rewrite</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.shrinkwrap.descriptors</groupId>
+            <artifactId>shrinkwrap-descriptors-api-javaee</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-test-utils</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlet</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.xmlmatchers</groupId>
+            <artifactId>xml-matchers</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationAsserterDeploymentContributor.java b/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationAsserterDeploymentContributor.java
new file mode 100644
index 0000000..c33d683
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationAsserterDeploymentContributor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.filter;
+
+import org.apache.knox.gateway.deploy.DeploymentContext;
+import org.apache.knox.gateway.identityasserter.common.filter.AbstractIdentityAsserterDeploymentContributor;
+import org.apache.knox.gateway.topology.Provider;
+
+public class NoImpersonationAsserterDeploymentContributor extends AbstractIdentityAsserterDeploymentContributor {
+
+  /**
+   * Name of our <b>identity-assertion</b> provider.
+   */
+  public static final String NO_DOAS_PROVIDER = "NoImpersonationProvider";
+  private static final String FILTER_CLASSNAME = NoImpersonationFilter.class.getName();
+  private static final String PRINCIPAL_MAPPING_PARAM_NAME = "principal.mapping";
+  private static final String GROUP_PRINCIPAL_MAPPING_PARAM_NAME = "group.principal.mapping";
+
+  @Override
+  public String getName() {
+    return NO_DOAS_PROVIDER;
+  }
+
+  @Override
+  public void contributeProvider( DeploymentContext context, Provider provider ) {
+    super.contributeProvider(context, provider);
+    String mappings = provider.getParams().get(PRINCIPAL_MAPPING_PARAM_NAME);
+    String groupMappings = provider.getParams().get(GROUP_PRINCIPAL_MAPPING_PARAM_NAME);
+
+    context.getWebAppDescriptor().createContextParam().paramName(PRINCIPAL_MAPPING_PARAM_NAME).paramValue(mappings);
+    context.getWebAppDescriptor().createContextParam().paramName(GROUP_PRINCIPAL_MAPPING_PARAM_NAME).paramValue(groupMappings);
+  }
+
+  @Override
+  protected String getFilterClassname() {
+    return FILTER_CLASSNAME;
+  }
+}
diff --git a/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationAsserterRequestWrapper.java b/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationAsserterRequestWrapper.java
new file mode 100644
index 0000000..6ef7dd0
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationAsserterRequestWrapper.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.filter;
+
+import org.apache.knox.gateway.identityasserter.common.filter.IdentityAsserterHttpServletRequestWrapper;
+import javax.servlet.http.HttpServletRequest;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class NoImpersonationAsserterRequestWrapper extends
+    IdentityAsserterHttpServletRequestWrapper {
+
+  public NoImpersonationAsserterRequestWrapper(
+      HttpServletRequest request, String principal) {
+    super(request, principal);
+  }
+
+  /**
+   * Skip adding doAs as query param
+   * @return
+   */
+  @Override
+  public String getQueryString() {
+    String q = null;
+    Map<String, List<String>> params;
+    try {
+      params = getParams();
+      if (params == null) {
+        params = new LinkedHashMap<>();
+      }
+
+      List<String> principalParamNames = getImpersonationParamNames();
+      params = scrubOfExistingPrincipalParams(params, principalParamNames);
+
+      String encoding = getCharacterEncoding();
+      if (encoding == null) {
+        encoding = Charset.defaultCharset().name();
+      }
+      q = urlEncode(params, encoding);
+    } catch (UnsupportedEncodingException e) {
+      log.unableToGetParamsFromQueryString(e);
+    }
+
+    return q;
+  }
+}
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
new file mode 100644
index 0000000..a09255b
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/src/main/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilter.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+import org.apache.knox.gateway.identityasserter.common.filter.CommonIdentityAssertionFilter;
+
+public class NoImpersonationFilter extends CommonIdentityAssertionFilter {
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    super.init(filterConfig);
+  }
+
+  @Override
+  public String[] mapGroupPrincipals(String mappedPrincipalName, Subject subject) {
+    return mapGroupPrincipalsBase(mappedPrincipalName, subject);
+  }
+
+  @Override
+  public String mapUserPrincipal(String principalName) {
+    return mapUserPrincipalBase(principalName);
+  }
+
+  @Override
+  public HttpServletRequestWrapper wrapHttpServletRequest(
+      ServletRequest request, String mappedPrincipalName) {
+    return new NoImpersonationAsserterRequestWrapper(
+        (HttpServletRequest) request,
+        mappedPrincipalName);
+  }
+}
diff --git a/gateway-provider-identity-assertion-no-doas/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-identity-assertion-no-doas/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 0000000..c5570a1
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ProviderDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##########################################################################
+
+org.apache.knox.gateway.identityasserter.filter.NoImpersonationAsserterDeploymentContributor
\ No newline at end of file
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
new file mode 100644
index 0000000..53f1457
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationFilterTest.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.filter;
+
+import org.apache.knox.gateway.security.GroupPrincipal;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import javax.security.auth.Subject;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import java.security.Principal;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class NoImpersonationFilterTest {
+
+  @Test
+  public void testInitParameters() throws Exception {
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+
+    NoImpersonationFilter filter = new NoImpersonationFilter();
+    Subject subject = new Subject();
+
+    subject.getPrincipals().add(new PrimaryPrincipal("lmccay"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+
+    filter.init(config);
+    String username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    String[] groups = filter.mapGroupPrincipals(username, subject);
+    assertEquals("lmccay", username);
+    assertNull(groups); // means for the caller to use the existing subject groups
+
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.replay( 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);
+    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));
+    assertFalse("group1 WAS found in groups: " + Arrays.toString(mappedGroups), groupFoundIn("group1", mappedGroups));
+
+    subject = new Subject();
+
+    subject.getPrincipals().add(new PrimaryPrincipal("kminder"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(config.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.replay( 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);
+    assertEquals("hdfs", username);
+    assertTrue("group1 not found in groups: " + Arrays.toString(mappedGroups), groupFoundIn("group1", mappedGroups));
+  }
+
+  private boolean groupFoundIn(String expected, String[] mappedGroups) {
+    if (mappedGroups == null) {
+      return false;
+    }
+    for (String mappedGroup : mappedGroups) {
+      if (mappedGroup.equals(expected)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Test
+  public void testContextParameters() throws Exception {
+    // for backward compatibility of old deployment contributor's method
+    // of adding init params to the servlet context instead of to the filter.
+    // There is the possibility that previously deployed topologies will have
+    // init params in web.xml at the context level instead of the filter level.
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+
+    NoImpersonationFilter filter = new NoImpersonationFilter();
+    Subject subject = new Subject();
+
+    subject.getPrincipals().add(new PrimaryPrincipal("lmccay"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+
+    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);
+
+    assertEquals("lmccay", username);
+    assertNull(groups); // means for the caller to use the existing subject groups
+
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(context.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    EasyMock.replay( config );
+    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);
+    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));
+    assertFalse("group1 WAS found in groups: " + Arrays.toString(groups), groupFoundIn("group1", groups));
+
+    subject = new Subject();
+
+    subject.getPrincipals().add(new PrimaryPrincipal("kminder"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+
+    config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("principal.mapping") ).andReturn( "" ).anyTimes();
+    context = EasyMock.createNiceMock(ServletContext.class);
+    EasyMock.expect(config.getServletContext() ).andReturn( context ).anyTimes();
+    EasyMock.expect(context.getInitParameter("principal.mapping") ).andReturn( "lmccay,kminder=hdfs;newuser=mapred" ).anyTimes();
+    EasyMock.expect(context.getInitParameter("group.principal.mapping") ).andReturn( "kminder=group1;lmccay=mrgroup,mrducks" ).anyTimes();
+    EasyMock.replay( config );
+    EasyMock.replay( context );
+    filter.init(config);
+    username = filter.mapUserPrincipal(((Principal) subject.getPrincipals(PrimaryPrincipal.class).toArray()[0]).getName());
+    assertEquals("hdfs", username);
+  }
+}
diff --git a/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationHttpServletRequestWrapperTest.java b/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationHttpServletRequestWrapperTest.java
new file mode 100644
index 0000000..95fafcb
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/src/test/java/org/apache/knox/gateway/identityasserter/filter/NoImpersonationHttpServletRequestWrapperTest.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.identityasserter.filter;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.test.mock.MockHttpServletRequest;
+import org.apache.knox.test.mock.MockServletInputStream;
+import org.junit.After;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertTrue;
+
+public class NoImpersonationHttpServletRequestWrapperTest {
+  @After
+  public void resetSystemProps() {
+    System.setProperty(GatewayConfig.HADOOP_KERBEROS_SECURED, "false");
+  }
+
+  @Test
+  public void testNoUserNameInPostMethod() throws IOException {
+    String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( StandardCharsets.UTF_8 ) ) ) );
+    request.setCharacterEncoding( StandardCharsets.UTF_8.name() );
+    request.setContentType( "application/x-www-form-urlencoded" );
+    request.setMethod("POST");
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+    assertThat( output, containsString( "" ) );
+  }
+
+  @Test
+  public void testNoUserNameInPostMethodWithoutEncoding() throws IOException {
+    String inputBody = "jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( StandardCharsets.UTF_8 ) ) ) );
+    request.setContentType( "application/x-www-form-urlencoded" );
+    request.setMethod("POST");
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+    // make sure principal is not added
+    assertTrue(StringUtils.isBlank(output));
+  }
+
+  @Test
+  public void testOverwriteUserNameInPostMethod() throws IOException {
+    String inputBody = "user.name=input-user&jar=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaWebHCat%2Fhadoop-examples.jar&class=org.apache.org.apache.hadoop.examples.WordCount&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Finput&arg=%2Ftmp%2FGatewayWebHdfsFuncTest%2FtestJavaMapReduceViaTempleton%2Foutput";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setInputStream( new MockServletInputStream( new ByteArrayInputStream( inputBody.getBytes( StandardCharsets.UTF_8 ) ) ) );
+    request.setCharacterEncoding( StandardCharsets.UTF_8.name() );
+    request.setContentType( "application/x-www-form-urlencoded" );
+    request.setMethod("POST");
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+    assertThat( output, containsString( "" ) );
+    assertThat( output, not( containsString( "input-user" ) ) );
+  }
+
+
+  @Test
+  public void testInsertUserNameInQueryString() {
+    String input = "param=value";
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "" ) );
+  }
+
+  @Test
+  public void testInsertNoDoAsInQueryString() {
+    System.setProperty(GatewayConfig.HADOOP_KERBEROS_SECURED, "true");
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString("op=LISTSTATUS&user.name=jack&User.Name=jill&DOas=admin&doas=root");
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+    assertThat(output, is("op=LISTSTATUS"));
+  }
+
+  @Test
+  public void testNoUserNameInNullQueryString() {
+    String input = null;
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "" ) );
+  }
+
+  @Test
+  public void testNoUserNameInNullQueryStringForGET() {
+    String input = null;
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "" ) );
+  }
+
+  @Test
+  public void testNoUserNameInQueryStringForPOST() {
+    String input = null;
+
+    MockHttpServletRequest request = new MockHttpServletRequest();
+    request.setQueryString( input );
+    request.setMethod("POST");
+
+    NoImpersonationAsserterRequestWrapper wrapper
+        = new NoImpersonationAsserterRequestWrapper( request, "output-user" );
+
+    String output = wrapper.getQueryString();
+
+    assertThat( output, containsString( "" ) );
+  }
+}
diff --git a/gateway-provider-identity-assertion-no-doas/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml b/gateway-provider-identity-assertion-no-doas/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
new file mode 100644
index 0000000..cf28b92
--- /dev/null
+++ b/gateway-provider-identity-assertion-no-doas/src/test/resources/org/apache/knox/gateway/identityasserter/function/UsernameFunctionProcessorTest/rewrite.xml
@@ -0,0 +1,24 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<rules>
+
+    <rule name="test-rule-username">
+        <match pattern="*://{host}:{port}/{path=**}?{**}"/>
+        <rewrite template="test-output-scheme://{host}:{port}/test-output-path/{path=**}?user.name={$username}?{**}?test-query-output-name=test-query-output-value"/>
+    </rule>
+
+</rules>
\ No newline at end of file
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index aafd9e6..e86449c 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -385,6 +385,10 @@
         </dependency>
         <dependency>
             <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-provider-identity-assertion-no-doas</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
             <artifactId>gateway-provider-ha</artifactId>
         </dependency>
 
diff --git a/pom.xml b/pom.xml
index 888701b..adeb0d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,6 +99,7 @@
         <module>gateway-provider-identity-assertion-regex</module>
         <module>gateway-provider-identity-assertion-switchcase</module>
         <module>gateway-provider-identity-assertion-pseudo</module>
+        <module>gateway-provider-identity-assertion-no-doas</module>
         <module>gateway-provider-jersey</module>
         <module>gateway-provider-ha</module>
         <module>gateway-service-admin</module>
@@ -979,6 +980,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.knox</groupId>
+                <artifactId>gateway-provider-identity-assertion-no-doas</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.knox</groupId>
                 <artifactId>gateway-provider-rewrite</artifactId>
                 <version>${project.version}</version>
             </dependency>