Skip to content

Commit 5b80b28

Browse files
authored
Merge pull request auth0#104 from auth0/leeway-seconds
Receive Leeway as seconds
2 parents ae5cb54 + 30260eb commit 5b80b28

File tree

3 files changed

+25
-24
lines changed

3 files changed

+25
-24
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,20 @@ The JWT token may include DateNumber fields that can be used to validate that:
125125

126126
When verifying a token the time validation occurs automatically, resulting in a `JWTVerificationException` being throw when the values are invalid. If any of the previous fields are missing they won't be considered in this validation.
127127

128-
To specify a **leeway window** in which the Token should still be considered valid, use the `acceptLeeway()` method in the `JWTVerifier` builder and pass a positive milliseconds value. This applies to every item listed above.
128+
To specify a **leeway window** in which the Token should still be considered valid, use the `acceptLeeway()` method in the `JWTVerifier` builder and pass a positive seconds value. This applies to every item listed above.
129129

130130
```java
131131
JWTVerifier verifier = JWT.require(Algorithm.RSA256(key))
132-
.acceptLeeway(100) //nbf, iat and exp
132+
.acceptLeeway(1) // 1 sec for nbf, iat and exp
133133
.build();
134134
```
135135

136136
You can also specify a custom value for a given Date claim and override the default one for only that claim.
137137

138138
```java
139139
JWTVerifier verifier = JWT.require(Algorithm.RSA256(key))
140-
.acceptLeeway(100) //nbf and iat
141-
.acceptExpiresAt(500) //exp
140+
.acceptLeeway(1) //1 sec for nbf and iat
141+
.acceptExpiresAt(5) //5 secs for exp
142142
.build();
143143
```
144144

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public Verification withAudience(String... audience) {
9191
* Define the default window in milliseconds in which the Not Before, Issued At and Expires At Claims will still be valid.
9292
* Setting a specific leeway value on a given Claim will override this value for that Claim.
9393
*
94-
* @param leeway the window in milliseconds in which the Not Before, Issued At and Expires At Claims will still be valid.
94+
* @param leeway the window in seconds in which the Not Before, Issued At and Expires At Claims will still be valid.
9595
* @return this same Verification instance.
9696
* @throws IllegalArgumentException if leeway is negative.
9797
*/
@@ -104,10 +104,10 @@ public Verification acceptLeeway(long leeway) throws IllegalArgumentException {
104104
}
105105

106106
/**
107-
* Set a specific leeway window in milliseconds in which the Expires At ("exp") Claim will still be valid.
107+
* Set a specific leeway window in seconds in which the Expires At ("exp") Claim will still be valid.
108108
* Expiration Date is always verified when the value is present. This method overrides the value set with acceptLeeway
109109
*
110-
* @param leeway the window in milliseconds in which the Expires At Claim will still be valid.
110+
* @param leeway the window in seconds in which the Expires At Claim will still be valid.
111111
* @return this same Verification instance.
112112
* @throws IllegalArgumentException if leeway is negative.
113113
*/
@@ -120,10 +120,10 @@ public Verification acceptExpiresAt(long leeway) throws IllegalArgumentException
120120
}
121121

122122
/**
123-
* Set a specific leeway window in milliseconds in which the Not Before ("nbf") Claim will still be valid.
123+
* Set a specific leeway window in seconds in which the Not Before ("nbf") Claim will still be valid.
124124
* Not Before Date is always verified when the value is present. This method overrides the value set with acceptLeeway
125125
*
126-
* @param leeway the window in milliseconds in which the Not Before Claim will still be valid.
126+
* @param leeway the window in seconds in which the Not Before Claim will still be valid.
127127
* @return this same Verification instance.
128128
* @throws IllegalArgumentException if leeway is negative.
129129
*/
@@ -136,10 +136,10 @@ public Verification acceptNotBefore(long leeway) throws IllegalArgumentException
136136
}
137137

138138
/**
139-
* Set a specific leeway window in milliseconds in which the Issued At ("iat") Claim will still be valid.
139+
* Set a specific leeway window in seconds in which the Issued At ("iat") Claim will still be valid.
140140
* Issued At Date is always verified when the value is present. This method overrides the value set with acceptLeeway
141141
*
142-
* @param leeway the window in milliseconds in which the Issued At Claim will still be valid.
142+
* @param leeway the window in seconds in which the Issued At Claim will still be valid.
143143
* @return this same Verification instance.
144144
* @throws IllegalArgumentException if leeway is negative.
145145
*/
@@ -201,11 +201,11 @@ public JWTVerifier build() {
201201
* @return a new JWTVerifier instance with a custom Clock.
202202
*/
203203
JWTVerifier build(Clock clock) {
204-
addDeltaToDateClaims();
204+
addLeewayToDateClaims();
205205
return new JWTVerifier(algorithm, claims, clock);
206206
}
207207

208-
private void addDeltaToDateClaims() {
208+
private void addLeewayToDateClaims() {
209209
if (!claims.containsKey(PublicClaims.EXPIRES_AT)) {
210210
claims.put(PublicClaims.EXPIRES_AT, defaultLeeway);
211211
}
@@ -312,14 +312,15 @@ private void assertValidStringClaim(String claimName, String value, String expec
312312

313313
private void assertValidDateClaim(Date date, long leeway, boolean shouldBeFuture) {
314314
Date today = clock.getToday();
315+
today.setTime((long) Math.floor((today.getTime() / 1000) * 1000)); //truncate millis
315316
boolean isValid;
316317
String errMessage;
317318
if (shouldBeFuture) {
318-
today.setTime(today.getTime() - leeway);
319+
today.setTime(today.getTime() - leeway * 1000);
319320
isValid = date == null || !today.after(date);
320321
errMessage = String.format("The Token has expired on %s.", date);
321322
} else {
322-
today.setTime(today.getTime() + leeway);
323+
today.setTime(today.getTime() + leeway * 1000);
323324
isValid = date == null || !today.before(date);
324325
errMessage = String.format("The Token can't be used before %s.", date);
325326
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,11 @@ public void shouldThrowOnNegativeCustomLeeway() throws Exception {
338338
@Test
339339
public void shouldValidateExpiresAtWithLeeway() throws Exception {
340340
Clock clock = mock(Clock.class);
341-
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE + 299));
341+
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE + 1000));
342342

343343
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0Nzc1OTJ9.isvT0Pqx0yjnZk53mUFSeYFJLDs-Ls9IsNAm86gIdZo";
344344
JWT jwt = JWTVerifier.init(Algorithm.HMAC256("secret"))
345-
.acceptExpiresAt(300)
345+
.acceptExpiresAt(2)
346346
.build(clock)
347347
.verify(token);
348348

@@ -367,7 +367,7 @@ public void shouldThrowOnInvalidExpiresAtIfPresent() throws Exception {
367367
exception.expect(InvalidClaimException.class);
368368
exception.expectMessage(startsWith("The Token has expired on"));
369369
Clock clock = mock(Clock.class);
370-
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE + 10));
370+
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE + 1000));
371371

372372
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0Nzc1OTJ9.isvT0Pqx0yjnZk53mUFSeYFJLDs-Ls9IsNAm86gIdZo";
373373
JWTVerifier.init(Algorithm.HMAC256("secret"))
@@ -388,11 +388,11 @@ public void shouldThrowOnNegativeExpiresAtLeeway() throws Exception {
388388
@Test
389389
public void shouldValidateNotBeforeWithLeeway() throws Exception {
390390
Clock clock = mock(Clock.class);
391-
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 299));
391+
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 1000));
392392

393393
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0Nzc1OTJ9.wq4ZmnSF2VOxcQBxPLfeh1J2Ozy1Tj5iUaERm3FKaw8";
394394
JWT jwt = JWTVerifier.init(Algorithm.HMAC256("secret"))
395-
.acceptNotBefore(300)
395+
.acceptNotBefore(2)
396396
.build(clock)
397397
.verify(token);
398398

@@ -404,7 +404,7 @@ public void shouldThrowOnInvalidNotBeforeIfPresent() throws Exception {
404404
exception.expect(InvalidClaimException.class);
405405
exception.expectMessage(startsWith("The Token can't be used before"));
406406
Clock clock = mock(Clock.class);
407-
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 10));
407+
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 1000));
408408

409409
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0Nzc1OTJ9.wq4ZmnSF2VOxcQBxPLfeh1J2Ozy1Tj5iUaERm3FKaw8";
410410
JWTVerifier.init(Algorithm.HMAC256("secret"))
@@ -438,11 +438,11 @@ public void shouldThrowOnNegativeNotBeforeLeeway() throws Exception {
438438
@Test
439439
public void shouldValidateIssuedAtWithLeeway() throws Exception {
440440
Clock clock = mock(Clock.class);
441-
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 299));
441+
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 1000));
442442

443443
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0Nzc1OTJ9.0WJky9eLN7kuxLyZlmbcXRL3Wy8hLoNCEk5CCl2M4lo";
444444
JWT jwt = JWTVerifier.init(Algorithm.HMAC256("secret"))
445-
.acceptIssuedAt(300)
445+
.acceptIssuedAt(2)
446446
.build(clock)
447447
.verify(token);
448448

@@ -454,7 +454,7 @@ public void shouldThrowOnInvalidIssuedAtIfPresent() throws Exception {
454454
exception.expect(InvalidClaimException.class);
455455
exception.expectMessage(startsWith("The Token can't be used before"));
456456
Clock clock = mock(Clock.class);
457-
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 10));
457+
when(clock.getToday()).thenReturn(new Date(DATE_TOKEN_MS_VALUE - 1000));
458458

459459
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0Nzc1OTJ9.0WJky9eLN7kuxLyZlmbcXRL3Wy8hLoNCEk5CCl2M4lo";
460460
JWTVerifier.init(Algorithm.HMAC256("secret"))

0 commit comments

Comments
 (0)