Skip to content

Commit

Permalink
OIDC: try to JWT decode userinfo response if JSON parsing failed (#16972
Browse files Browse the repository at this point in the history
)
  • Loading branch information
MatMaul authored Mar 21, 2024
1 parent db95b75 commit 3ab9e6d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
1 change: 1 addition & 0 deletions changelog.d/16972.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OIDC: try to JWT decode userinfo response if JSON parsing failed.
32 changes: 28 additions & 4 deletions synapse/handlers/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,14 +829,38 @@ async def _fetch_userinfo(self, token: Token) -> UserInfo:
logger.debug("Using the OAuth2 access_token to request userinfo")
metadata = await self.load_metadata()

resp = await self._http_client.get_json(
resp = await self._http_client.request(
"GET",
metadata["userinfo_endpoint"],
headers={"Authorization": ["Bearer {}".format(token["access_token"])]},
headers=Headers(
{"Authorization": ["Bearer {}".format(token["access_token"])]}
),
)

logger.debug("Retrieved user info from userinfo endpoint: %r", resp)
body = await readBody(resp)

content_type_headers = resp.headers.getRawHeaders("Content-Type")
assert content_type_headers
# We use `startswith` because the header value can contain the `charset` parameter
# even if it is useless, and Twisted doesn't take care of that for us.
if content_type_headers[0].startswith("application/jwt"):
alg_values = metadata.get(
"id_token_signing_alg_values_supported", ["RS256"]
)
jwt = JsonWebToken(alg_values)
jwk_set = await self.load_jwks()
try:
decoded_resp = jwt.decode(body, key=jwk_set)
except ValueError:
logger.info("Reloading JWKS after decode error")
jwk_set = await self.load_jwks(force=True) # try reloading the jwks
decoded_resp = jwt.decode(body, key=jwk_set)
else:
decoded_resp = json_decoder.decode(body.decode("utf-8"))

logger.debug("Retrieved user info from userinfo endpoint: %r", decoded_resp)

return UserInfo(resp)
return UserInfo(decoded_resp)

async def _verify_jwt(
self,
Expand Down

0 comments on commit 3ab9e6d

Please sign in to comment.