@@ -122,6 +122,19 @@ def wipe(dictionary, sensitive_fields): # Masks sensitive info
122
122
default = str , # A workaround when assertion is in bytes in Python 3
123
123
))
124
124
125
+ def __parse_account (self , response , id_token_claims ):
126
+ """Return client_info and home_account_id"""
127
+ if "client_info" in response : # It happens when client_info and profile are in request
128
+ client_info = json .loads (decode_part (response ["client_info" ]))
129
+ if "uid" in client_info and "utid" in client_info :
130
+ return client_info , "{uid}.{utid}" .format (** client_info )
131
+ # https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/387
132
+ if id_token_claims : # This would be an end user on ADFS-direct scenario
133
+ sub = id_token_claims ["sub" ] # "sub" always exists, per OIDC specs
134
+ return {"uid" : sub }, sub
135
+ # client_credentials flow will reach this code path
136
+ return {}, None
137
+
125
138
def __add (self , event , now = None ):
126
139
# event typically contains: client_id, scope, token_endpoint,
127
140
# response, params, data, grant_type
@@ -138,14 +151,7 @@ def __add(self, event, now=None):
138
151
id_token_claims = (
139
152
decode_id_token (id_token , client_id = event ["client_id" ])
140
153
if id_token else {})
141
- client_info = {}
142
- home_account_id = None # It would remain None in client_credentials flow
143
- if "client_info" in response : # We asked for it, and AAD will provide it
144
- client_info = json .loads (decode_part (response ["client_info" ]))
145
- home_account_id = "{uid}.{utid}" .format (** client_info )
146
- elif id_token_claims : # This would be an end user on ADFS-direct scenario
147
- client_info ["uid" ] = id_token_claims .get ("sub" )
148
- home_account_id = id_token_claims .get ("sub" )
154
+ client_info , home_account_id = self .__parse_account (response , id_token_claims )
149
155
150
156
target = ' ' .join (event .get ("scope" ) or []) # Per schema, we don't sort it
151
157
0 commit comments