views: add the original path as a <eo:login-hint> element (#65639)
gitea/django-mellon/pipeline/head Build started... Details

Some identity providers (including authentic) may be interested in
    knowing what the origin path was before the sso request (obviously
    the opaque nonce alone does not allow them to retrieve that
    information).
This commit is contained in:
Paul Marillonnet 2022-05-24 10:18:46 +02:00
parent 025cda4293
commit c78834ba8e
2 changed files with 25 additions and 4 deletions

View File

@ -580,6 +580,10 @@ class LoginView(ProfileMixin, LogMixin, View):
hints.append('backoffice')
if login_hint == 'always_backoffice':
hints.append('backoffice')
if next_url is not None:
# eventually add path as a login_hint, which may be used as a filter element
# for a2's authentication backends.
hints.append(f'orig_path:{next_url}')
for hint in hints:
node = ET.Element(LOGIN_HINT)

View File

@ -644,7 +644,7 @@ def test_sso_slo_pass_login_hints_always_backoffice(db, app, idp, caplog, sp_set
url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
root = ET.fromstring(idp.request)
login_hints = root.findall('.//{https://www.entrouvert.com/}login-hint')
assert len(login_hints) == 1, 'missing login hint'
assert len(login_hints) == 2, 'missing login hint'
assert login_hints[0].text == 'backoffice', 'login hint is not backoffice'
@ -655,23 +655,40 @@ def test_sso_slo_pass_login_hints_backoffice(db, app, idp, caplog, sp_settings):
url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
root = ET.fromstring(idp.request)
login_hints = root.findall('.//{https://www.entrouvert.com/}login-hint')
assert len(login_hints) == 0
assert len(login_hints) == 1
response = app.get(reverse('mellon_login') + '?next=/whatever/')
url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
root = ET.fromstring(idp.request)
login_hints = root.findall('.//{https://www.entrouvert.com/}login-hint')
assert len(login_hints) == 0
assert len(login_hints) == 1
for next_url in ['/manage/', '/admin/', '/manager/']:
response = app.get(reverse('mellon_login') + '?next=%s' % next_url)
url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
root = ET.fromstring(idp.request)
login_hints = root.findall('.//{https://www.entrouvert.com/}login-hint')
assert len(login_hints) == 1, 'missing login hint'
assert len(login_hints) == 2, 'missing login hint'
assert login_hints[0].text == 'backoffice', 'login hint is not backoffice'
def test_sso_slo_login_hints_orig_path(db, app, idp, caplog, sp_settings):
sp_settings.MELLON_LOGIN_HINTS = []
response = app.get(reverse('mellon_login'))
url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
root = ET.fromstring(idp.request)
login_hints = root.findall('.//{https://www.entrouvert.com/}login-hint')
assert len(login_hints) == 1
assert login_hints[0].text == 'orig_path:/'
response = app.get(reverse('mellon_login') + '?next=/foo/bar/')
url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
root = ET.fromstring(idp.request)
login_hints = root.findall('.//{https://www.entrouvert.com/}login-hint')
assert len(login_hints) == 1
assert login_hints[0].text == 'orig_path:/foo/bar/'
def test_passive_auth_middleware_ok(db, app, idp, caplog, settings):
settings.MELLON_OPENED_SESSION_COOKIE_NAME = 'IDP_SESSION'
assert 'MELLON_PASSIVE_TRIED' not in app.cookies