Skip to content

Commit 9c8132d

Browse files
committed
Properly validate issuer & audience when supplied
Previously JWTVerifier didn't validate issuer & audience if those claims where missing from the token, deeming it valid.
1 parent 111023b commit 9c8132d

File tree

4 files changed

+36
-13
lines changed

4 files changed

+36
-13
lines changed

src/main/java/com/auth0/jwt/JWTAudienceException.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@ public class JWTAudienceException extends JWTVerifyException {
1414
private JsonNode audienceNode;
1515

1616
public JWTAudienceException(final JsonNode audienceNode) {
17-
Validate.notNull(audienceNode);
1817
this.audienceNode = audienceNode;
1918
}
2019

2120
public JWTAudienceException(final String message, final JsonNode audienceNode) {
2221
super(message);
23-
Validate.notNull(audienceNode);
2422
this.audienceNode = audienceNode;
2523
}
2624

src/main/java/com/auth0/jwt/JWTIssuerException.java

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

3-
import org.apache.commons.lang3.Validate;
4-
53
/**
64
* Represents Exception related to Issuer - for example issuer mismatch / missing upon verification
75
*/
@@ -10,13 +8,11 @@ public class JWTIssuerException extends JWTVerifyException {
108
private final String issuer;
119

1210
public JWTIssuerException(final String issuer) {
13-
Validate.notNull(issuer);
1411
this.issuer = issuer;
1512
}
1613

1714
public JWTIssuerException(final String message, final String issuer) {
1815
super(message);
19-
Validate.notNull(issuer);
2016
this.issuer = issuer;
2117
}
2218

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,27 +185,37 @@ protected void verifyExpiration(final JsonNode jwtClaims) throws JWTExpiredExcep
185185

186186
protected void verifyIssuer(final JsonNode jwtClaims) throws JWTIssuerException {
187187
Validate.notNull(jwtClaims);
188+
189+
if (this.issuer == null ) {
190+
return;
191+
}
192+
188193
final String issuerFromToken = jwtClaims.has("iss") ? jwtClaims.get("iss").asText() : null;
189-
if (issuerFromToken != null && issuer != null && !issuer.equals(issuerFromToken)) {
194+
195+
if (issuerFromToken == null || !issuer.equals(issuerFromToken)) {
190196
throw new JWTIssuerException("jwt issuer invalid", issuerFromToken);
191197
}
192198
}
193199

194200
protected void verifyAudience(final JsonNode jwtClaims) throws JWTAudienceException {
195201
Validate.notNull(jwtClaims);
196-
if (audience == null)
202+
if (audience == null) {
197203
return;
204+
}
198205
final JsonNode audNode = jwtClaims.get("aud");
199-
if (audNode == null)
200-
return;
206+
if (audNode == null) {
207+
throw new JWTAudienceException("jwt audience invalid", null);
208+
}
201209
if (audNode.isArray()) {
202210
for (final JsonNode jsonNode : audNode) {
203-
if (audience.equals(jsonNode.textValue()))
211+
if (audience.equals(jsonNode.textValue())) {
204212
return;
213+
}
205214
}
206215
} else if (audNode.isTextual()) {
207-
if (audience.equals(audNode.textValue()))
216+
if (audience.equals(audNode.textValue())) {
208217
return;
218+
}
209219
}
210220
throw new JWTAudienceException("jwt audience invalid", audNode);
211221
}

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
77
import com.fasterxml.jackson.databind.node.ObjectNode;
88
import org.apache.commons.codec.binary.Base64;
9+
import org.junit.Rule;
910
import org.junit.Test;
11+
import org.junit.rules.ExpectedException;
1012

1113
import java.security.SignatureException;
1214

@@ -19,6 +21,8 @@ public class JWTVerifierTest {
1921

2022
private static final Base64 decoder = new Base64(true);
2123

24+
@Rule
25+
public ExpectedException expectedException = ExpectedException.none();
2226

2327
@Test(expected = IllegalArgumentException.class)
2428
public void constructorShouldFailOnEmptySecret() {
@@ -85,7 +89,7 @@ public void shouldVerifySignature() throws Exception {
8589
"cGxlLmNvbS9pc19yb290Ijp0cnVlfQ" +
8690
"." +
8791
"dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk";
88-
byte[] secret = decoder.decodeBase64("AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow");
92+
byte[] secret = decoder.decode("AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow");
8993
new JWTVerifier(secret, "audience")
9094
.verifySignature(jws.split("\\."), Algorithm.HS256);
9195
}
@@ -116,6 +120,7 @@ public void shouldFailIssuer() throws Exception {
116120

117121
@Test
118122
public void shouldVerifyIssuerWhenNotFoundInClaimsSet() throws Exception {
123+
expectedException.expect(JWTIssuerException.class);
119124
new JWTVerifier("such secret", "amaze audience", "very issuer")
120125
.verifyIssuer(JsonNodeFactory.instance.objectNode());
121126
}
@@ -134,6 +139,7 @@ public void shouldFailAudience() throws Exception {
134139

135140
@Test
136141
public void shouldVerifyAudienceWhenNotFoundInClaimsSet() throws Exception {
142+
expectedException.expect(JWTAudienceException.class);
137143
new JWTVerifier("such secret", "amaze audience")
138144
.verifyAudience(JsonNodeFactory.instance.objectNode());
139145
}
@@ -171,6 +177,19 @@ public void decodeAndParse() throws Exception {
171177
assertEquals("123", decodedJSON.get("number").asText());
172178
}
173179

180+
@Test
181+
public void shouldVerifyAudienceFromToken() throws Exception {
182+
expectedException.expect(JWTAudienceException.class);
183+
JWTVerifier verifier = new JWTVerifier("I.O.U a secret", "samples-api", null);
184+
verifier.verify("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.wLlz9xDltxqKHQC7BeauPi5Q4KQK4nDjlRqQPvKVLYk");
185+
}
186+
187+
@Test
188+
public void shouldVerifyIssuerFromToken() throws Exception {
189+
expectedException.expect(JWTIssuerException.class);
190+
JWTVerifier verifier = new JWTVerifier("I.O.U a secret", null, "samples.auth0.com");
191+
verifier.verify("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.wLlz9xDltxqKHQC7BeauPi5Q4KQK4nDjlRqQPvKVLYk");
192+
}
174193

175194
public static JsonNode createSingletonJSONNode(String key, String value) {
176195
final ObjectNode jsonNodes = JsonNodeFactory.instance.objectNode();

0 commit comments

Comments
 (0)