From 9758ced8df3aab3de04d4502c7daa91855970456 Mon Sep 17 00:00:00 2001 From: Jip Rietveld Date: Thu, 2 May 2024 14:24:44 +0200 Subject: [PATCH 1/4] [EDIT] validate_audience to validate_iap_jwt Removing the insecure python-jose package --- authenticating-users/main.py | 46 +++++++++------------------ authenticating-users/requirements.txt | 3 +- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/authenticating-users/main.py b/authenticating-users/main.py index 9f4b9504..daeed74b 100644 --- a/authenticating-users/main.py +++ b/authenticating-users/main.py @@ -18,28 +18,9 @@ from flask import Flask app = Flask(__name__) -CERTS = None AUDIENCE = None -# [START getting_started_auth_certs] -def certs(): - """Returns a dictionary of current Google public key certificates for - validating Google-signed JWTs. Since these change rarely, the result - is cached on first request for faster subsequent responses. - """ - import requests - - global CERTS - if CERTS is None: - response = requests.get( - 'https://www.gstatic.com/iap/verify/public_key' - ) - CERTS = response.json() - return CERTS -# [END getting_started_auth_certs] - - # [START getting_started_auth_metadata] def get_metadata(item_name): """Returns a string with the project metadata value for the item_name. @@ -77,26 +58,29 @@ def audience(): # [END getting_started_auth_audience] -# [START getting_started_auth_validate_assertion] -def validate_assertion(assertion): +# [START iap_validate_jwt] +def validate_iap_jwt(iap_jwt) -> tuple[str, str]: """Checks that the JWT assertion is valid (properly signed, for the correct audience) and if so, returns strings for the requesting user's email and a persistent user ID. If not valid, returns None for each field. + + Source: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/iap/validate_jwt.py """ - from jose import jwt + from google.auth.transport import requests as google_auth_requests + from google.oauth2 import id_token try: - info = jwt.decode( - assertion, - certs(), - algorithms=['ES256'], - audience=audience() - ) - return info['email'], info['sub'] + decoded_jwt = id_token.verify_token( + iap_jwt, + google_auth_requests.Request(), + audience=audience(), + certs_url="https://www.gstatic.com/iap/verify/public_key", + ) + return decoded_jwt["email"], decoded_jwt["sub"] except Exception as e: print('Failed to validate assertion: {}'.format(e), file=sys.stderr) return None, None -# [END getting_started_auth_validate_assertion] +# [END iap_validate_jwt] # [START getting_started_auth_front_controller] @@ -105,7 +89,7 @@ def say_hello(): from flask import request assertion = request.headers.get('X-Goog-IAP-JWT-Assertion') - email, id = validate_assertion(assertion) + email, id = validate_iap_jwt(assertion) page = "

Hello {}

".format(email) return page # [END getting_started_auth_front_controller] diff --git a/authenticating-users/requirements.txt b/authenticating-users/requirements.txt index 0d4a3c36..5c366946 100644 --- a/authenticating-users/requirements.txt +++ b/authenticating-users/requirements.txt @@ -1,6 +1,7 @@ # [START getting_started_requirements] Flask==2.2.5 cryptography==41.0.2 -python-jose[cryptography]==3.3.0 +google-auth~=2.19.1 +google-cloud-iam~=2.3.0 requests==2.31.0 # [END getting_started_requirements] From a2620564efa69536dab32f39a07ace78c0d82f3b Mon Sep 17 00:00:00 2001 From: Jip Rietveld Date: Thu, 2 May 2024 14:25:05 +0200 Subject: [PATCH 2/4] [EDIT] Tests to use new validate_iap_jwt --- authenticating-users/main_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/authenticating-users/main_test.py b/authenticating-users/main_test.py index 38b934b6..efbc263a 100644 --- a/authenticating-users/main_test.py +++ b/authenticating-users/main_test.py @@ -22,7 +22,7 @@ def fake_validate(assertion): return None, None -main.validate_assertion = fake_validate +main.validate_iap_jwt = fake_validate def test_home_page(): From 18f0dbcf3566897fe6818263c2927cdd3bf5ff52 Mon Sep 17 00:00:00 2001 From: Jennifer Davis Date: Wed, 21 Aug 2024 23:41:02 -0700 Subject: [PATCH 3/4] fix: revert the region tag don't create a conflict with pre-existing region tags; ensure that existing region tag doesn't break here --- authenticating-users/main.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/authenticating-users/main.py b/authenticating-users/main.py index daeed74b..25ee3cc5 100644 --- a/authenticating-users/main.py +++ b/authenticating-users/main.py @@ -57,8 +57,7 @@ def audience(): return AUDIENCE # [END getting_started_auth_audience] - -# [START iap_validate_jwt] +# [START getting_started_auth_validate_assertion] def validate_iap_jwt(iap_jwt) -> tuple[str, str]: """Checks that the JWT assertion is valid (properly signed, for the correct audience) and if so, returns strings for the requesting user's @@ -80,7 +79,7 @@ def validate_iap_jwt(iap_jwt) -> tuple[str, str]: except Exception as e: print('Failed to validate assertion: {}'.format(e), file=sys.stderr) return None, None -# [END iap_validate_jwt] +# [END getting_started_auth_validate_assertion] # [START getting_started_auth_front_controller] From 16a6778318d9d62a49bb9aedf0e798b4966a83a4 Mon Sep 17 00:00:00 2001 From: Jennifer Davis Date: Fri, 23 Aug 2024 11:29:19 -0700 Subject: [PATCH 4/4] fix(auth): resolve some linting issues --- authenticating-users/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/authenticating-users/main.py b/authenticating-users/main.py index 25ee3cc5..bae55a76 100644 --- a/authenticating-users/main.py +++ b/authenticating-users/main.py @@ -57,13 +57,13 @@ def audience(): return AUDIENCE # [END getting_started_auth_audience] + # [START getting_started_auth_validate_assertion] def validate_iap_jwt(iap_jwt) -> tuple[str, str]: """Checks that the JWT assertion is valid (properly signed, for the correct audience) and if so, returns strings for the requesting user's email and a persistent user ID. If not valid, returns None for each field. - Source: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/iap/validate_jwt.py """ from google.auth.transport import requests as google_auth_requests from google.oauth2 import id_token