diff --git a/doc/source/configuration/settings.rst b/doc/source/configuration/settings.rst index 1a844f1cb1..61cc0f7429 100644 --- a/doc/source/configuration/settings.rst +++ b/doc/source/configuration/settings.rst @@ -1565,6 +1565,20 @@ Default: ``None`` Allows to specify a callback to the IdP to cleanup the SSO resources. Once the user logs out it will redirect to the IdP log out method. +WEBSSO_KEYSTONE_URL +----------------------- + +.. versionadded:: 15.0.0(Stein) + +Default: None + +The full auth URL for the Keystone endpoint used for web single-sign-on +authentication. Use this when ``OPENSTACK_KEYSTONE_URL`` is set to an internal +Keystone endpoint and is not reachable from the external network where the +identity provider lives. This URL will take precedence over +``OPENSTACK_KEYSTONE_URL`` if the login choice is an external +identity provider (IdP). + Neutron ------- diff --git a/openstack_auth/tests/unit/test_auth.py b/openstack_auth/tests/unit/test_auth.py index b2f0179f1c..119464d9fc 100644 --- a/openstack_auth/tests/unit/test_auth.py +++ b/openstack_auth/tests/unit/test_auth.py @@ -16,6 +16,7 @@ import uuid from django.conf import settings from django.contrib import auth from django import test +from django.test.utils import override_settings from django.urls import reverse from keystoneauth1 import exceptions as keystone_exceptions from keystoneauth1.identity import v2 as v2_auth @@ -1195,6 +1196,25 @@ class OpenStackAuthTestsWebSSO(OpenStackAuthTestsMixin, self.assertRedirects(response, redirect_url, status_code=302, target_status_code=404) + @override_settings(WEBSSO_KEYSTONE_URL='http://keystone-public:5000/v3') + def test_websso_redirect_using_websso_keystone_url(self): + origin = 'http://testserver/auth/websso/' + protocol = 'oidc' + redirect_url = ('%s/auth/OS-FEDERATION/identity_providers/%s' + '/protocols/%s/websso?origin=%s' % + (settings.WEBSSO_KEYSTONE_URL, self.idp_id, + protocol, origin)) + + form_data = {'auth_type': self.idp_oidc_id, + 'region': settings.OPENSTACK_KEYSTONE_URL} + url = reverse('login') + + # POST to the page and redirect to keystone. + response = self.client.post(url, form_data) + # verify that the request was sent back to WEBSSO_KEYSTONE_URL + self.assertRedirects(response, redirect_url, status_code=302, + target_status_code=404) + def test_websso_login(self): projects = [self.data.project_one, self.data.project_two] domains = [] diff --git a/openstack_auth/utils.py b/openstack_auth/utils.py index c08cdea3a4..70ccfdd5ec 100644 --- a/openstack_auth/utils.py +++ b/openstack_auth/utils.py @@ -191,7 +191,8 @@ def get_websso_url(request, auth_url, websso_auth): :param request: Django http request object. :type request: django.http.HttpRequest :param auth_url: Keystone endpoint configured in the horizon setting. - The value is derived from: + If WEBSSO_KEYSTONE_URL is defined, its value will be + used. Otherwise, the value is derived from: - OPENSTACK_KEYSTONE_URL - AVAILABLE_REGIONS :type auth_url: string diff --git a/openstack_auth/views.py b/openstack_auth/views.py index 62ed7028cb..bac06edf82 100644 --- a/openstack_auth/views.py +++ b/openstack_auth/views.py @@ -71,7 +71,8 @@ def login(request, template_name=None, extra_context=None, **kwargs): if request.method == 'POST': auth_type = request.POST.get('auth_type', 'credentials') if utils.is_websso_enabled() and auth_type != 'credentials': - auth_url = request.POST.get('region') + auth_url = getattr(settings, 'WEBSSO_KEYSTONE_URL', + request.POST.get('region')) url = utils.get_websso_url(request, auth_url, auth_type) return shortcuts.redirect(url) diff --git a/openstack_dashboard/local/local_settings.py.example b/openstack_dashboard/local/local_settings.py.example index 9ac3bcdbd2..ba36ff1b95 100644 --- a/openstack_dashboard/local/local_settings.py.example +++ b/openstack_dashboard/local/local_settings.py.example @@ -247,6 +247,14 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_" # variable. #WEBSSO_DEFAULT_REDIRECT_LOGOUT = None +# If set this URL will be used for web single-sign-on authentication +# instead of OPENSTACK_KEYSTONE_URL. This is needed in the deployment +# scenarios where network segmentation is used per security requirement. +# In this case, the controllers are not reachable from public network. +# Therefore, user's browser will not be able to access OPENSTACK_KEYSTONE_URL +# if it is set to the internal endpoint. +#WEBSSO_KEYSTONE_URL = "http://keystone-public.example.com/v3" + # The Keystone Provider drop down uses Keystone to Keystone federation # to switch between Keystone service providers. # Set display name for Identity Provider (dropdown display name) diff --git a/releasenotes/notes/support-websso_keystone_url-f663bbf40a5855c9.yaml b/releasenotes/notes/support-websso_keystone_url-f663bbf40a5855c9.yaml new file mode 100644 index 0000000000..15e01369c2 --- /dev/null +++ b/releasenotes/notes/support-websso_keystone_url-f663bbf40a5855c9.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + [:bug:`1544703`] Add a new optional WEBSSO_KEYSTONE_URL property to + facilitate WEBSSO deployments where network segmentation is used per + security requirement. In this case, the controllers are not reachable + from public network. Therefore, user's browser will not be able to access + OPENSTACK_KEYSTONE_URL if it is set to the internal endpoint.