From 2704f4feaae4a1d800f01e3854781347ce62c4a2 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 3 Aug 2021 16:38:02 +0200 Subject: [PATCH] views: keep a nonce during a forceAuthn request (#55953) Nonce value and forceAuthn is linked to the request id which is randomly generated by lasso and returned by IdPs as part of a SAML SSO. --- mellon/views.py | 11 ++++++++++- tests/test_sso_slo.py | 20 +++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mellon/views.py b/mellon/views.py index a22be3d..c78c517 100644 --- a/mellon/views.py +++ b/mellon/views.py @@ -251,6 +251,11 @@ class LoginView(ProfileMixin, LogMixin, View): if content is not None: values.append(content) attributes['issuer'] = login.remoteProviderId + in_response_to = login.response.inResponseTo + if in_response_to: + attributes['nonce'] = request.session.get('mellon-nonce-%s' % in_response_to) + attributes['force_authn'] = request.session.get('mellon-force-authn-%s' % in_response_to, False) + if login.nameIdentifier: name_id = login.nameIdentifier name_id_format = force_text(name_id.format or lasso.SAML2_NAME_IDENTIFIER_FORMAT_UNSPECIFIED) @@ -490,8 +495,12 @@ class LoginView(ProfileMixin, LogMixin, View): policy = authn_request.nameIdPolicy policy.allowCreate = utils.get_setting(idp, 'NAME_ID_POLICY_ALLOW_CREATE') policy.format = utils.get_setting(idp, 'NAME_ID_POLICY_FORMAT') - force_authn = utils.get_setting(idp, 'FORCE_AUTHN') + force_authn = utils.get_setting(idp, 'FORCE_AUTHN') or 'force-authn' in request.GET + # link the nonce and forceAuthn state to the request-id + if 'nonce' in request.GET: + request.session['mellon-nonce-%s' % authn_request.id] = request.GET['nonce'] if force_authn: + request.session['mellon-force-authn-%s' % authn_request.id] = True authn_request.forceAuthn = True if request.GET.get('passive') == '1': authn_request.isPassive = True diff --git a/tests/test_sso_slo.py b/tests/test_sso_slo.py index f9ec6b1..61eae22 100644 --- a/tests/test_sso_slo.py +++ b/tests/test_sso_slo.py @@ -94,7 +94,7 @@ class MockIdp(object): self.session_dump = None def process_authn_request_redirect(self, url, auth_result=True, consent=True, msg=None): - login = lasso.Login(self.server) + login = self.login = lasso.Login(self.server) if self.identity_dump: login.setIdentityFromDump(self.identity_dump) if self.session_dump: @@ -421,6 +421,8 @@ def test_sso(db, app, idp, caplog, sp_settings): assert app.session['mellon_session']['first_name'] == ['Fr\xe9d\xe9ric'] assert app.session['mellon_session']['email'] == ['john.doe@gmail.com'] assert app.session['mellon_session']['wtf'] == [] + assert not app.session['mellon_session']['force_authn'] + assert not app.session['mellon_session']['nonce'] def test_sso_request_denied(db, app, idp, caplog, sp_settings): @@ -732,3 +734,19 @@ def test_debug_sso(db, app, idp, caplog, sp_settings, settings): assert '