Skip to content

Commit a343d10

Browse files
committed
Refactor of "User specified hostnames for redirect #148" [#148]
1 parent 74a80f5 commit a343d10

File tree

4 files changed

+22
-24
lines changed

4 files changed

+22
-24
lines changed

djangosaml2/utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from django.conf import settings
1616
from django.core.exceptions import ImproperlyConfigured
17+
from django.utils.http import is_safe_url
1718
from django.utils.module_loading import import_string
1819
from saml2.s_utils import UnknownSystemEntity
1920

@@ -80,3 +81,17 @@ def fail_acs_response(request, *args, **kwargs):
8081
failure_function = import_string(get_custom_setting('SAML_ACS_FAILURE_RESPONSE_FUNCTION',
8182
'djangosaml2.acs_failures.template_failure'))
8283
return failure_function(request, *args, **kwargs)
84+
85+
86+
def validate_referral_url(request, url):
87+
# Ensure the user-originating redirection url is safe.
88+
# By setting SAML_ALLOWED_HOSTS in settings.py the user may provide a list of "allowed"
89+
# hostnames for post-login redirects, much like one would specify ALLOWED_HOSTS .
90+
# If this setting is absent, the default is to use the hostname that was used for the current
91+
# request.
92+
saml_allowed_hosts = set(getattr(settings, 'SAML_ALLOWED_HOSTS', [request.get_host()]))
93+
94+
if not is_safe_url(url=url, allowed_hosts=saml_allowed_hosts):
95+
return settings.LOGIN_REDIRECT_URL
96+
else:
97+
return url

djangosaml2/views.py

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
from django.http import Http404, HttpResponse
2727
from django.shortcuts import render
2828
from django.template import TemplateDoesNotExist
29-
from django.utils.http import is_safe_url
3029
from django.views.decorators.csrf import csrf_exempt
3130
from django.views.decorators.http import require_POST
3231
from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST
@@ -55,7 +54,8 @@
5554
from .overrides import Saml2Client
5655
from .signals import post_authenticated
5756
from .utils import (available_idps, fail_acs_response, get_custom_setting,
58-
get_idp_sso_supported_bindings, get_location)
57+
get_idp_sso_supported_bindings, get_location,
58+
validate_referral_url)
5959

6060
try:
6161
from django.contrib.auth.views import LogoutView
@@ -104,17 +104,7 @@ def login(request,
104104
if not came_from:
105105
logger.warning('The next parameter exists but is empty')
106106
came_from = settings.LOGIN_REDIRECT_URL
107-
108-
# Ensure the user-originating redirection url is safe.
109-
# By setting SAML_ALLOWED_HOSTS in settings.py the user may provide a list of "allowed"
110-
# hostnames for post-login redirects, much like one would specify ALLOWED_HOSTS .
111-
# If this setting is absent, the default is to use the hostname that was used for the current
112-
# request.
113-
saml_allowed_hosts = set(getattr(settings, 'SAML_ALLOWED_HOSTS', [request.get_host()]))
114-
115-
if not is_safe_url(url=came_from, allowed_hosts=saml_allowed_hosts):
116-
came_from = settings.LOGIN_REDIRECT_URL
117-
107+
came_from = validate_referral_url(request, came_from)
118108

119109
# if the user is already authenticated that maybe because of two reasons:
120110
# A) He has this URL in two browser windows and in the other one he
@@ -358,16 +348,8 @@ def assertion_consumer_service(request,
358348
if not relay_state:
359349
logger.warning('The RelayState parameter exists but is empty')
360350
relay_state = default_relay_state
361-
362-
# Ensure the user-originating redirection url is safe.
363-
# By setting SAML_ALLOWED_HOSTS in settings.py the user may provide a list of "allowed"
364-
# hostnames for post-login redirects, much like one would specify ALLOWED_HOSTS .
365-
# If this setting is absent, the default is to use the hostname that was used for the current
366-
# request.
367-
saml_allowed_hosts = set(getattr(settings, 'SAML_ALLOWED_HOSTS', [request.get_host()]))
368-
369-
if not is_safe_url(url=relay_state, allowed_hosts=saml_allowed_hosts):
370-
relay_state = settings.LOGIN_REDIRECT_URL
351+
relay_state = validate_referral_url(request, relay_state)
352+
371353
logger.debug('Redirecting to the RelayState: %s', relay_state)
372354
return HttpResponseRedirect(relay_state)
373355

tests/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
INSTALLED_APPS = (
2828
'testprofiles',
29-
29+
3030
'django.contrib.admin',
3131
'django.contrib.auth',
3232
'django.contrib.contenttypes',

tests/testprofiles/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)