pass id_token on logout from FranceConnect (fixes #28997)
This commit is contained in:
parent
b896d1af68
commit
43f0a85dd5
|
@ -168,9 +168,11 @@ def test_fc_login_page(caplog):
|
|||
assert session.extra_user_variables['fc_sub'] == 'ymca'
|
||||
|
||||
resp = app.get('/logout')
|
||||
assert resp.location.endswith('/ident/fc/logout')
|
||||
resp = resp.follow()
|
||||
assert resp.location == 'https://fcp.integ01.dev-franceconnect.fr/api/v1/logout?post_logout_redirect_uri=http%3A%2F%2Fexample.net'
|
||||
splitted = urlparse.urlsplit(resp.location)
|
||||
assert urlparse.urlunsplit((splitted.scheme, splitted.netloc, splitted.path, '', '')) \
|
||||
== 'https://fcp.integ01.dev-franceconnect.fr/api/v1/logout'
|
||||
assert urlparse.parse_qs(splitted.query)['post_logout_redirect_uri'] == ['http://example.net']
|
||||
assert urlparse.parse_qs(splitted.query)['id_token_hint']
|
||||
assert not get_session(app)
|
||||
|
||||
# Test error handling path
|
||||
|
|
|
@ -327,13 +327,14 @@ class FCAuthMethod(AuthMethod):
|
|||
return None
|
||||
# check id_token nonce
|
||||
id_token = result['id_token']
|
||||
access_token = result['access_token']
|
||||
header, payload, signature = id_token.split('.')
|
||||
payload = json_loads(base64url_decode(payload))
|
||||
nonce = hashlib.sha256(str(session.id)).hexdigest()
|
||||
if payload['nonce'] != nonce:
|
||||
logger.error('FranceConnect returned nonce did not match')
|
||||
return None
|
||||
return result['access_token']
|
||||
return access_token, id_token
|
||||
|
||||
def get_user_info(self, access_token):
|
||||
logger = get_logger()
|
||||
|
@ -436,7 +437,7 @@ class FCAuthMethod(AuthMethod):
|
|||
logger.error(_('FranceConnect authentication failed: %s'),
|
||||
_(msg) if msg else error)
|
||||
return redirect(next_url)
|
||||
access_token = self.get_access_token(request.form['code'])
|
||||
access_token, id_token = self.get_access_token(request.form['code'])
|
||||
if not access_token:
|
||||
return redirect(next_url)
|
||||
user_info = self.get_user_info(access_token)
|
||||
|
@ -448,7 +449,8 @@ class FCAuthMethod(AuthMethod):
|
|||
session_var_fc_user = {}
|
||||
for key in flattened_user_info:
|
||||
session_var_fc_user['fc_' + key] = flattened_user_info[key]
|
||||
|
||||
session_var_fc_user['fc_access_token'] = access_token
|
||||
session_var_fc_user['fc_id_token'] = id_token
|
||||
# Lookup or create user
|
||||
sub = user_info['sub']
|
||||
user = None
|
||||
|
@ -471,9 +473,13 @@ class FCAuthMethod(AuthMethod):
|
|||
return redirect(next_url)
|
||||
|
||||
def logout(self):
|
||||
session = get_session()
|
||||
id_token = session.extra_user_variables['fc_id_token']
|
||||
get_session_manager().expire_session()
|
||||
logout_url = self.get_logout_url()
|
||||
post_logout_redirect_uri = get_publisher().get_frontoffice_url()
|
||||
logout_url += '?' + urllib.urlencode({
|
||||
'id_token_hint': id_token,
|
||||
'post_logout_redirect_uri': post_logout_redirect_uri,
|
||||
})
|
||||
return redirect(logout_url)
|
||||
|
|
|
@ -265,9 +265,8 @@ class RootDirectory(Directory):
|
|||
return redirect(get_publisher().get_root_url())
|
||||
ident_methods = get_cfg('identification', {}).get('methods', [])
|
||||
|
||||
if 'fc' in ident_methods and session.extra_user_variables and 'fc_sub' in session.extra_user_variables:
|
||||
get_session_manager().expire_session()
|
||||
return redirect(get_publisher().get_root_url() + 'ident/fc/logout')
|
||||
if 'fc' in ident_methods and session.extra_user_variables and 'fc_id_token' in session.extra_user_variables:
|
||||
return get_publisher().ident_methods['fc']().logout()
|
||||
|
||||
if not 'idp' in ident_methods:
|
||||
get_session_manager().expire_session()
|
||||
|
|
Loading…
Reference in New Issue