[horizon] fix https login

When the stx-openstack is deployed with https enabled (certificate and
domain_name setup), the horizon login is failing and the following
message is displayed: "Cookies may be turned off. Make sure cookies are
enabled and try again". Checking horizon log, it's possible to see that
auth request is failing with "Origin checking failed".

This is hapenning because Django version used by horizon was upversioned
from Django 3.2 to Django 4.2 for stx-opentack caracal [1]. After
version 4.0, CSFR protection implemented by Django consults the Origin
header and requires the CSRF_TRUSTED_ORIGINS config to be defined [2].

To fix this issue, this change cherry-picks the changes [3] and [4]
already merged to the openstack-helm repos, and updates the horizon
plugin to dynamically set the CSRF_TRUSTED_ORIGINS config based on the
current definitions for endpoint_domain and serviceEndpointPattern [5].

[1]https://review.opendev.org/c/starlingx/root/+/940739
[2]https://docs.djangoproject.com/en/4.2/releases/4.0/#csrf
[3]https://review.opendev.org/c/openstack/openstack-helm/+/922755
[4]https://review.opendev.org/c/openstack/openstack-helm/+/922973
[5]https://review.opendev.org/c/starlingx/openstack-armada-app/+/931836

Test Plan:
[PASS] build stx-openstack tarball

HTTPS Test Case:
[PASS] install openstack with certificate and domain_name setup
[PASS] Access horizon via fqdn (e.g.: https://horizon-<domain>.com/)

HTTP Test Case:
[PASS] install openstack without certificate and domain_name setup
[PASS] Access horizon via ip:port (e.g.: http://<ip>:<port>/)

Closes-Bug: #2103799

Change-Id: Icd4820e16c1faa9247dd675b1dc24f6e5a343a25
Signed-off-by: Alex Figueiredo <alex.fernandesfigueiredo@windriver.com>
This commit is contained in:
Alex Figueiredo 2025-03-21 10:51:37 -03:00
parent 8709072253
commit 2f7492a0b1
5 changed files with 109 additions and 0 deletions

View File

@ -0,0 +1,42 @@
From 776b29a26da2fae6f2aa575f401f3f4da873ab1c Mon Sep 17 00:00:00 2001
From: Nicholas Kuechler <nkuechler@gmail.com>
Date: Tue, 25 Jun 2024 11:53:09 -0500
Subject: [PATCH 21/22] horizon: Allows setting Django's CSRF_TRUSTED_ORIGINS
in helm values file
Change-Id: I8930b8df7c068c63ee19a7f3a29c66ef2b3ee820
[ Cherry-picked to stx-openstack caracal ]
Test Plan:
[PASS] build stx-openstack tarball
Related-Bug: #2103799
Signed-off-by: Alex Figueiredo <alex.fernandesfigueiredo@windriver.com>
---
horizon/values.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/horizon/values.yaml b/horizon/values.yaml
index 98f8ede2..6362ad87 100644
--- a/horizon/values.yaml
+++ b/horizon/values.yaml
@@ -217,6 +217,7 @@ conf:
show_openrc_file: "True"
csrf_cookie_secure: "False"
csrf_cookie_httponly: "False"
+ csrf_trusted_origins: []
enforce_password_check: "True"
# Set enable_pwd_validator to true to enforce password validator settings.
enable_pwd_validator: false
@@ -312,6 +313,9 @@ conf:
SESSION_COOKIE_HTTPONLY = {{ .Values.conf.horizon.local_settings.config.session_cookie_httponly }}
+ # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins
+ CSRF_TRUSTED_ORIGINS = {{ .Values.conf.horizon.local_settings.config.csrf_trusted_origins }}
+
# Overrides for OpenStack API versions. Use this setting to force the
# OpenStack dashboard to use a specific API version for a given service API.
# Versions specified here should be integers or floats, not strings.
--
2.34.1

View File

@ -0,0 +1,35 @@
From b49bc7619031cd35eb3b90484b7f8716eba91887 Mon Sep 17 00:00:00 2001
From: Nicholas Kuechler <nkuechler@gmail.com>
Date: Thu, 27 Jun 2024 13:57:29 -0500
Subject: [PATCH 22/22] horizon: fix templating of list of strings for
CSRF_TRUSTED_ORIGINS
Change-Id: I740cd48103950e1599e77db46c7e4d9e65677177
[ Cherry-picked to stx-openstack caracal ]
Test Plan:
[PASS] build stx-openstack tarball
[PASS] install openstack with certificate and domain_name setup, enabling HTTPs
[PASS] Access horizon via fqdn (ex: https://horizon-<domain>.com/)
Related-Bug: #2103799
Signed-off-by: Alex Figueiredo <alex.fernandesfigueiredo@windriver.com>
---
horizon/values.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/horizon/values.yaml b/horizon/values.yaml
index 6362ad87..fbf465f5 100644
--- a/horizon/values.yaml
+++ b/horizon/values.yaml
@@ -314,7 +314,7 @@ conf:
SESSION_COOKIE_HTTPONLY = {{ .Values.conf.horizon.local_settings.config.session_cookie_httponly }}
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins
- CSRF_TRUSTED_ORIGINS = {{ .Values.conf.horizon.local_settings.config.csrf_trusted_origins }}
+ CSRF_TRUSTED_ORIGINS = [{{ include "helm-toolkit.utils.joinListWithCommaAndSingleQuotes" .Values.conf.horizon.local_settings.config.csrf_trusted_origins }}]
# Overrides for OpenStack API versions. Use this setting to force the
# OpenStack dashboard to use a specific API version for a given service API.
--
2.34.1

View File

@ -18,3 +18,5 @@
0018-Define-values-for-NetApp-volume-backend.patch
0019-Add-cluster-host-ip-env-var-to-nova.patch
0020-Add-service-role-to-neutron-policy.patch
0021-horizon-Allows-setting-Django-s-CSRF_TRUSTED_ORIGINS.patch
0022-horizon-fix-templating-of-list-of-strings-for-CSRF_T.patch

View File

@ -10,6 +10,7 @@ from sysinv.helm import common
from k8sapp_openstack.common import constants as app_constants
from k8sapp_openstack.helm import openstack
from k8sapp_openstack.utils import get_services_fqdn_pattern
class HorizonHelm(openstack.OpenstackBaseHelm):
@ -116,6 +117,30 @@ class HorizonHelm(openstack.OpenstackBaseHelm):
'https_enabled': 'True',
})
# After version 4.0, CSFR protection implemented by Django consults
# the Origin header and requires the CSRF_TRUSTED_ORIGINS config to be
# defined.
# Ref.: https://docs.djangoproject.com/en/4.2/releases/4.0/#csrf
csrf_trusted_origins = []
# Get the openstack endpoint public domain name
endpoint_domain = self._get_service_parameter(
constants.SERVICE_TYPE_OPENSTACK,
constants.SERVICE_PARAM_SECTION_OPENSTACK_HELM,
constants.SERVICE_PARAM_NAME_ENDPOINT_DOMAIN)
if endpoint_domain is not None:
# Define endpoint domain based on pattern
fqdn_pattern = get_services_fqdn_pattern()
service_endpoint = fqdn_pattern.format(
service_name=self.SERVICE_NAME,
endpoint_domain=str(endpoint_domain.value),
).lower()
csrf_trusted_origins.append("%s://%s" %
(self._get_public_protocol(),
service_endpoint))
local_settings_config.update({
'csrf_trusted_origins': csrf_trusted_origins,
})
lockout_retries = self._get_service_parameter('horizon', 'auth', 'lockout_retries')
lockout_seconds = self._get_service_parameter('horizon', 'auth', 'lockout_seconds')
if lockout_retries is not None and lockout_seconds is not None:

View File

@ -122,6 +122,8 @@ conf:
keystone_multidomain_support: 'False'
# OpenStack Help Documentation URL
help_url: 'http://docs.openstack.org/2024.1/'
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins
csrf_trusted_origins: []
# Pass any settings to the end of local_settings.py
raw: { }
template: |
@ -169,6 +171,9 @@ conf:
#CSRF_COOKIE_SECURE = True
#SESSION_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins
CSRF_TRUSTED_ORIGINS = [{{ include "helm-toolkit.utils.joinListWithCommaAndSingleQuotes" .Values.conf.horizon.local_settings.config.csrf_trusted_origins }}]
# Overrides for OpenStack API versions. Use this setting to force the
# OpenStack dashboard to use a specific API version for a given service API.
# Versions specified here should be integers or floats, not strings.