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 '