|
@@ -82,7 +82,8 @@ def _fetch_certs(request, certs_url):
|
|
|
"""Fetches certificates.
|
|
|
|
|
|
Google-style cerificate endpoints return JSON in the format of
|
|
|
- ``{'key id': 'x509 certificate'}``.
|
|
|
+ ``{'key id': 'x509 certificate'}`` or a certificate array according
|
|
|
+ to the JWK spec (see https://tools.ietf.org/html/rfc7517).
|
|
|
|
|
|
Args:
|
|
|
request (google.auth.transport.Request): The object used to make
|
|
@@ -90,8 +91,8 @@ def _fetch_certs(request, certs_url):
|
|
|
certs_url (str): The certificate endpoint URL.
|
|
|
|
|
|
Returns:
|
|
|
- Mapping[str, str]: A mapping of public key ID to x.509 certificate
|
|
|
- data.
|
|
|
+ Mapping[str, str] | Mapping[str, list]: A mapping of public keys
|
|
|
+ in x.509 or JWK spec.
|
|
|
"""
|
|
|
response = request(certs_url, method="GET")
|
|
|
|
|
@@ -120,7 +121,8 @@ def verify_token(
|
|
|
intended for. If None then the audience is not verified.
|
|
|
certs_url (str): The URL that specifies the certificates to use to
|
|
|
verify the token. This URL should return JSON in the format of
|
|
|
- ``{'key id': 'x509 certificate'}``.
|
|
|
+ ``{'key id': 'x509 certificate'}`` or a certificate array according to
|
|
|
+ the JWK spec (see https://tools.ietf.org/html/rfc7517).
|
|
|
clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
|
|
|
validation.
|
|
|
|
|
@@ -129,12 +131,28 @@ def verify_token(
|
|
|
"""
|
|
|
certs = _fetch_certs(request, certs_url)
|
|
|
|
|
|
- return jwt.decode(
|
|
|
- id_token,
|
|
|
- certs=certs,
|
|
|
- audience=audience,
|
|
|
- clock_skew_in_seconds=clock_skew_in_seconds,
|
|
|
- )
|
|
|
+ if "keys" in certs:
|
|
|
+ try:
|
|
|
+ import jwt as jwt_lib # type: ignore
|
|
|
+ except ImportError as caught_exc: # pragma: NO COVER
|
|
|
+ raise ImportError(
|
|
|
+ "The pyjwt library is not installed, please install the pyjwt package to use the jwk certs format."
|
|
|
+ ) from caught_exc
|
|
|
+ jwks_client = jwt_lib.PyJWKClient(certs_url)
|
|
|
+ signing_key = jwks_client.get_signing_key_from_jwt(id_token)
|
|
|
+ return jwt_lib.decode(
|
|
|
+ id_token,
|
|
|
+ signing_key.key,
|
|
|
+ algorithms=[signing_key.algorithm_name],
|
|
|
+ audience=audience,
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ return jwt.decode(
|
|
|
+ id_token,
|
|
|
+ certs=certs,
|
|
|
+ audience=audience,
|
|
|
+ clock_skew_in_seconds=clock_skew_in_seconds,
|
|
|
+ )
|
|
|
|
|
|
|
|
|
def verify_oauth2_token(id_token, request, audience=None, clock_skew_in_seconds=0):
|