Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit 943e88f

Browse files
committed
If sid in ID Token, pick it up and add to identifier mapping.
Support for back channel logout.
1 parent 06fc811 commit 943e88f

2 files changed

Lines changed: 74 additions & 10 deletions

File tree

src/oidcrp/__init__.py

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import traceback
55
from importlib import import_module
66

7-
from cryptojwt.utils import as_bytes
7+
from cryptojwt.utils import as_bytes, as_unicode
8+
from oidcmsg.exception import MessageException, NotForMe
89
from oidcmsg.oauth2 import ResponseMessage
910
from oidcmsg.oauth2 import is_error_message
10-
from oidcmsg.oidc import AccessTokenResponse
11+
from oidcmsg.oidc import AccessTokenResponse, verified_claim_name
1112
from oidcmsg.oidc import AuthorizationRequest
1213
from oidcmsg.oidc import AuthorizationResponse
1314
from oidcmsg.oidc import OpenIDSchema
15+
from oidcmsg.oidc.session import BackChannelLogoutRequest
1416
from oidcmsg.time_util import time_sans_frac
1517
from oidcservice import rndstr
1618
from oidcservice.exception import OidcServiceError
@@ -732,7 +734,6 @@ def finalize(self, issuer, response):
732734
state=_state, client=client)
733735

734736
if 'userinfo' in client.service and token['access_token']:
735-
736737
inforesp = self.get_user_info(
737738
state=authorization_response['state'], client=client,
738739
access_token=token['access_token'])
@@ -750,10 +751,32 @@ def finalize(self, issuer, response):
750751

751752
logger.debug("UserInfo: %s", inforesp)
752753

754+
try:
755+
_sid_support = client.service_context.provider_info[
756+
'backchannel_logout_session_supported']
757+
except KeyError:
758+
try:
759+
_sid_support = client.service_context.provider_info[
760+
'frontchannel_logout_session_supported']
761+
except:
762+
_sid_support = False
763+
764+
if _sid_support:
765+
try:
766+
sid = token['id_token']['sid']
767+
except KeyError:
768+
pass
769+
else:
770+
client.session_interface.store_sid2state(sid, _state)
771+
772+
client.session_interface.store_sub2state(token['id_token']['sub'],
773+
_state)
774+
753775
return {
754776
'userinfo': inforesp,
755777
'state': authorization_response['state'],
756-
'token': token['access_token']
778+
'token': token['access_token'],
779+
'id_token': token['id_token']
757780
}
758781

759782
def has_active_authentication(self, state):
@@ -830,7 +853,7 @@ def logout(self, state, client=None, post_logout_redirect_uri=''):
830853
:param client: Which client to use
831854
:param post_logout_redirect_uri: If a special post_logout_redirect_uri
832855
should be used
833-
:return:
856+
:return: A US
834857
"""
835858
if client is None:
836859
client = self.get_client_from_session_key(state)
@@ -847,13 +870,54 @@ def logout(self, state, client=None, post_logout_redirect_uri=''):
847870
else:
848871
request_args = {}
849872

850-
resp = client.do_request('end_session', state=state,
851-
request_args=request_args)
852-
if is_error_message(resp):
853-
raise OidcServiceError(resp['error'])
873+
resp = srv.get_request_parameters(state=state,
874+
request_args=request_args)
854875

855876
return resp
856877

878+
def backchannel_logout(self, client, request='', request_args=None):
879+
"""
880+
881+
:param request: URL encoded logout request
882+
:return:
883+
"""
884+
885+
if request:
886+
req = BackChannelLogoutRequest().from_urlencoded(as_unicode(request))
887+
else:
888+
req = BackChannelLogoutRequest(**request_args)
889+
890+
kwargs = {
891+
'aud': client.service_context.client_id,
892+
'iss': client.service_context.issuer,
893+
'keyjar': client.service_context.keyjar
894+
}
895+
896+
try:
897+
req.verify(**kwargs)
898+
except (MessageException, ValueError, NotForMe) as err:
899+
raise MessageException('Bogus logout request: {}'.format(err))
900+
901+
# Find the subject through 'sid' or 'sub'
902+
903+
try:
904+
sub = req[verified_claim_name('logout_token')]['sub']
905+
except KeyError:
906+
try:
907+
sid = req[verified_claim_name('logout_token')]['sid']
908+
except KeyError:
909+
raise MessageException('Neither "sid" nor "sub"')
910+
else:
911+
_state = client.session_interface.get_state_by_sid(sid)
912+
else:
913+
_state = client.session_interface.get_state_by_sub(sub)
914+
915+
return _state
916+
917+
def clear_session(self, state):
918+
client = self.get_client_from_session_key(state)
919+
client.session_interface.remove_state(state)
920+
857921

858922
def get_provider_specific_service(service_provider, service, **kwargs):
859923
"""

src/oidcrp/oidc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def fetch_distributed_claims(self, userinfo, callback=None):
108108
service=self.service['userinfo'],
109109
access_token= spec['access_token'])
110110
_resp = self.http.send(spec["endpoint"], 'GET',
111-
**http_args)
111+
**http_args)
112112
else:
113113
if callback:
114114
token = callback(spec['endpoint'])

0 commit comments

Comments
 (0)