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 1e230d09b KNOX-3226 - Add RemoteAuthProivder Integration Test (#1125)
1e230d09b is described below

commit 1e230d09b28e8ae9b90f0b2029286e3900dda59a
Author: Sandeep MorĂ© <[email protected]>
AuthorDate: Mon Dec 8 19:28:10 2025 -0500

    KNOX-3226 - Add RemoteAuthProivder Integration Test (#1125)
    
    * KNOX-3226 - Add RemoteAuthProivder Integration Test
---
 .github/workflows/build/Dockerfile                 |   2 +
 .github/workflows/build/Dockerfile.local           |   2 +
 .../workflows/build/conf/topologies/remoteauth.xml |  63 ++++++++++++
 .github/workflows/publish-test-results.yml         |   2 +-
 .github/workflows/tests/requirements.txt           |   2 +-
 .github/workflows/tests/test_remote_auth.py        | 106 +++++++++++++++++++++
 6 files changed, 175 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/build/Dockerfile 
b/.github/workflows/build/Dockerfile
index 5d6056aad..441cf1ba4 100644
--- a/.github/workflows/build/Dockerfile
+++ b/.github/workflows/build/Dockerfile
@@ -37,6 +37,8 @@ ADD master /knox-runtime/data/security/master
 ADD gateway-site.xml /knox-runtime/conf/gateway-site.xml
 ADD conf/topologies/knoxtoken.xml /knox-runtime/conf/topologies/knoxtoken.xml
 ADD conf/topologies/knoxldap.xml /knox-runtime/conf/topologies/knoxldap.xml
+ADD conf/topologies/remoteauth.xml /knox-runtime/conf/topologies/remoteauth.xml
+
 ADD conf/topologies/health.xml /knox-runtime/conf/topologies/health.xml
 
 RUN chown -R gateway /knox-runtime/
diff --git a/.github/workflows/build/Dockerfile.local 
b/.github/workflows/build/Dockerfile.local
index ba95ae168..73e1c9bfe 100644
--- a/.github/workflows/build/Dockerfile.local
+++ b/.github/workflows/build/Dockerfile.local
@@ -59,6 +59,8 @@ ADD gateway-site.xml /knox-runtime/conf/gateway-site.xml
 ADD conf/topologies/knoxtoken.xml /knox-runtime/conf/topologies/knoxtoken.xml
 ADD conf/topologies/health.xml /knox-runtime/conf/topologies/health.xml
 ADD conf/topologies/knoxldap.xml /knox-runtime/conf/topologies/knoxldap.xml
+ADD conf/topologies/remoteauth.xml /knox-runtime/conf/topologies/remoteauth.xml
+
 
 RUN chown -R gateway /knox-runtime/
 
diff --git a/.github/workflows/build/conf/topologies/remoteauth.xml 
b/.github/workflows/build/conf/topologies/remoteauth.xml
new file mode 100644
index 000000000..2587ec506
--- /dev/null
+++ b/.github/workflows/build/conf/topologies/remoteauth.xml
@@ -0,0 +1,63 @@
+<!--
+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.
+-->
+<topology>
+    <gateway>
+        <provider>
+            <role>authentication</role>
+            <name>RemoteAuthProvider</name>
+            <enabled>true</enabled>
+            <param>
+                <name>remote.auth.url</name>
+                
<value>https://localhost:8443/gateway/knoxldap/auth/api/v1/pre</value>
+            </param>
+            <param>
+                <name>remote.auth.include.headers</name>
+                <value>Authorization</value>
+            </param>
+            <param>                                                            
                 
+                <name>remote.auth.expire.after</name>                          
                          
+                <value>5</value>                                               
                                                                                
                            
+            </param> 
+            <param>
+                <name>remote.auth.user.header</name>
+                <value>x-knox-actor-username</value>
+            </param>
+            <param>
+                <name>remote.auth.group.header</name>
+                <value>x-knox-actor-groups-*</value>
+            </param>
+            <param>
+                <name>remote.auth.truststore.path</name>
+                <value></value> 
+                <!-- Empty path triggers fallback to gateway 
keystore/truststore which trusts the self-signed cert -->
+            </param>
+        </provider>
+        <provider>
+            <role>identity-assertion</role>
+            <name>Default</name>
+            <enabled>true</enabled>
+        </provider>
+    </gateway>
+    <service>
+        <role>KNOX-AUTH-SERVICE</role>
+        <param>
+            <name>ignore.additional.path</name>
+            <value>true</value>
+        </param>
+    </service>
+</topology>
diff --git a/.github/workflows/publish-test-results.yml 
b/.github/workflows/publish-test-results.yml
index 54627b00c..0f584f599 100644
--- a/.github/workflows/publish-test-results.yml
+++ b/.github/workflows/publish-test-results.yml
@@ -36,7 +36,7 @@ jobs:
       - name: Download and Extract Artifacts
         uses: actions/download-artifact@v4
         with:
-          run_id: ${{ github.event.workflow_run.id }}
+          run-id: ${{ github.event.workflow_run.id }}
           github-token: ${{ secrets.GITHUB_TOKEN }}
           path: artifacts
 
diff --git a/.github/workflows/tests/requirements.txt 
b/.github/workflows/tests/requirements.txt
index b328d990f..9967c535d 100644
--- a/.github/workflows/tests/requirements.txt
+++ b/.github/workflows/tests/requirements.txt
@@ -1,2 +1,2 @@
-requests==2.32.3
+requests==2.32.4
 pytest==8.3.4
diff --git a/.github/workflows/tests/test_remote_auth.py 
b/.github/workflows/tests/test_remote_auth.py
new file mode 100644
index 000000000..38cf18054
--- /dev/null
+++ b/.github/workflows/tests/test_remote_auth.py
@@ -0,0 +1,106 @@
+# 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.
+import os
+import unittest
+import requests
+import urllib3
+from requests.auth import HTTPBasicAuth
+
+########################################################
+# This test is verifying the behavior of the RemoteAuthProvider.
+# It is using the 'auth/api/v1/pre' endpoint to get the actor ID and group 
headers.
+# It is using the 'guest' user to get the guest user headers.
+# It is using the 'admin' user to get the admin user headers.
+# It is verifying that the actor ID and group headers are correct.
+# It is verifying that the actor ID and group headers are not empty.
+# It is verifying that the actor ID and group headers are not None.
+########################################################
+# Suppress InsecureRequestWarning
+urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
+
+class TestRemoteAuth(unittest.TestCase):
+    def setUp(self):
+        self.base_url = os.environ.get("KNOX_GATEWAY_URL", 
"https://localhost:8443/";)
+        if not self.base_url.endswith("/"):
+            self.base_url += "/"
+        self.topology_url = self.base_url + 
"gateway/remoteauth/auth/api/v1/pre"
+
+    def test_remote_auth_success(self):
+        """
+        Verify that valid credentials result in successful authentication
+        and correct identity assertion using knoxldap as remote auth.
+        """
+        print(f"\nTesting remote auth success against {self.topology_url}")
+        # The RemoteAuthFilter forwards Authorization header to knoxldap.
+        # knoxldap accepts guest:guest-password
+        response = requests.get(
+            self.topology_url,
+            auth=HTTPBasicAuth('guest', 'guest-password'),
+            verify=False,
+            timeout=30
+        )
+        print(f"Status Code: {response.status_code}")
+        print(f"Headers: {response.headers}")
+        self.assertEqual(response.status_code, 200)
+
+        # RemoteAuthFilter sets principal from x-knox-actor-username (guest)
+        # KNOX-AUTH-SERVICE (pre endpoint) echoes principal in X-Knox-Actor-ID 
(default)
+        self.assertIn('X-Knox-Actor-ID', response.headers)
+        self.assertEqual(response.headers['X-Knox-Actor-ID'], 'guest')
+
+    def test_remote_auth_admin_groups(self):
+        """
+        Verify admin user gets multiple groups from knoxldap mapping
+        """
+        print(f"\nTesting remote auth admin against {self.topology_url}")
+        response = requests.get(
+            self.topology_url,
+            auth=HTTPBasicAuth('admin', 'admin-password'),
+            verify=False,
+            timeout=30
+        )
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.headers['X-Knox-Actor-ID'], 'admin')
+
+        # knoxldap maps admin to: 
longGroupName1,longGroupName2,longGroupName3,longGroupName4
+        # RemoteAuthFilter picks these up from x-knox-actor-groups-*
+        # And KNOX-AUTH-SERVICE echoes them back in X-Knox-Actor-Groups-*
+        
+        group_headers = [h for h in response.headers if 
h.lower().startswith('x-knox-actor-groups')]
+        all_groups = []
+        for h in group_headers:
+            all_groups.extend(response.headers[h].split(','))
+        
+        print(f"Found groups: {all_groups}")
+        self.assertIn('longGroupName1', all_groups)
+        self.assertIn('longGroupName2', all_groups)
+
+    def test_remote_auth_failure(self):
+        """
+        Verify invalid credentials result in 401
+        """
+        print(f"\nTesting remote auth failure against {self.topology_url}")
+        response = requests.get(
+            self.topology_url,
+            auth=HTTPBasicAuth('baduser', 'badpass'),
+            verify=False,
+            timeout=30
+        )
+        print(f"Status Code: {response.status_code}")
+        # When remote auth fails (knoxldap returns 401), RemoteAuthFilter 
should return 401
+        self.assertEqual(response.status_code, 401)
+
+if __name__ == '__main__':
+    unittest.main()

Reply via email to