fix: Allow multiple audiences for id_token.verify_token (#733)
* feat: Allow multiple audiences for id_token.verify_token (#732)
* running black
Co-authored-by: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com>
diff --git a/google/auth/jwt.py b/google/auth/jwt.py
index 8165dda..892f3a8 100644
--- a/google/auth/jwt.py
+++ b/google/auth/jwt.py
@@ -219,8 +219,9 @@
in the token's header.
verify (bool): Whether to perform signature and claim validation.
Verification is done by default.
- audience (str): The audience claim, 'aud', that this JWT should
- contain. If None then the JWT's 'aud' parameter is not verified.
+ audience (str or list): The audience claim, 'aud', that this JWT should
+ contain. Or a list of audience claims. If None then the JWT's 'aud'
+ parameter is not verified.
Returns:
Mapping[str, str]: The deserialized JSON payload in the JWT.
@@ -279,9 +280,11 @@
# Check audience.
if audience is not None:
claim_audience = payload.get("aud")
- if audience != claim_audience:
+ if isinstance(audience, str):
+ audience = [audience]
+ if claim_audience not in audience:
raise ValueError(
- "Token has wrong audience {}, expected {}".format(
+ "Token has wrong audience {}, expected one of {}".format(
claim_audience, audience
)
)
diff --git a/google/oauth2/id_token.py b/google/oauth2/id_token.py
index 5e36260..5fbb6a1 100644
--- a/google/oauth2/id_token.py
+++ b/google/oauth2/id_token.py
@@ -112,8 +112,8 @@
id_token (Union[str, bytes]): The encoded token.
request (google.auth.transport.Request): The object used to make
HTTP requests.
- audience (str): The audience that this token is intended for. If None
- then the audience is not verified.
+ audience (str or list): The audience or audiences that this token is
+ 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'}``.
diff --git a/tests/test_jwt.py b/tests/test_jwt.py
index 7b5ba5c..c5290eb 100644
--- a/tests/test_jwt.py
+++ b/tests/test_jwt.py
@@ -144,6 +144,17 @@
assert payload["metadata"]["meta"] == "data"
+def test_decode_valid_with_audience_list(token_factory):
+ payload = jwt.decode(
+ token_factory(),
+ certs=PUBLIC_CERT_BYTES,
+ audience=["audience@example.com", "another_audience@example.com"],
+ )
+ assert payload["aud"] == "audience@example.com"
+ assert payload["user"] == "billy bob"
+ assert payload["metadata"]["meta"] == "data"
+
+
def test_decode_valid_unverified(token_factory):
payload = jwt.decode(token_factory(), certs=OTHER_CERT_BYTES, verify=False)
assert payload["aud"] == "audience@example.com"
@@ -211,6 +222,14 @@
assert excinfo.match(r"Token has wrong audience")
+def test_decode_bad_token_wrong_audience_list(token_factory):
+ token = token_factory()
+ audience = ["audience2@example.com", "audience3@example.com"]
+ with pytest.raises(ValueError) as excinfo:
+ jwt.decode(token, PUBLIC_CERT_BYTES, audience=audience)
+ assert excinfo.match(r"Token has wrong audience")
+
+
def test_decode_wrong_cert(token_factory):
with pytest.raises(ValueError) as excinfo:
jwt.decode(token_factory(), OTHER_CERT_BYTES)