Skip to content

Commit

Permalink
🐞 OIDC: Use Authorization Code Flow instead of implicit flow (#338)
Browse files Browse the repository at this point in the history
Parent issue: sequentech/meta#716
  • Loading branch information
Findeton committed Apr 23, 2024
1 parent abd54f3 commit 0697fa2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
47 changes: 38 additions & 9 deletions iam/authmethods/m_openidconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@

from contracts.base import JsonTypeEncoder

import requests
import jwt
import base64

LOGGER = logging.getLogger('iam')


Expand Down Expand Up @@ -409,7 +413,8 @@ def authenticate(self, auth_event, request, mode='authenticate'):
method_name="authenticate",
)

id_token = req.get('id_token', '')
#id_token = req.get('id_token', '')
code = req.get('code', '')
provider_id = req.get('provider_id', '')
nonce = req.get('nonce', '')

Expand All @@ -426,13 +431,37 @@ def authenticate(self, auth_event, request, mode='authenticate'):
)

provider = self.providers[provider_id]
# parses and verifies/validates the id token
id_token_obj = provider['client'].parse_response(
AuthorizationResponse,
info=id_token,
sformat="jwt",
keyjar=provider['client'].keyjar,
scope="openid"

url = provider['provider']['public_info']['token_endpoint']
redirect_uri = settings.EMAIL_AUTH_CODE_URL.replace("__EVENT_ID__/public/login/__RECEIVER__", "login-openid-connect-redirect")
data = {
'code': code,
'client_id': provider['provider']['public_info']['client_id'],
'client_secret': provider['provider']['private_info']['client_secret'],
'redirect_uri': redirect_uri,
'grant_type': "authorization_code",
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post(url, data=data, headers=headers)
response = r.json()
id_token = response['id_token']

# setup a PyJWKClient to get the appropriate signing key
jwks_client = jwt.PyJWKClient(provider['provider']['public_info']["jwks_uri"])

# get signing_key from id_token
signing_key = jwks_client.get_signing_key_from_jwt(id_token)

# now, decode_complete to get payload + header
algorithms = ["none","HS256","HS384","HS512","RS256","RS384","RS512","ES256","ES256K","ES384","ES521","ES512","PS256","PS384","PS512","EdDSA"]
id_token_obj = jwt.api_jwt.decode_complete(
id_token,
key=signing_key.key,
algorithms=algorithms,
audience=provider['provider']['public_info']['client_id'],
options={"verify_signature": True}
)
if not id_token_obj:
return self.error(
Expand All @@ -445,9 +474,9 @@ def authenticate(self, auth_event, request, mode='authenticate'):
auth_event=auth_event,
method_name="authenticate",
)
id_token_dict = id_token_obj["payload"]

# verify nonce securely
id_token_dict = id_token_obj.to_dict()
if not constant_time_compare(id_token_dict['nonce'], nonce):
return self.error(
ErrorCodes.INVALID_REQUEST,
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pycparser==2.21
pycryptodomex==3.19.1
Pygments==2.15.0
pyjwkest==1.4.2
PyJWT==2.4.0
PyJWT[crypto]>=2.8.0
PySocks==1.7.1
python-dateutil==2.5.3
pytz==2021.3
Expand Down

0 comments on commit 0697fa2

Please sign in to comment.