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()