Skip to content

Commit 8b676c0

Browse files
committed
add time claims verification in the isExpired method.
1 parent c4fffb2 commit 8b676c0

6 files changed

Lines changed: 126 additions & 24 deletions

File tree

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,15 @@ public String getSignature() {
112112

113113
@Override
114114
public boolean isExpired() {
115-
//TODO: Add advanced validation
116-
return false;
115+
final Date iat = getIssuedAt();
116+
final Date nbf = getNotBefore();
117+
final Date exp = getExpiresAt();
118+
final Date today = new Date();
119+
120+
boolean issuedAtValid = iat == null || iat.before(today);
121+
boolean notBeforeValid = nbf == null || nbf.after(today);
122+
boolean expiresAtValid = exp == null || exp.after(today);
123+
124+
return !issuedAtValid || !notBeforeValid || !expiresAtValid;
117125
}
118126
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ String[] getStringOrArray(Map<String, JsonNode> tree, String claimName) throws J
6464
return arr;
6565
}
6666

67-
private Date getDate(Map<String, JsonNode> tree, String claimName) {
67+
Date getDate(Map<String, JsonNode> tree, String claimName) {
6868
JsonNode node = tree.get(claimName);
6969
if (node == null || node.isNull() || !node.canConvertToLong()) {
7070
return null;
@@ -73,7 +73,7 @@ private Date getDate(Map<String, JsonNode> tree, String claimName) {
7373
return new Date(ms);
7474
}
7575

76-
private String getString(Map<String, JsonNode> tree, String claimName) {
76+
String getString(Map<String, JsonNode> tree, String claimName) {
7777
JsonNode node = tree.get(claimName);
7878
if (node == null || node.isNull()) {
7979
return null;

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
*/
66
public interface JWT extends Payload, Header, Signature {
77

8-
//TODO replace with advanced validations
8+
/**
9+
* Tests whether this token's DateTime values IssuedAt, ExpiresAt and NotBefore are time valid.
10+
* If any of them are missing they won't be taken into account. If the token it's expired it shouldn't be used.
11+
*
12+
* @return whether the token should be used or not.
13+
*/
914
boolean isExpired();
1015
}

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

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

3-
import com.auth0.jwt.JWTDecoder;
43
import com.auth0.jwt.exceptions.JWTDecodeException;
54
import com.auth0.jwt.impl.BaseClaim;
65
import com.auth0.jwt.interfaces.Claim;
@@ -175,42 +174,46 @@ public void shouldGetType() throws Exception {
175174
}
176175

177176
@Test
178-
@Ignore("Pending implementation")
179177
public void shouldBeExpired() throws Exception {
180178
long pastSeconds = System.currentTimeMillis() / 1000;
181179
long futureSeconds = (System.currentTimeMillis() + 10000) / 1000;
182180

183-
JWT issuedAndExpiresInTheFuture = customTimeJWT(futureSeconds, futureSeconds);
181+
JWT issuedAndExpiresInTheFuture = customTimeJWT(futureSeconds, futureSeconds, futureSeconds);
184182
assertTrue(issuedAndExpiresInTheFuture.isExpired());
185-
JWT issuedInTheFuture = customTimeJWT(futureSeconds, null);
183+
JWT issuedInTheFuture = customTimeJWT(futureSeconds, null, null);
186184
assertTrue(issuedInTheFuture.isExpired());
187185

188-
JWT issuedAndExpiresInThePast = customTimeJWT(pastSeconds, pastSeconds);
186+
JWT issuedAndExpiresInThePast = customTimeJWT(pastSeconds, pastSeconds, pastSeconds);
189187
assertTrue(issuedAndExpiresInThePast.isExpired());
190-
JWT expiresInThePast = customTimeJWT(null, pastSeconds);
188+
JWT expiresInThePast = customTimeJWT(null, pastSeconds, null);
191189
assertTrue(expiresInThePast.isExpired());
192190

193-
JWT issuedInTheFutureExpiresInThePast = customTimeJWT(futureSeconds, pastSeconds);
191+
JWT issuedInTheFutureExpiresInThePast = customTimeJWT(futureSeconds, pastSeconds, pastSeconds);
194192
assertTrue(issuedInTheFutureExpiresInThePast.isExpired());
193+
194+
JWT notBeforeThePast = customTimeJWT(null, null, pastSeconds);
195+
assertTrue(notBeforeThePast.isExpired());
195196
}
196197

197198
@Test
198-
@Ignore("Pending implementation")
199199
public void shouldNotBeExpired() throws Exception {
200200
long pastSeconds = System.currentTimeMillis() / 1000;
201201
long futureSeconds = (System.currentTimeMillis() + 10000) / 1000;
202202

203-
JWT missingDates = customTimeJWT(null, null);
203+
JWT missingDates = customTimeJWT(null, null, null);
204204
assertFalse(missingDates.isExpired());
205205

206-
JWT issuedInThePastExpiresInTheFuture = customTimeJWT(pastSeconds, futureSeconds);
206+
JWT issuedInThePastExpiresInTheFuture = customTimeJWT(pastSeconds, futureSeconds, futureSeconds);
207207
assertFalse(issuedInThePastExpiresInTheFuture.isExpired());
208208

209-
JWT issuedInThePast = customTimeJWT(pastSeconds, null);
209+
JWT issuedInThePast = customTimeJWT(pastSeconds, null, null);
210210
assertFalse(issuedInThePast.isExpired());
211211

212-
JWT expiresInTheFuture = customTimeJWT(null, futureSeconds);
212+
JWT expiresInTheFuture = customTimeJWT(null, futureSeconds, null);
213213
assertFalse(expiresInTheFuture.isExpired());
214+
215+
JWT notBeforeTheFuture = customTimeJWT(null, null, futureSeconds);
216+
assertFalse(notBeforeTheFuture.isExpired());
214217
}
215218

216219
//Private PublicClaims
@@ -241,17 +244,23 @@ public void shouldGetNullClaimIfClaimValueIsNull() throws Exception {
241244

242245
//Helper Methods
243246

244-
private JWT customTimeJWT(Long iat, Long exp) {
247+
private JWT customTimeJWT(Long iat, Long exp, Long nbf) {
245248
String header = base64Encode("{}");
246249
StringBuilder bodyBuilder = new StringBuilder("{");
247250
if (iat != null) {
248-
bodyBuilder.append("\"iat\":\"").append(iat.longValue()).append("\"");
251+
bodyBuilder.append("\"iat\":").append(iat.longValue());
249252
}
250253
if (exp != null) {
251254
if (iat != null) {
252255
bodyBuilder.append(",");
253256
}
254-
bodyBuilder.append("\"exp\":\"").append(exp.longValue()).append("\"");
257+
bodyBuilder.append("\"exp\":").append(exp.longValue());
258+
}
259+
if (nbf != null) {
260+
if (iat != null || exp != null) {
261+
bodyBuilder.append(",");
262+
}
263+
bodyBuilder.append("\"nbf\":").append(nbf.longValue());
255264
}
256265
bodyBuilder.append("}");
257266
String body = base64Encode(bodyBuilder.toString());

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,15 @@ public void shouldGetType() throws Exception {
284284
assertThat(jwt, is(notNullValue()));
285285
assertThat(jwt.getType(), is("JWS"));
286286
}
287+
288+
@Test
289+
public void shouldGetIfItsExpired() throws Exception {
290+
String token = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NzY3MjcwODZ9.L9dcPHEDQew2u9MkDCORFkfDGcSOsgoPqNY-LUMLEHg";
291+
JWT jwt = JWT.require(Algorithm.HMAC256("secret"))
292+
.build()
293+
.verify(token);
294+
295+
assertThat(jwt, is(notNullValue()));
296+
assertThat(jwt.isExpired(), is(true));
297+
}
287298
}

lib/src/test/java/com/auth0/jwt/impl/PayloadDeserializerTest.java

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@
1313
import org.junit.Test;
1414
import org.junit.rules.ExpectedException;
1515

16-
import java.util.ArrayList;
17-
import java.util.HashMap;
18-
import java.util.List;
19-
import java.util.Map;
16+
import java.util.*;
2017

2118
import static org.hamcrest.Matchers.*;
2219
import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining;
@@ -126,4 +123,76 @@ public void shouldGetNullArrayWhenParsingNonArrayOrTextNode() throws Exception {
126123
assertThat(values, is(nullValue()));
127124
}
128125

126+
127+
@Test
128+
public void shouldGetNullDateWhenParsingNullNode() throws Exception {
129+
Map<String, JsonNode> tree = new HashMap<>();
130+
NullNode node = NullNode.getInstance();
131+
tree.put("key", node);
132+
133+
Date date = deserializer.getDate(tree, "key");
134+
assertThat(date, is(nullValue()));
135+
}
136+
137+
@Test
138+
public void shouldGetNullDateWhenParsingNull() throws Exception {
139+
Map<String, JsonNode> tree = new HashMap<>();
140+
tree.put("key", null);
141+
142+
Date date = deserializer.getDate(tree, "key");
143+
assertThat(date, is(nullValue()));
144+
}
145+
146+
@Test
147+
public void shouldGetNullDateWhenParsingNonNumericNode() throws Exception {
148+
Map<String, JsonNode> tree = new HashMap<>();
149+
TextNode node = new TextNode("123456789");
150+
tree.put("key", node);
151+
152+
Date date = deserializer.getDate(tree, "key");
153+
assertThat(date, is(nullValue()));
154+
}
155+
156+
@Test
157+
public void shouldGetDateWhenParsingNumericNode() throws Exception {
158+
Map<String, JsonNode> tree = new HashMap<>();
159+
long seconds = 1478627949 / 1000;
160+
LongNode node = new LongNode(seconds);
161+
tree.put("key", node);
162+
163+
Date date = deserializer.getDate(tree, "key");
164+
assertThat(date, is(notNullValue()));
165+
assertThat(date.getTime(), is(seconds * 1000));
166+
}
167+
168+
@Test
169+
public void shouldGetNullStringWhenParsingNullNode() throws Exception {
170+
Map<String, JsonNode> tree = new HashMap<>();
171+
NullNode node = NullNode.getInstance();
172+
tree.put("key", node);
173+
174+
String text = deserializer.getString(tree, "key");
175+
assertThat(text, is(nullValue()));
176+
}
177+
178+
@Test
179+
public void shouldGetNullStringWhenParsingNull() throws Exception {
180+
Map<String, JsonNode> tree = new HashMap<>();
181+
tree.put("key", null);
182+
183+
String text = deserializer.getString(tree, "key");
184+
assertThat(text, is(nullValue()));
185+
}
186+
187+
@Test
188+
public void shouldGetStringWhenParsingTextNode() throws Exception {
189+
Map<String, JsonNode> tree = new HashMap<>();
190+
TextNode node = new TextNode("something here");
191+
tree.put("key", node);
192+
193+
String text = deserializer.getString(tree, "key");
194+
assertThat(text, is(notNullValue()));
195+
assertThat(text, is("something here"));
196+
}
197+
129198
}

0 commit comments

Comments
 (0)