create a new Interface "Clock" plus implementations of Clock to exhibit desired behavior

This commit is contained in:
Mitchell Morris 2016-02-23 19:30:20 -06:00
parent 83054a755d
commit a20c92c095
6 changed files with 83 additions and 11 deletions

View File

@ -0,0 +1,7 @@
package io.jsonwebtoken;
import java.util.Date;
public interface Clock {
Date now();
}

View File

@ -0,0 +1,10 @@
package io.jsonwebtoken;
import java.util.Date;
public class DefaultClock implements Clock {
@Override
public Date now() {
return new Date();
}
}

View File

@ -125,13 +125,13 @@ public interface JwtParser {
JwtParser require(String claimName, Object value);
/**
* Replaces the system time-of-day call to return this fixed value instead. A {@code null} value will remove
* the fixed date output and return the system time-of-day instead.
* Replace the {@code clock} used by the parser to determine the current time-of-day to use when validating
* the parsed JWT. If {@code null}, will reset the behavior to use the system clock.
*
* @param now the time-of-day to use for parsimg this JWT or {@code null} to use the current time-of-day
* @param clock a {@code Clock} object to return the time-of-day or {@code null}
* @return the builder instance for method chaining.
*/
JwtParser setFixedClock(Date now);
JwtParser setClock(Clock clock);
/**
* Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not

View File

@ -18,8 +18,10 @@ package io.jsonwebtoken.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.ClaimJwtException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.CompressionCodec;
import io.jsonwebtoken.CompressionCodecResolver;
import io.jsonwebtoken.DefaultClock;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.IncorrectClaimException;
@ -69,7 +71,7 @@ public class DefaultJwtParser implements JwtParser {
Claims expectedClaims = new DefaultClaims();
private Date now = new Date();
private Clock clock = new DefaultClock();
@Override
public JwtParser requireIssuedAt(Date issuedAt) {
@ -130,11 +132,11 @@ public class DefaultJwtParser implements JwtParser {
}
@Override
public JwtParser setFixedClock(Date now) {
if (now == null) {
this.now = new Date();
public JwtParser setClock(Clock clock) {
if (clock == null) {
this.clock = new DefaultClock();
} else {
this.now = now;
this.clock = clock;
}
return this;
@ -361,6 +363,8 @@ public class DefaultJwtParser implements JwtParser {
SimpleDateFormat sdf;
final Date now = this.clock.now();
//https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30#section-4.1.4
//token MUST NOT be accepted on or after any specified exp time:
Date exp = claims.getExpiration();

View File

@ -0,0 +1,22 @@
package io.jsonwebtoken.impl;
import io.jsonwebtoken.Clock;
import java.util.Date;
public class FixedClock implements Clock {
private final Date now;
public FixedClock() {
this(new Date());
}
public FixedClock(Date now) {
this.now = now;
}
@Override
public Date now() {
return this.now;
}
}

View File

@ -15,6 +15,7 @@
*/
package io.jsonwebtoken
import io.jsonwebtoken.impl.FixedClock
import io.jsonwebtoken.impl.TextCodec
import org.junit.Test
@ -1394,13 +1395,41 @@ class JwtParserTest {
}
@Test
void testParseClockManipulation() {
void testParseClockManipulationWithFixedClock() {
def then = System.currentTimeMillis() - 1000
Date expiry = new Date(then)
Date beforeExpiry = new Date(then - 1000)
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
Jwts.parser().setFixedClock(beforeExpiry).parse(compact)
Jwts.parser().setClock(new FixedClock(beforeExpiry)).parse(compact)
}
@Test
void testParseClockManipulationWithNullClock() {
Date expiry = new Date(System.currentTimeMillis() - 1000)
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
try {
Jwts.parser().setClock(null).parse(compact)
fail()
} catch (ExpiredJwtException e) {
assertTrue e.getMessage().startsWith('JWT expired at ')
}
}
@Test
void testParseClockManipulationWithDefaultClock() {
Date expiry = new Date(System.currentTimeMillis() - 1000)
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
try {
Jwts.parser().setClock(new DefaultClock()).parse(compact)
fail()
} catch (ExpiredJwtException e) {
assertTrue e.getMessage().startsWith('JWT expired at ')
}
}
}