@@ -82,16 +82,17 @@ def _fetch_certs(request, certs_url):
8282 """Fetches certificates.
8383
8484 Google-style cerificate endpoints return JSON in the format of
85- ``{'key id': 'x509 certificate'}``.
85+ ``{'key id': 'x509 certificate'}`` or a certificate array according
86+ to the JWK spec (see https://tools.ietf.org/html/rfc7517).
8687
8788 Args:
8889 request (google.auth.transport.Request): The object used to make
8990 HTTP requests.
9091 certs_url (str): The certificate endpoint URL.
9192
9293 Returns:
93- Mapping[str, str]: A mapping of public key ID to x.509 certificate
94- data .
94+ Mapping[str, str] | Mapping[str, list] : A mapping of public keys
95+ in x.509 or JWK spec .
9596 """
9697 response = request (certs_url , method = "GET" )
9798
@@ -120,7 +121,8 @@ def verify_token(
120121 intended for. If None then the audience is not verified.
121122 certs_url (str): The URL that specifies the certificates to use to
122123 verify the token. This URL should return JSON in the format of
123- ``{'key id': 'x509 certificate'}``.
124+ ``{'key id': 'x509 certificate'}`` or a certificate array according to
125+ the JWK spec (see https://tools.ietf.org/html/rfc7517).
124126 clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
125127 validation.
126128
@@ -129,12 +131,28 @@ def verify_token(
129131 """
130132 certs = _fetch_certs (request , certs_url )
131133
132- return jwt .decode (
133- id_token ,
134- certs = certs ,
135- audience = audience ,
136- clock_skew_in_seconds = clock_skew_in_seconds ,
137- )
134+ if "keys" in certs :
135+ try :
136+ import jwt as jwt_lib # type: ignore
137+ except ImportError as caught_exc : # pragma: NO COVER
138+ raise ImportError (
139+ "The pyjwt library is not installed, please install the pyjwt package to use the jwk certs format."
140+ ) from caught_exc
141+ jwks_client = jwt_lib .PyJWKClient (certs_url )
142+ signing_key = jwks_client .get_signing_key_from_jwt (id_token )
143+ return jwt_lib .decode (
144+ id_token ,
145+ signing_key .key ,
146+ algorithms = [signing_key .algorithm_name ],
147+ audience = audience ,
148+ )
149+ else :
150+ return jwt .decode (
151+ id_token ,
152+ certs = certs ,
153+ audience = audience ,
154+ clock_skew_in_seconds = clock_skew_in_seconds ,
155+ )
138156
139157
140158def verify_oauth2_token (id_token , request , audience = None , clock_skew_in_seconds = 0 ):
0 commit comments