Skip to content

Commit 38d2ce2

Browse files
committed
receive Audience as List instead of an Array.
1 parent 5b80b28 commit 38d2ce2

File tree

12 files changed

+71
-51
lines changed

12 files changed

+71
-51
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,10 @@ String subject = jwt.getSubject();
206206

207207
#### Audience ("aud")
208208

209-
Returns the Audience value in or null if it's not defined in the Payload.
209+
Returns the Audience value or null if it's not defined in the Payload.
210210

211211
```java
212-
String[] audience = jwt.getAudience();
212+
List<String> audience = jwt.getAudience();
213213
```
214214

215215
#### Expiration Time ("exp")

lib/src/main/java/com/auth0/jwt/JWT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.auth0.jwt.interfaces.Claim;
66

77
import java.util.Date;
8+
import java.util.List;
89

910
public final class JWT implements com.auth0.jwt.interfaces.JWT {
1011

@@ -62,7 +63,7 @@ public String getSubject() {
6263
}
6364

6465
@Override
65-
public String[] getAudience() {
66+
public List<String> getAudience() {
6667
return jwt.getAudience();
6768
}
6869

lib/src/main/java/com/auth0/jwt/JWTDecoder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.apache.commons.codec.binary.StringUtils;
1111

1212
import java.util.Date;
13+
import java.util.List;
1314

1415
/**
1516
* The JWTDecoder class holds the decode method to parse a given Token into it's JWT representation.
@@ -88,7 +89,7 @@ public String getSubject() {
8889
}
8990

9091
@Override
91-
public String[] getAudience() {
92+
public List<String> getAudience() {
9293
return payload.getAudience();
9394
}
9495

lib/src/main/java/com/auth0/jwt/JWTVerifier.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public Verification withSubject(String subject) {
8383
* @return this same Verification instance.
8484
*/
8585
public Verification withAudience(String... audience) {
86-
requireClaim(PublicClaims.AUDIENCE, audience);
86+
requireClaim(PublicClaims.AUDIENCE, Arrays.asList(audience));
8787
return this;
8888
}
8989

@@ -258,7 +258,7 @@ private void verifyClaims(JWT jwt, Map<String, Object> claims) {
258258
for (Map.Entry<String, Object> entry : claims.entrySet()) {
259259
switch (entry.getKey()) {
260260
case PublicClaims.AUDIENCE:
261-
assertValidAudienceClaim(jwt.getAudience(), (String[]) entry.getValue());
261+
assertValidAudienceClaim(jwt.getAudience(), (List<String>) entry.getValue());
262262
break;
263263
case PublicClaims.EXPIRES_AT:
264264
assertValidDateClaim(jwt.getExpiresAt(), (Long) entry.getValue(), true);
@@ -329,9 +329,9 @@ private void assertValidDateClaim(Date date, long leeway, boolean shouldBeFuture
329329
}
330330
}
331331

332-
private void assertValidAudienceClaim(String[] audience, String[] value) {
333-
if (!Arrays.equals(audience, value)) {
334-
throw new InvalidClaimException("The Claim 'aud' value doesn't match the required one.");
332+
private void assertValidAudienceClaim(List<String> audience, List<String> value) {
333+
if (audience == null || !audience.containsAll(value)) {
334+
throw new InvalidClaimException("The Claim 'aud' value doesn't contain the required audience.");
335335
}
336336
}
337337
}

lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
1212

1313
import java.io.IOException;
14-
import java.util.Date;
15-
import java.util.Map;
14+
import java.util.*;
1615

1716
class PayloadDeserializer extends StdDeserializer<Payload> {
1817

@@ -34,7 +33,7 @@ public Payload deserialize(JsonParser p, DeserializationContext ctxt) throws IOE
3433

3534
String issuer = getString(tree, PublicClaims.ISSUER);
3635
String subject = getString(tree, PublicClaims.SUBJECT);
37-
String[] audience = getStringOrArray(tree, PublicClaims.AUDIENCE);
36+
List<String> audience = getStringOrArray(tree, PublicClaims.AUDIENCE);
3837
Date expiresAt = getDateFromSeconds(tree, PublicClaims.EXPIRES_AT);
3938
Date notBefore = getDateFromSeconds(tree, PublicClaims.NOT_BEFORE);
4039
Date issuedAt = getDateFromSeconds(tree, PublicClaims.ISSUED_AT);
@@ -43,25 +42,25 @@ public Payload deserialize(JsonParser p, DeserializationContext ctxt) throws IOE
4342
return new PayloadImpl(issuer, subject, audience, expiresAt, notBefore, issuedAt, jwtId, tree);
4443
}
4544

46-
String[] getStringOrArray(Map<String, JsonNode> tree, String claimName) throws JWTDecodeException {
45+
List<String> getStringOrArray(Map<String, JsonNode> tree, String claimName) throws JWTDecodeException {
4746
JsonNode node = tree.remove(claimName);
4847
if (node == null || node.isNull() || !(node.isArray() || node.isTextual())) {
4948
return null;
5049
}
5150
if (node.isTextual() && !node.asText().isEmpty()) {
52-
return new String[]{node.asText()};
51+
return Collections.singletonList(node.asText());
5352
}
5453

5554
ObjectMapper mapper = new ObjectMapper();
56-
String[] arr = new String[node.size()];
55+
List<String> list = new ArrayList<>(node.size());
5756
for (int i = 0; i < node.size(); i++) {
5857
try {
59-
arr[i] = mapper.treeToValue(node.get(i), String.class);
58+
list.add(mapper.treeToValue(node.get(i), String.class));
6059
} catch (JsonProcessingException e) {
6160
throw new JWTDecodeException("Couldn't map the Claim's array contents to String", e);
6261
}
6362
}
64-
return arr;
63+
return list;
6564
}
6665

6766
Date getDateFromSeconds(Map<String, JsonNode> tree, String claimName) {

lib/src/main/java/com/auth0/jwt/impl/PayloadImpl.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
import com.auth0.jwt.interfaces.Payload;
55
import com.fasterxml.jackson.databind.JsonNode;
66

7-
import java.util.Collections;
8-
import java.util.Date;
9-
import java.util.HashMap;
10-
import java.util.Map;
7+
import java.util.*;
118

129
import static com.auth0.jwt.impl.ClaimImpl.extractClaim;
1310

@@ -17,14 +14,14 @@
1714
class PayloadImpl implements Payload {
1815
private final String issuer;
1916
private final String subject;
20-
private final String[] audience;
17+
private final List<String> audience;
2118
private final Date expiresAt;
2219
private final Date notBefore;
2320
private final Date issuedAt;
2421
private final String jwtId;
2522
private final Map<String, JsonNode> tree;
2623

27-
PayloadImpl(String issuer, String subject, String[] audience, Date expiresAt, Date notBefore, Date issuedAt, String jwtId, Map<String, JsonNode> tree) {
24+
PayloadImpl(String issuer, String subject, List<String> audience, Date expiresAt, Date notBefore, Date issuedAt, String jwtId, Map<String, JsonNode> tree) {
2825
this.issuer = issuer;
2926
this.subject = subject;
3027
this.audience = audience;
@@ -50,7 +47,7 @@ public String getSubject() {
5047
}
5148

5249
@Override
53-
public String[] getAudience() {
50+
public List<String> getAudience() {
5451
return audience;
5552
}
5653

lib/src/main/java/com/auth0/jwt/interfaces/Payload.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.auth0.jwt.interfaces;
22

33
import java.util.Date;
4+
import java.util.List;
45

56
/**
67
* The Payload class represents the 2nd part of the JWT, where the Payload value is hold.
@@ -26,7 +27,7 @@ public interface Payload {
2627
*
2728
* @return the Audience value or null.
2829
*/
29-
String[] getAudience();
30+
List<String> getAudience();
3031

3132
/**
3233
* Get the value of the "exp" claim, or null if it's not available.

lib/src/test/java/com/auth0/jwt/JWTDecoderTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.auth0.jwt.interfaces.Claim;
66
import com.auth0.jwt.interfaces.JWT;
77
import org.apache.commons.codec.binary.Base64;
8+
import org.hamcrest.collection.IsCollectionWithSize;
9+
import org.hamcrest.core.IsCollectionContaining;
810
import org.junit.Ignore;
911
import org.junit.Rule;
1012
import org.junit.Test;
@@ -105,16 +107,16 @@ public void shouldGetSubject() throws Exception {
105107
public void shouldGetArrayAudience() throws Exception {
106108
JWT jwt = JWTDecoder.decode("eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOlsiSG9wZSIsIlRyYXZpcyIsIlNvbG9tb24iXX0.Tm4W8WnfPjlmHSmKFakdij0on2rWPETpoM7Sh0u6-S4");
107109
assertThat(jwt, is(notNullValue()));
108-
assertThat(jwt.getAudience(), is(arrayWithSize(3)));
109-
assertThat(jwt.getAudience(), is(arrayContaining("Hope", "Travis", "Solomon")));
110+
assertThat(jwt.getAudience(), is(IsCollectionWithSize.hasSize(3)));
111+
assertThat(jwt.getAudience(), is(IsCollectionContaining.hasItems("Hope", "Travis", "Solomon")));
110112
}
111113

112114
@Test
113115
public void shouldGetStringAudience() throws Exception {
114116
JWT jwt = JWTDecoder.decode("eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJKYWNrIFJleWVzIn0.a4I9BBhPt1OB1GW67g2P1bEHgi6zgOjGUL4LvhE9Dgc");
115117
assertThat(jwt, is(notNullValue()));
116-
assertThat(jwt.getAudience(), is(arrayWithSize(1)));
117-
assertThat(jwt.getAudience(), is(arrayContaining("Jack Reyes")));
118+
assertThat(jwt.getAudience(), is(IsCollectionWithSize.hasSize(1)));
119+
assertThat(jwt.getAudience(), is(IsCollectionContaining.hasItems("Jack Reyes")));
118120
}
119121

120122
@Test

lib/src/test/java/com/auth0/jwt/JWTTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.auth0.jwt;
22

33
import com.auth0.jwt.algorithms.Algorithm;
4+
import org.hamcrest.collection.IsCollectionWithSize;
5+
import org.hamcrest.core.IsCollectionContaining;
46
import org.junit.Rule;
57
import org.junit.Test;
68
import org.junit.rules.ExpectedException;
@@ -207,8 +209,8 @@ public void shouldGetArrayAudience() throws Exception {
207209
.verify(token);
208210

209211
assertThat(jwt, is(notNullValue()));
210-
assertThat(jwt.getAudience(), is(arrayWithSize(3)));
211-
assertThat(jwt.getAudience(), is(arrayContaining("Hope", "Travis", "Solomon")));
212+
assertThat(jwt.getAudience(), is(IsCollectionWithSize.hasSize(3)));
213+
assertThat(jwt.getAudience(), is(IsCollectionContaining.hasItems("Hope", "Travis", "Solomon")));
212214
}
213215

214216
@Test
@@ -219,8 +221,8 @@ public void shouldGetStringAudience() throws Exception {
219221
.verify(token);
220222

221223
assertThat(jwt, is(notNullValue()));
222-
assertThat(jwt.getAudience(), is(arrayWithSize(1)));
223-
assertThat(jwt.getAudience(), is(arrayContaining("Jack Reyes")));
224+
assertThat(jwt.getAudience(), is(IsCollectionWithSize.hasSize(1)));
225+
assertThat(jwt.getAudience(), is(IsCollectionContaining.hasItems("Jack Reyes")));
224226
}
225227

226228
@Test

lib/src/test/java/com/auth0/jwt/JWTVerifierTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,22 @@ public void shouldValidateAudience() throws Exception {
101101
assertThat(jwtArr, is(notNullValue()));
102102
}
103103

104+
@Test
105+
public void shouldAcceptPartialAudience() throws Exception {
106+
//Token 'aud' = ["Mark", "David", "John"]
107+
String tokenArr = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiTWFyayIsIkRhdmlkIiwiSm9obiJdfQ.DX5xXiCaYvr54x_iL0LZsJhK7O6HhAdHeDYkgDeb0Rw";
108+
JWT jwtArr = JWTVerifier.init(Algorithm.HMAC256("secret"))
109+
.withAudience("John")
110+
.build()
111+
.verify(tokenArr);
112+
113+
assertThat(jwtArr, is(notNullValue()));
114+
}
115+
104116
@Test
105117
public void shouldThrowOnInvalidAudience() throws Exception {
106118
exception.expect(InvalidClaimException.class);
107-
exception.expectMessage("The Claim 'aud' value doesn't match the required one.");
119+
exception.expectMessage("The Claim 'aud' value doesn't contain the required audience.");
108120
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.Rq8IxqeX7eA6GgYxlcHdPFVRNFFZc5rEI3MQTZZbK3I";
109121
JWTVerifier.init(Algorithm.HMAC256("secret"))
110122
.withAudience("nope")

0 commit comments

Comments
 (0)