From 3f843542de44f96e467e98b96f4429fe01c56412 Mon Sep 17 00:00:00 2001 From: Jeremiah Millay Date: Sat, 21 Oct 2023 21:38:31 -0400 Subject: [PATCH 1/3] Allow st2web proxy auth mode to work in HA environments --- CHANGELOG.rst | 3 +++ conf/HA/nginx/st2.conf.blueprint.sample | 1 + conf/HA/nginx/st2.conf.controller.sample | 1 + conf/nginx/st2.conf | 1 + st2auth/st2auth/controllers/v1/auth.py | 6 +++++- st2common/st2common/openapi.yaml | 4 ++++ st2common/st2common/openapi.yaml.j2 | 4 ++++ 7 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 92ca775ac4..d9efe84527 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,9 @@ in development Fixed ~~~~~ +* Fix proxy auth mode in HA environments #5766 + Contributed by @floatingstatic + * Fix CI usses #6015 Contributed by Amanda McGuinness (@amanda11 intive) diff --git a/conf/HA/nginx/st2.conf.blueprint.sample b/conf/HA/nginx/st2.conf.blueprint.sample index 91f3cdafd6..482118f6a8 100644 --- a/conf/HA/nginx/st2.conf.blueprint.sample +++ b/conf/HA/nginx/st2.conf.blueprint.sample @@ -96,6 +96,7 @@ server { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-User $remote_user; proxy_pass_header Authorization; proxy_set_header Connection ''; diff --git a/conf/HA/nginx/st2.conf.controller.sample b/conf/HA/nginx/st2.conf.controller.sample index b7108f56c8..9bb721cc80 100644 --- a/conf/HA/nginx/st2.conf.controller.sample +++ b/conf/HA/nginx/st2.conf.controller.sample @@ -118,6 +118,7 @@ server { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-User $remote_user; proxy_pass_header Authorization; proxy_set_header Connection ''; diff --git a/conf/nginx/st2.conf b/conf/nginx/st2.conf index fc2243068a..6e83d18cbe 100644 --- a/conf/nginx/st2.conf +++ b/conf/nginx/st2.conf @@ -146,6 +146,7 @@ server { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-User $remote_user; proxy_pass_header Authorization; proxy_set_header Connection ''; diff --git a/st2auth/st2auth/controllers/v1/auth.py b/st2auth/st2auth/controllers/v1/auth.py index c77546141f..b072d6c2d0 100644 --- a/st2auth/st2auth/controllers/v1/auth.py +++ b/st2auth/st2auth/controllers/v1/auth.py @@ -67,6 +67,10 @@ def post(self, request, **kwargs): if "x-forwarded-for" in kwargs: headers["x-forwarded-for"] = kwargs.pop("x-forwarded-for") + remote_user = kwargs.pop("remote_user", None) + if not remote_user and "x-forwarded-user" in kwargs: + remote_user = kwargs.pop("x-forwarded-user", None) + authorization = kwargs.pop("authorization", None) if authorization: authorization = tuple(authorization.split(" ")) @@ -75,7 +79,7 @@ def post(self, request, **kwargs): request=request, headers=headers, remote_addr=kwargs.pop("remote_addr", None), - remote_user=kwargs.pop("remote_user", None), + remote_user=remote_user, authorization=authorization, **kwargs, ) diff --git a/st2common/st2common/openapi.yaml b/st2common/st2common/openapi.yaml index e86e42727d..93d4bcdec6 100644 --- a/st2common/st2common/openapi.yaml +++ b/st2common/st2common/openapi.yaml @@ -4444,6 +4444,10 @@ paths: in: header description: set externally to indicate real source of the request type: string + - name: x-forwarded-user + in: header + description: set externally to indicate the remote username in the case of proxy auth + type: string - name: request in: body description: Lifespan of the token diff --git a/st2common/st2common/openapi.yaml.j2 b/st2common/st2common/openapi.yaml.j2 index f053f0f3d0..6b10362640 100644 --- a/st2common/st2common/openapi.yaml.j2 +++ b/st2common/st2common/openapi.yaml.j2 @@ -4440,6 +4440,10 @@ paths: in: header description: set externally to indicate real source of the request type: string + - name: x-forwarded-user + in: header + description: set externally to indicate the remote username in the case of proxy auth + type: string - name: request in: body description: Lifespan of the token From ea2fedaf695c9775def43c54605924cf5c1b4464 Mon Sep 17 00:00:00 2001 From: Jeremiah Millay Date: Sun, 22 Oct 2023 11:42:22 -0400 Subject: [PATCH 2/3] add test case for proxy auth user headers --- st2auth/tests/unit/controllers/v1/test_token.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/st2auth/tests/unit/controllers/v1/test_token.py b/st2auth/tests/unit/controllers/v1/test_token.py index e56c7e9acb..ea0ff403db 100644 --- a/st2auth/tests/unit/controllers/v1/test_token.py +++ b/st2auth/tests/unit/controllers/v1/test_token.py @@ -97,6 +97,21 @@ def _test_token_post(self, path=TOKEN_V1_PATH): self.assertLess(actual_expiry, expected_expiry) return response + def test_token_post_proxy_user(self): + headers = { + "X-Forwarded-For": "192.0.2.1", + "X-Forwarded-User": "testuser" + } + response = self.app.post_json( + TOKEN_V1_PATH, {}, + headers=headers, + expect_errors=False, + extra_environ={"REMOTE_USER": ""}, + ) + self.assertEqual(response.status_int, 201) + self.assertIsNotNone(response.json["token"]) + self.assertEqual(response.json["user"], "testuser") + def test_token_post_unauthorized(self): response = self.app.post_json( TOKEN_V1_PATH, {}, expect_errors=True, extra_environ={"REMOTE_USER": ""} From 5321ece1d61ae294d6f865cc1c19e36ec1fa9d8c Mon Sep 17 00:00:00 2001 From: Jeremiah Millay Date: Sun, 22 Oct 2023 11:46:47 -0400 Subject: [PATCH 3/3] black --- st2auth/tests/unit/controllers/v1/test_token.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/st2auth/tests/unit/controllers/v1/test_token.py b/st2auth/tests/unit/controllers/v1/test_token.py index ea0ff403db..95bed14c99 100644 --- a/st2auth/tests/unit/controllers/v1/test_token.py +++ b/st2auth/tests/unit/controllers/v1/test_token.py @@ -98,12 +98,10 @@ def _test_token_post(self, path=TOKEN_V1_PATH): return response def test_token_post_proxy_user(self): - headers = { - "X-Forwarded-For": "192.0.2.1", - "X-Forwarded-User": "testuser" - } + headers = {"X-Forwarded-For": "192.0.2.1", "X-Forwarded-User": "testuser"} response = self.app.post_json( - TOKEN_V1_PATH, {}, + TOKEN_V1_PATH, + {}, headers=headers, expect_errors=False, extra_environ={"REMOTE_USER": ""},