From ba5bd50e3d21a9487e1e366409c0b3d56fc22df0 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 13 Jun 2017 12:51:50 +0200 Subject: [PATCH] idp_oidc: fill id_token also with user's info (fixes #16854) --- src/authentic2_idp_oidc/utils.py | 16 ++++++++++++++++ src/authentic2_idp_oidc/views.py | 26 +++++++++----------------- tests/test_idp_oidc.py | 6 ++++++ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/authentic2_idp_oidc/utils.py b/src/authentic2_idp_oidc/utils.py index 764617e..fedb78e 100644 --- a/src/authentic2_idp_oidc/utils.py +++ b/src/authentic2_idp_oidc/utils.py @@ -94,3 +94,19 @@ def make_pairwise_sub(client, user): sub = sector_identifier + str(user.uuid) + settings.SECRET_KEY sub = base64.b64encode(hashlib.sha256(sub).digest()) return sub + + +def create_user_info(client, user, scope_set, id_token=False): + '''Create user info dictionnary''' + user_info = { + 'sub': make_sub(client, user) + } + if 'profile' in scope_set: + user_info['family_name'] = user.last_name + user_info['given_name'] = user.first_name + if user.username: + user_info['preferred_username'] = user.username.split('@', 1)[0] + if 'email' in scope_set: + user_info['email'] = user.email + user_info['email_verified'] = True + return user_info diff --git a/src/authentic2_idp_oidc/views.py b/src/authentic2_idp_oidc/views.py index e7c3849..784d47e 100644 --- a/src/authentic2_idp_oidc/views.py +++ b/src/authentic2_idp_oidc/views.py @@ -246,7 +246,8 @@ def authorize(request, *args, **kwargs): acr = 0 if nonce and last_auth.get('nonce') == nonce: acr = 1 - id_token = { + id_token = utils.create_user_info(client, request.user, scopes, id_token=True) + id_token.update({ 'iss': request.build_absolute_uri('/'), 'sub': utils.make_sub(client, request.user), 'aud': client.client_id, @@ -255,7 +256,7 @@ def authorize(request, *args, **kwargs): 'iat': timestamp_from_datetime(start), 'auth_time': last_auth['when'], 'acr': acr, - } + }) if nonce: id_token['nonce'] = nonce params = { @@ -349,7 +350,9 @@ def token(request, *args, **kwargs): if (oidc_code.nonce and last_authentication_event(oidc_code.session).get('nonce') == oidc_code.nonce): acr = 1 - id_token = { + # prefill id_token with user info + id_token = utils.create_user_info(client, oidc_code.user, oidc_code.scope_set(), id_token=True) + id_token.update({ 'iss': request.build_absolute_uri('/'), 'sub': utils.make_sub(client, oidc_code.user), 'aud': client.client_id, @@ -358,7 +361,7 @@ def token(request, *args, **kwargs): 'iat': timestamp_from_datetime(start), 'auth_time': timestamp_from_datetime(oidc_code.auth_time), 'acr': acr, - } + }) if oidc_code.nonce: id_token['nonce'] = oidc_code.nonce response = HttpResponse(json.dumps({ @@ -393,19 +396,8 @@ def user_info(request, *args, **kwargs): access_token = authenticate_access_token(request) if access_token is None: return HttpResponse('unauthenticated', status=401) - scope_set = access_token.scope_set() - user = access_token.user - user_info = { - 'sub': utils.make_sub(access_token.client, access_token.user) - } - if 'profile' in scope_set: - user_info['family_name'] = user.last_name - user_info['given_name'] = user.first_name - if user.username: - user_info['preferred_username'] = user.username.split('@', 1)[0] - if 'email' in scope_set: - user_info['email'] = user.email - user_info['email_verified'] = True + user_info = utils.create_user_info(access_token.client, access_token.user, + access_token.scope_set()) return HttpResponse(json.dumps(user_info), content_type='application/json') diff --git a/tests/test_idp_oidc.py b/tests/test_idp_oidc.py index a154671..c4ecebb 100644 --- a/tests/test_idp_oidc.py +++ b/tests/test_idp_oidc.py @@ -199,6 +199,12 @@ def test_authorization_code_sso(login_first, oidc_settings, oidc_client, simple_ assert claims['acr'] == 0 else: assert claims['acr'] == 1 + assert claims['sub'] == make_sub(oidc_client, simple_user) + assert claims['preferred_username'] == simple_user.username + assert claims['given_name'] == simple_user.first_name + assert claims['family_name'] == simple_user.last_name + assert claims['email'] == simple_user.email + assert claims['email_verified'] is True user_info_url = make_url('oidc-user-info') response = app.get(user_info_url, headers=bearer_authentication_headers(access_token)) -- 2.1.4