views: improve handling of next_url for sp initiated logout (#69740)

This commit is contained in:
Benjamin Dauvergne 2022-09-30 00:46:05 +02:00
parent 43ce1d8141
commit 86d3cad3b8
2 changed files with 11 additions and 7 deletions

View File

@ -723,8 +723,12 @@ class LogoutView(ProfileMixin, LogMixin, View):
def sp_logout_request(self, request):
'''Launch a logout request to the identity provider'''
next_url = request.GET.get(REDIRECT_FIELD_NAME)
referer = request.headers.get('Referer')
field_next_url = request.GET.get(REDIRECT_FIELD_NAME)
next_url = None
if field_next_url and utils.same_origin(request.build_absolute_uri(), field_next_url):
next_url = field_next_url
next_url = next_url or '/'
if not referer or utils.same_origin(request.build_absolute_uri(), referer):
if hasattr(request, 'user') and request.user.is_authenticated:
logout = None
@ -754,7 +758,7 @@ class LogoutView(ProfileMixin, LogMixin, View):
self.log.info('user logged out, SLO request sent to IdP')
else:
# anonymous user: if next_url is None redirect to referer
return HttpResponseRedirect(next_url or referer)
return HttpResponseRedirect(next_url)
else:
self.log.warning('logout refused referer %r is not of the same origin', referer)
return HttpResponseRedirect(next_url)
@ -774,9 +778,7 @@ class LogoutView(ProfileMixin, LogMixin, View):
self.log.warning('partial logout')
except lasso.Error as e:
self.log.warning('unable to process a logout response: %s', e)
return HttpResponseRedirect(resolve_url(settings.LOGIN_REDIRECT_URL))
next_url = self.get_next_url(default=resolve_url(settings.LOGIN_REDIRECT_URL))
return HttpResponseRedirect(next_url)
return HttpResponseRedirect(self.get_next_url() or '/')
logout = csrf_exempt(LogoutView.as_view())

View File

@ -254,14 +254,16 @@ def test_sso_slo(db, app, idp, caplog, sp_settings):
# again, user is already logged out
response = app.get(reverse('mellon_logout'), extra_environ={'HTTP_REFERER': '/some/path'})
assert urlparse.urlparse(response['Location']).path == '/some/path'
assert urlparse.urlparse(response['Location']).path == '/'
def test_sso_slo_next(db, app, idp, caplog, sp_settings):
response = app.get(reverse('mellon_login'))
url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
response = app.post(reverse('mellon_login'), params={'SAMLResponse': body, 'RelayState': relay_state})
response = app.get(reverse('mellon_logout') + '?next=/some/path/')
response = app.get(
reverse('mellon_logout') + '?next=/some/path/', extra_environ={'HTTP_REFERER': '/other/path'}
)
assert urlparse.urlparse(response['Location']).path == '/singleLogout'
url = idp.process_logout_request_redirect(response.location)
response = app.get(url)