Skip to content

Commit 56c3946

Browse files
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>
1 parent 82293fe commit 56c3946

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

google/auth/jwt.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ def decode(token, certs=None, verify=True, audience=None):
219219
in the token's header.
220220
verify (bool): Whether to perform signature and claim validation.
221221
Verification is done by default.
222-
audience (str): The audience claim, 'aud', that this JWT should
223-
contain. If None then the JWT's 'aud' parameter is not verified.
222+
audience (str or list): The audience claim, 'aud', that this JWT should
223+
contain. Or a list of audience claims. If None then the JWT's 'aud'
224+
parameter is not verified.
224225
225226
Returns:
226227
Mapping[str, str]: The deserialized JSON payload in the JWT.
@@ -279,9 +280,11 @@ def decode(token, certs=None, verify=True, audience=None):
279280
# Check audience.
280281
if audience is not None:
281282
claim_audience = payload.get("aud")
282-
if audience != claim_audience:
283+
if isinstance(audience, str):
284+
audience = [audience]
285+
if claim_audience not in audience:
283286
raise ValueError(
284-
"Token has wrong audience {}, expected {}".format(
287+
"Token has wrong audience {}, expected one of {}".format(
285288
claim_audience, audience
286289
)
287290
)

google/oauth2/id_token.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ def verify_token(id_token, request, audience=None, certs_url=_GOOGLE_OAUTH2_CERT
112112
id_token (Union[str, bytes]): The encoded token.
113113
request (google.auth.transport.Request): The object used to make
114114
HTTP requests.
115-
audience (str): The audience that this token is intended for. If None
116-
then the audience is not verified.
115+
audience (str or list): The audience or audiences that this token is
116+
intended for. If None then the audience is not verified.
117117
certs_url (str): The URL that specifies the certificates to use to
118118
verify the token. This URL should return JSON in the format of
119119
``{'key id': 'x509 certificate'}``.

tests/test_jwt.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,17 @@ def test_decode_valid_with_audience(token_factory):
144144
assert payload["metadata"]["meta"] == "data"
145145

146146

147+
def test_decode_valid_with_audience_list(token_factory):
148+
payload = jwt.decode(
149+
token_factory(),
150+
certs=PUBLIC_CERT_BYTES,
151+
audience=["audience@example.com", "another_audience@example.com"],
152+
)
153+
assert payload["aud"] == "audience@example.com"
154+
assert payload["user"] == "billy bob"
155+
assert payload["metadata"]["meta"] == "data"
156+
157+
147158
def test_decode_valid_unverified(token_factory):
148159
payload = jwt.decode(token_factory(), certs=OTHER_CERT_BYTES, verify=False)
149160
assert payload["aud"] == "audience@example.com"
@@ -211,6 +222,14 @@ def test_decode_bad_token_wrong_audience(token_factory):
211222
assert excinfo.match(r"Token has wrong audience")
212223

213224

225+
def test_decode_bad_token_wrong_audience_list(token_factory):
226+
token = token_factory()
227+
audience = ["audience2@example.com", "audience3@example.com"]
228+
with pytest.raises(ValueError) as excinfo:
229+
jwt.decode(token, PUBLIC_CERT_BYTES, audience=audience)
230+
assert excinfo.match(r"Token has wrong audience")
231+
232+
214233
def test_decode_wrong_cert(token_factory):
215234
with pytest.raises(ValueError) as excinfo:
216235
jwt.decode(token_factory(), OTHER_CERT_BYTES)

0 commit comments

Comments
 (0)