|
44 | 44 | ) |
45 | 45 | from saml2.mdstore import SourceNotFound |
46 | 46 | from saml2.sigver import MissingKey |
| 47 | +from saml2.samlp import AuthnRequest |
47 | 48 | from saml2.validate import ResponseLifetimeExceed, ToEarly |
48 | 49 | from saml2.xmldsig import ( # support for SHA1 is required by spec |
49 | 50 | SIG_RSA_SHA1, SIG_RSA_SHA256) |
@@ -105,9 +106,16 @@ def login(request, |
105 | 106 | came_from = settings.LOGIN_REDIRECT_URL |
106 | 107 |
|
107 | 108 | # Ensure the user-originating redirection url is safe. |
108 | | - if not is_safe_url(url=came_from, allowed_hosts={request.get_host()}): |
| 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): |
109 | 116 | came_from = settings.LOGIN_REDIRECT_URL |
110 | 117 |
|
| 118 | + |
111 | 119 | # if the user is already authenticated that maybe because of two reasons: |
112 | 120 | # A) He has this URL in two browser windows and in the other one he |
113 | 121 | # has already initiated the authenticated session. |
@@ -221,6 +229,9 @@ def login(request, |
221 | 229 | binding=binding, |
222 | 230 | **kwargs) |
223 | 231 | try: |
| 232 | + if isinstance(request_xml, AuthnRequest): |
| 233 | + # request_xml will be an instance of AuthnRequest if the message is not signed |
| 234 | + request_xml = str(request_xml) |
224 | 235 | saml_request = base64.b64encode(bytes(request_xml, 'UTF-8')).decode('utf-8') |
225 | 236 |
|
226 | 237 | http_response = render(request, post_binding_form_template, { |
@@ -348,7 +359,15 @@ def assertion_consumer_service(request, |
348 | 359 | if not relay_state: |
349 | 360 | logger.warning('The RelayState parameter exists but is empty') |
350 | 361 | relay_state = default_relay_state |
351 | | - if not is_safe_url(url=relay_state, allowed_hosts={request.get_host()}): |
| 362 | + |
| 363 | + # Ensure the user-originating redirection url is safe. |
| 364 | + # By setting SAML_ALLOWED_HOSTS in settings.py the user may provide a list of "allowed" |
| 365 | + # hostnames for post-login redirects, much like one would specify ALLOWED_HOSTS . |
| 366 | + # If this setting is absent, the default is to use the hostname that was used for the current |
| 367 | + # request. |
| 368 | + saml_allowed_hosts = set(getattr(settings, 'SAML_ALLOWED_HOSTS', [request.get_host()])) |
| 369 | + |
| 370 | + if not is_safe_url(url=relay_state, allowed_hosts=saml_allowed_hosts): |
352 | 371 | relay_state = settings.LOGIN_REDIRECT_URL |
353 | 372 | logger.debug('Redirecting to the RelayState: %s', relay_state) |
354 | 373 | return HttpResponseRedirect(relay_state) |
|
0 commit comments