Make WebSSO trusted_dashboard hostname case-insensitive

Ensure the hostname in the trusted_dashboard config is lowercase
to prevent failures when comparing against the origin query URL.

Conflicts:
        keystone/common/utils.py

Closes-Bug: #1538754
Change-Id: I807a567e7d93c09c5c370065509c106b7d1c973b
(cherry picked from commit 78c9ccc9ee)
This commit is contained in:
Roxana Gherle 2016-01-28 00:11:02 -08:00 committed by Roxana Gherle
parent ff0bd967f9
commit c665080d4a
3 changed files with 32 additions and 1 deletions

View File

@ -526,3 +526,14 @@ def get_token_ref(context):
except KeyError:
LOG.warning(_LW("Couldn't find the auth context."))
raise exception.Unauthorized()
def lower_case_hostname(url):
"""Change the URL's hostname to lowercase"""
# NOTE(gyee): according to
# https://www.w3.org/TR/WD-html40-970708/htmlweb.html, the netloc portion
# of the URL is case-insensitive
parsed = moves.urllib.parse.urlparse(url)
# Note: _replace method for named tuples is public and defined in docs
replaced = parsed._replace(netloc=parsed.netloc.lower())
return moves.urllib.parse.urlunparse(replaced)

View File

@ -24,6 +24,7 @@ from keystone.auth import controllers as auth_controllers
from keystone.common import authorization
from keystone.common import controller
from keystone.common import dependency
from keystone.common import utils as k_utils
from keystone.common import validation
from keystone.common import wsgi
from keystone.contrib.federation import idp as keystone_idp
@ -269,7 +270,11 @@ class Auth(auth_controllers.Auth):
LOG.error(msg)
raise exception.ValidationError(msg)
if host not in CONF.federation.trusted_dashboard:
# change trusted_dashboard hostnames to lowercase before comparison
trusted_dashboards = [k_utils.lower_case_hostname(trusted)
for trusted in CONF.federation.trusted_dashboard]
if host not in trusted_dashboards:
msg = _('%(host)s is not a trusted dashboard host')
msg = msg % {'host': host}
LOG.error(msg)

View File

@ -3306,6 +3306,21 @@ class WebSSOTests(FederatedTokenTests):
resp = self.api.federated_sso_auth(context, self.PROTOCOL)
self.assertIn(self.TRUSTED_DASHBOARD, resp.body)
def test_get_sso_origin_host_case_insensitive(self):
# test lowercase hostname in trusted_dashboard
context = {
'query_string': {
'origin': "http://horizon.com",
},
}
host = self.api._get_sso_origin_host(context)
self.assertEqual("http://horizon.com", host)
# test uppercase hostname in trusted_dashboard
self.config_fixture.config(group='federation',
trusted_dashboard=['http://Horizon.com'])
host = self.api._get_sso_origin_host(context)
self.assertEqual("http://horizon.com", host)
def test_federated_sso_auth_with_protocol_specific_remote_id(self):
self.config_fixture.config(
group=self.PROTOCOL,