Skip to content

Commit 0edc6f9

Browse files
committed
Merge pull request auth0#12 from Toilal/verify-exceptions
Use explicit JWTVerifyException for claims related verifying
2 parents 619c82c + 7dda86d commit 0edc6f9

6 files changed

Lines changed: 91 additions & 12 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.auth0.jwt;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class JWTAudienceException extends JWTVerifyException {
9+
private JsonNode audienceNode;
10+
11+
public JWTAudienceException(JsonNode audienceNode) {
12+
this.audienceNode = audienceNode;
13+
}
14+
15+
public JWTAudienceException(String message, JsonNode audienceNode) {
16+
super(message);
17+
this.audienceNode = audienceNode;
18+
}
19+
20+
public List<String> getAudience() {
21+
ArrayList<String> audience = new ArrayList<String>();
22+
if (audienceNode.isArray()) {
23+
for (JsonNode jsonNode : audienceNode) {
24+
audience.add(jsonNode.textValue());
25+
}
26+
} else if (audienceNode.isTextual()) {
27+
audience.add(audienceNode.textValue());
28+
}
29+
return audience;
30+
}
31+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.auth0.jwt;
2+
3+
public class JWTExpiredException extends JWTVerifyException {
4+
private long expiration;
5+
6+
public JWTExpiredException(long expiration) {
7+
this.expiration = expiration;
8+
}
9+
10+
public JWTExpiredException(String message, long expiration) {
11+
super(message);
12+
this.expiration = expiration;
13+
}
14+
15+
public long getExpiration() {
16+
return expiration;
17+
};
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.auth0.jwt;
2+
3+
public class JWTIssuerException extends JWTVerifyException {
4+
private final String issuer;
5+
6+
public JWTIssuerException(String issuer) {
7+
this.issuer = issuer;
8+
}
9+
10+
public JWTIssuerException(String message, String issuer) {
11+
super(message);
12+
this.issuer = issuer;
13+
}
14+
15+
public String getIssuer() {
16+
return issuer;
17+
}
18+
}

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.security.InvalidKeyException;
1111
import java.security.NoSuchAlgorithmException;
1212
import java.security.SignatureException;
13+
import java.util.ArrayList;
1314
import java.util.Arrays;
1415
import java.util.HashMap;
1516
import java.util.Map;
@@ -62,11 +63,12 @@ public JWTVerifier(String secret) {
6263
*
6364
* @param token token to verify
6465
* @throws SignatureException when signature is invalid
65-
* @throws IllegalStateException when token's structure, expiration, issuer or audience are invalid
66+
* @throws JWTVerifyException when expiration, issuer or audience are invalid
67+
* @throws IllegalStateException when token's structure is invalid
6668
*/
6769
public Map<String, Object> verify(String token)
6870
throws NoSuchAlgorithmException, InvalidKeyException, IllegalStateException,
69-
IOException, SignatureException {
71+
IOException, SignatureException, JWTVerifyException {
7072
if (token == null || "".equals(token)) {
7173
throw new IllegalStateException("token not set");
7274
}
@@ -107,23 +109,23 @@ void verifySignature(String[] pieces, String algorithm) throws NoSuchAlgorithmEx
107109
}
108110
}
109111

110-
void verifyExpiration(JsonNode jwtClaims) {
112+
void verifyExpiration(JsonNode jwtClaims) throws JWTExpiredException {
111113
final long expiration = jwtClaims.has("exp") ? jwtClaims.get("exp").asLong(0) : 0;
112114

113115
if (expiration != 0 && System.currentTimeMillis() / 1000L >= expiration) {
114-
throw new IllegalStateException("jwt expired");
116+
throw new JWTExpiredException("jwt expired", expiration);
115117
}
116118
}
117119

118-
void verifyIssuer(JsonNode jwtClaims) {
120+
void verifyIssuer(JsonNode jwtClaims) throws JWTIssuerException {
119121
final String issuerFromToken = jwtClaims.has("iss") ? jwtClaims.get("iss").asText() : null;
120122

121123
if (issuerFromToken != null && issuer != null && !issuer.equals(issuerFromToken)) {
122-
throw new IllegalStateException("jwt issuer invalid");
124+
throw new JWTIssuerException("jwt issuer invalid", issuerFromToken);
123125
}
124126
}
125127

126-
void verifyAudience(JsonNode jwtClaims) {
128+
void verifyAudience(JsonNode jwtClaims) throws JWTAudienceException {
127129
if (audience == null)
128130
return;
129131
JsonNode audNode = jwtClaims.get("aud");
@@ -138,7 +140,7 @@ void verifyAudience(JsonNode jwtClaims) {
138140
if (audience.equals(audNode.textValue()))
139141
return;
140142
}
141-
throw new IllegalStateException("jwt audience invalid");
143+
throw new JWTAudienceException("jwt audience invalid", audNode);
142144
}
143145

144146
String getAlgorithm(JsonNode jwtHeader) {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.auth0.jwt;
2+
3+
public class JWTVerifyException extends Exception {
4+
public JWTVerifyException() {
5+
}
6+
7+
public JWTVerifyException(String message) {
8+
super(message);
9+
}
10+
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void shouldVerifySignature() throws Exception {
9090
.verifySignature(jws.split("\\."), "HmacSHA256");
9191
}
9292

93-
@Test(expected = IllegalStateException.class)
93+
@Test(expected = JWTExpiredException.class)
9494
public void shouldFailWhenExpired1SecondAgo() throws Exception {
9595
new JWTVerifier("such secret").verifyExpiration(
9696
createSingletonJSONNode("exp", Long.toString(System.currentTimeMillis() / 1000L - 1L)));
@@ -108,7 +108,7 @@ public void shouldVerifyIssuer() throws Exception {
108108
.verifyIssuer(createSingletonJSONNode("iss", "very issuer"));
109109
}
110110

111-
@Test(expected = IllegalStateException.class)
111+
@Test(expected = JWTIssuerException.class)
112112
public void shouldFailIssuer() throws Exception {
113113
new JWTVerifier("such secret", "amaze audience", "very issuer")
114114
.verifyIssuer(createSingletonJSONNode("iss", "wow"));
@@ -126,7 +126,7 @@ public void shouldVerifyAudience() throws Exception {
126126
.verifyAudience(createSingletonJSONNode("aud", "amaze audience"));
127127
}
128128

129-
@Test(expected = IllegalStateException.class)
129+
@Test(expected = JWTAudienceException.class)
130130
public void shouldFailAudience() throws Exception {
131131
new JWTVerifier("such secret", "amaze audience")
132132
.verifyAudience(createSingletonJSONNode("aud", "wow"));
@@ -151,7 +151,7 @@ public void shouldVerifyArrayAudience() throws Exception {
151151
new ObjectMapper().readValue("[ \"foo\", \"amaze audience\" ]", ArrayNode.class)));
152152
}
153153

154-
@Test(expected = IllegalStateException.class)
154+
@Test(expected = JWTAudienceException.class)
155155
public void shouldFailArrayAudience() throws Exception {
156156
new JWTVerifier("such secret", "amaze audience")
157157
.verifyAudience(createSingletonJSONNode("aud",

0 commit comments

Comments
 (0)