Repository: googleapis/google-auth-library-python

Issue:
Make `verify_oauth2_token` check the issuer claim
It [doesn't](https://github.com/googleapis/google-auth-library-python/search?q=%22accounts.google.com%22&unscoped_q=%22accounts.google.com%22) look like the Python library checks for the issuer claim as it does for other language libraries ([Node.js](https://github.com/googleapis/google-auth-library-nodejs/blob/07955406e85f07fb60821192253205b9f4137ab9/src/auth/oauth2client.ts#L513-L516)).

It would make the Google authentication instructions [here](https://developers.devsite.corp.google.com/identity/sign-in/web/backend-auth#using-a-google-api-client-library) more consistent across if `verify_oauth2_token` checks both "`accounts.google.com`" and "`https://accounts.google.com`".



Discussion:

Resolving patch:
diff --git a/google/auth/transport/requests.py b/google/auth/transport/requests.py
--- a/google/auth/transport/requests.py
+++ b/google/auth/transport/requests.py
@@ -365,7 +365,11 @@ def configure_mtls_channel(self, client_cert_callback=None):
             six.raise_from(new_exc, caught_exc)
 
         try:
-            self._is_mtls, cert, key = google.auth.transport._mtls_helper.get_client_cert_and_key(
+            (
+                self._is_mtls,
+                cert,
+                key,
+            ) = google.auth.transport._mtls_helper.get_client_cert_and_key(
                 client_cert_callback
             )
 
diff --git a/google/oauth2/id_token.py b/google/oauth2/id_token.py
--- a/google/oauth2/id_token.py
+++ b/google/oauth2/id_token.py
@@ -80,6 +80,8 @@
     "/securetoken@system.gserviceaccount.com"
 )
 
+_GOOGLE_ISSUERS = ["accounts.google.com", "https://accounts.google.com"]
+
 
 def _fetch_certs(request, certs_url):
     """Fetches certificates.
@@ -140,11 +142,23 @@ def verify_oauth2_token(id_token, request, audience=None):
 
     Returns:
         Mapping[str, Any]: The decoded token.
+
+    Raises:
+        exceptions.GoogleAuthError: If the issuer is invalid.
     """
-    return verify_token(
+    idinfo = verify_token(
         id_token, request, audience=audience, certs_url=_GOOGLE_OAUTH2_CERTS_URL
     )
 
+    if idinfo["iss"] not in _GOOGLE_ISSUERS:
+        raise exceptions.GoogleAuthError(
+            "Wrong issuer. 'iss' should be one of the following: {}".format(
+                _GOOGLE_ISSUERS
+            )
+        )
+
+    return idinfo
+
 
 def verify_firebase_token(id_token, request, audience=None):
     """Verifies an ID Token issued by Firebase Authentication.


Test patch:
diff --git a/tests/oauth2/test_id_token.py b/tests/oauth2/test_id_token.py
--- a/tests/oauth2/test_id_token.py
+++ b/tests/oauth2/test_id_token.py
@@ -95,6 +95,7 @@ def test_verify_token_args(_fetch_certs, decode):
 
 @mock.patch("google.oauth2.id_token.verify_token", autospec=True)
 def test_verify_oauth2_token(verify_token):
+    verify_token.return_value = {"iss": "accounts.google.com"}
     result = id_token.verify_oauth2_token(
         mock.sentinel.token, mock.sentinel.request, audience=mock.sentinel.audience
     )
@@ -108,6 +109,16 @@ def test_verify_oauth2_token(verify_token):
     )
 
 
+@mock.patch("google.oauth2.id_token.verify_token", autospec=True)
+def test_verify_oauth2_token_invalid_iss(verify_token):
+    verify_token.return_value = {"iss": "invalid_issuer"}
+
+    with pytest.raises(exceptions.GoogleAuthError):
+        id_token.verify_oauth2_token(
+            mock.sentinel.token, mock.sentinel.request, audience=mock.sentinel.audience
+        )
+
+
 @mock.patch("google.oauth2.id_token.verify_token", autospec=True)
 def test_verify_firebase_token(verify_token):
     result = id_token.verify_firebase_token(