Allow to specify redirections on single IdP scenarios
In scenarios where the cloud operators have only a single Identity Provider, we can have a default redirection to remove unnecessary user clicks and improve user experience. Closes-bug: #1784368 Change-Id: I251703dcaeac43174fbcba7e0658c6f92098b2e0
This commit is contained in:
parent
a4443f4be7
commit
7fc8018956
@ -1522,6 +1522,49 @@ Default: ``"credentials"``
|
||||
Specifies the default authentication mechanism. When user lands on the login
|
||||
page, this is the first choice they will see.
|
||||
|
||||
WEBSSO_DEFAULT_REDIRECT
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 15.0.0(Stein)
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Allows to redirect on login to the IdP provider defined on PROTOCOL and REGION
|
||||
In cases you have a single IdP providing websso, in order to improve user
|
||||
experience, you can redirect on the login page to the IdP directly by
|
||||
specifying WEBSSO_DEFAULT_REDIRECT_PROTOCOL and WEBSSO_DEFAULT_REDIRECT_REGION
|
||||
variables.
|
||||
|
||||
WEBSSO_DEFAULT_REDIRECT_PROTOCOL
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 15.0.0(Stein)
|
||||
|
||||
Default: ``None``
|
||||
|
||||
Allows to specify the protocol for the IdP to contact if the
|
||||
WEBSSO_DEFAULT_REDIRECT is set to True
|
||||
|
||||
WEBSSO_DEFAULT_REDIRECT_REGION
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 15.0.0(Stein)
|
||||
|
||||
Default: ``OPENSTACK_KEYSTONE_URL``
|
||||
|
||||
Allows to specify thee region of the IdP to contact if the
|
||||
WEBSSO_DEFAULT_REDIRECT is set to True
|
||||
|
||||
WEBSSO_DEFAULT_REDIRECT_LOGOUT
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 15.0.0(Stein)
|
||||
|
||||
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.
|
||||
|
||||
Neutron
|
||||
-------
|
||||
|
||||
|
@ -1237,4 +1237,33 @@ class OpenStackAuthTestsWebSSO(OpenStackAuthTestsMixin,
|
||||
response = self.client.post(url, form_data)
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
|
||||
|
||||
def test_websso_login_default_redirect(self):
|
||||
origin = 'http://testserver/auth/websso/'
|
||||
protocol = 'oidc'
|
||||
redirect_url = ('%s/auth/OS-FEDERATION/websso/%s?origin=%s' %
|
||||
(settings.OPENSTACK_KEYSTONE_URL, protocol, origin))
|
||||
|
||||
settings.WEBSSO_DEFAULT_REDIRECT = True
|
||||
settings.WEBSSO_DEFAULT_REDIRECT_PROTOCOL = 'oidc'
|
||||
settings.WEBSSO_DEFAULT_REDIRECT_REGION = (
|
||||
settings.OPENSTACK_KEYSTONE_URL)
|
||||
|
||||
url = reverse('login')
|
||||
|
||||
# POST to the page and redirect to keystone.
|
||||
response = self.client.get(url)
|
||||
self.assertRedirects(response, redirect_url, status_code=302,
|
||||
target_status_code=404)
|
||||
|
||||
def test_websso_logout_default_redirect(self):
|
||||
settings.WEBSSO_DEFAULT_REDIRECT = True
|
||||
settings.WEBSSO_DEFAULT_REDIRECT_LOGOUT = 'http://idptest/logout'
|
||||
|
||||
url = reverse('logout')
|
||||
|
||||
# POST to the page and redirect to logout method from idp.
|
||||
response = self.client.get(url)
|
||||
self.assertRedirects(response, settings.WEBSSO_DEFAULT_REDIRECT_LOGOUT,
|
||||
status_code=302, target_status_code=301)
|
||||
|
||||
load_tests = load_tests_apply_scenarios
|
||||
|
@ -12,6 +12,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.views import generic
|
||||
|
||||
from openstack_auth import utils
|
||||
from openstack_auth import views
|
||||
@ -33,4 +34,8 @@ urlpatterns = [
|
||||
]
|
||||
|
||||
if utils.is_websso_enabled():
|
||||
urlpatterns.append(url(r"^websso/$", views.websso, name='websso'))
|
||||
urlpatterns += [
|
||||
url(r"^websso/$", views.websso, name='websso'),
|
||||
url(r"^error/$",
|
||||
generic.TemplateView.as_view(template_name="403.html"))
|
||||
]
|
||||
|
@ -38,6 +38,16 @@ def set_session_from_user(request, user):
|
||||
request.user = user
|
||||
|
||||
|
||||
def unset_session_user_variables(request):
|
||||
request.session['token'] = None
|
||||
request.session['user_id'] = None
|
||||
request.session['region_endpoint'] = None
|
||||
request.session['services_region'] = None
|
||||
# Update the user object cached in the request
|
||||
request._cached_user = None
|
||||
request.user = None
|
||||
|
||||
|
||||
def create_user_from_token(request, token, endpoint, services_region=None):
|
||||
# if the region is provided, use that, otherwise use the preferred region
|
||||
svc_region = services_region or \
|
||||
|
@ -146,6 +146,30 @@ def is_websso_enabled():
|
||||
return websso_enabled and keystonev3_plus
|
||||
|
||||
|
||||
def is_websso_default_redirect():
|
||||
"""Checks if the websso default redirect is available.
|
||||
|
||||
As with websso, this is only supported in Keystone version 3.
|
||||
"""
|
||||
websso_default_redirect = getattr(settings,
|
||||
'WEBSSO_DEFAULT_REDIRECT', False)
|
||||
keystonev3_plus = (get_keystone_version() >= 3)
|
||||
return websso_default_redirect and keystonev3_plus
|
||||
|
||||
|
||||
def get_websso_default_redirect_protocol():
|
||||
return getattr(settings, 'WEBSSO_DEFAULT_REDIRECT_PROTOCOL', None)
|
||||
|
||||
|
||||
def get_websso_default_redirect_region():
|
||||
return getattr(settings, 'WEBSSO_DEFAULT_REDIRECT_REGION',
|
||||
settings.OPENSTACK_KEYSTONE_URL)
|
||||
|
||||
|
||||
def get_websso_default_redirect_logout():
|
||||
return getattr(settings, 'WEBSSO_DEFAULT_REDIRECT_LOGOUT', None)
|
||||
|
||||
|
||||
def build_absolute_uri(request, relative_url):
|
||||
"""Ensure absolute_uri are relative to WEBROOT."""
|
||||
webroot = getattr(settings, 'WEBROOT', '')
|
||||
|
@ -55,6 +55,17 @@ LOG = logging.getLogger(__name__)
|
||||
def login(request, template_name=None, extra_context=None, **kwargs):
|
||||
"""Logs a user in using the :class:`~openstack_auth.forms.Login` form."""
|
||||
|
||||
# If the user enabled websso and the default redirect
|
||||
# redirect to the default websso url
|
||||
if (request.method == 'GET' and utils.is_websso_enabled and
|
||||
utils.is_websso_default_redirect()):
|
||||
protocol = utils.get_websso_default_redirect_protocol()
|
||||
region = utils.get_websso_default_redirect_region()
|
||||
origin = request.build_absolute_uri('/auth/websso/')
|
||||
url = ('%s/auth/OS-FEDERATION/websso/%s?origin=%s' %
|
||||
(region, protocol, origin))
|
||||
return shortcuts.redirect(url)
|
||||
|
||||
# If the user enabled websso and selects default protocol
|
||||
# from the dropdown, We need to redirect user to the websso url
|
||||
if request.method == 'POST':
|
||||
@ -151,9 +162,12 @@ def websso(request):
|
||||
request.user = auth.authenticate(request=request, auth_url=auth_url,
|
||||
token=token)
|
||||
except exceptions.KeystoneAuthException as exc:
|
||||
msg = 'Login failed: %s' % six.text_type(exc)
|
||||
res = django_http.HttpResponseRedirect(settings.LOGIN_URL)
|
||||
res.set_cookie('logout_reason', msg, max_age=10)
|
||||
if utils.is_websso_default_redirect():
|
||||
res = django_http.HttpResponseRedirect(settings.LOGIN_ERROR)
|
||||
else:
|
||||
msg = 'Login failed: %s' % six.text_type(exc)
|
||||
res = django_http.HttpResponseRedirect(settings.LOGIN_URL)
|
||||
res.set_cookie('logout_reason', msg, max_age=10)
|
||||
return res
|
||||
|
||||
auth_user.set_session_from_user(request, request.user)
|
||||
@ -178,8 +192,15 @@ def logout(request, login_url=None, **kwargs):
|
||||
LOG.info(msg)
|
||||
|
||||
""" Securely logs a user out. """
|
||||
return django_auth_views.logout_then_login(request, login_url=login_url,
|
||||
**kwargs)
|
||||
if (utils.is_websso_enabled and utils.is_websso_default_redirect() and
|
||||
utils.get_websso_default_redirect_logout()):
|
||||
auth_user.unset_session_user_variables(request)
|
||||
return django_http.HttpResponseRedirect(
|
||||
utils.get_websso_default_redirect_logout())
|
||||
else:
|
||||
return django_auth_views.logout_then_login(request,
|
||||
login_url=login_url,
|
||||
**kwargs)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -26,6 +26,7 @@ DEBUG = True
|
||||
WEBROOT = '/'
|
||||
#LOGIN_URL = WEBROOT + 'auth/login/'
|
||||
#LOGOUT_URL = WEBROOT + 'auth/logout/'
|
||||
#LOGIN_ERROR = WEBROOT + 'auth/error/'
|
||||
#
|
||||
# LOGIN_REDIRECT_URL can be used as an alternative for
|
||||
# HORIZON_CONFIG.user_home, if user_home is not set.
|
||||
@ -231,6 +232,21 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"
|
||||
# "acme_saml2": ("acme", "saml2"),
|
||||
#}
|
||||
|
||||
# Enables redirection on login to the identity provider defined on
|
||||
# WEBSSO_DEFAULT_REDIRECT_PROTOCOL and WEBSSO_DEFAULT_REDIRECT_REGION
|
||||
#WEBSSO_DEFAULT_REDIRECT = False
|
||||
|
||||
# Specifies the protocol to use for default redirection on login
|
||||
#WEBSSO_DEFAULT_REDIRECT_PROTOCOL = None
|
||||
|
||||
# Specifies the region to which the connection will be established on login
|
||||
#WEBSSO_DEFAULT_REDIRECT_REGION = OPENSTACK_KEYSTONE_URL
|
||||
|
||||
# Enables redirection on logout to the method specified on the identity provider.
|
||||
# Once logout the client will be redirected to the address specified in this
|
||||
# variable.
|
||||
#WEBSSO_DEFAULT_REDIRECT_LOGOUT = None
|
||||
|
||||
# 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)
|
||||
|
@ -54,6 +54,7 @@ SITE_BRANDING = 'OpenStack Dashboard'
|
||||
WEBROOT = '/'
|
||||
LOGIN_URL = None
|
||||
LOGOUT_URL = None
|
||||
LOGIN_ERROR = None
|
||||
LOGIN_REDIRECT_URL = None
|
||||
MEDIA_ROOT = None
|
||||
MEDIA_URL = None
|
||||
@ -418,6 +419,8 @@ if LOGIN_URL is None:
|
||||
LOGIN_URL = WEBROOT + 'auth/login/'
|
||||
if LOGOUT_URL is None:
|
||||
LOGOUT_URL = WEBROOT + 'auth/logout/'
|
||||
if LOGIN_ERROR is None:
|
||||
LOGIN_ERROR = WEBROOT + 'auth/error/'
|
||||
if LOGIN_REDIRECT_URL is None:
|
||||
LOGIN_REDIRECT_URL = WEBROOT
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- Adds the possibility to redirect the login to an identity provider by
|
||||
default. For that purpose the following variables have been added,
|
||||
``WEBSSO_DEFAULT_REDIRECT``, ``WEBSSO_DEFAULT_REDIRECT_PROTOCOL``,
|
||||
``WEBSSO_DEFAULT_REDIRECT_REGION`` and ``WEBSSO_DEFAULT_REDIRECT_LOGOUT``.
|
Loading…
Reference in New Issue
Block a user