mirror of https://github.com/jwtk/jjwt.git
109: enabled injection of a time source - a 'Clock'
This commit is contained in:
parent
13d2e8370a
commit
72e0e3b23c
|
@ -1,7 +1,22 @@
|
|||
package io.jsonwebtoken;
|
||||
|
||||
import io.jsonwebtoken.impl.DefaultClock;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A clock represents a time source that can be used when creating and verifying JWTs.
|
||||
*
|
||||
* @since 0.7.0
|
||||
*/
|
||||
public interface Clock {
|
||||
|
||||
public static final Clock DEFAULT = new DefaultClock();
|
||||
|
||||
/**
|
||||
* Returns the clock's current timestamp at the instant the method is invoked.
|
||||
*
|
||||
* @return the clock's current timestamp at the instant the method is invoked.
|
||||
*/
|
||||
Date now();
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package io.jsonwebtoken;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class DefaultClock implements Clock {
|
||||
@Override
|
||||
public Date now() {
|
||||
return new Date();
|
||||
}
|
||||
}
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package io.jsonwebtoken;
|
||||
|
||||
import io.jsonwebtoken.impl.DefaultClock;
|
||||
|
||||
import java.security.Key;
|
||||
import java.util.Date;
|
||||
|
||||
|
@ -125,11 +127,12 @@ public interface JwtParser {
|
|||
JwtParser require(String claimName, Object value);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Sets the {@link Clock} that determines the timestamp to use when validating the parsed JWT.
|
||||
* The parser uses a {@link DefaultClock DefaultClock} instance by default.
|
||||
*
|
||||
* @param clock a {@code Clock} object to return the time-of-day or {@code null}
|
||||
* @param clock a {@code Clock} object to return the timestamp to use when validating the parsed JWT.
|
||||
* @return the builder instance for method chaining.
|
||||
* @since 0.7.0
|
||||
*/
|
||||
JwtParser setClock(Clock clock);
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package io.jsonwebtoken.impl;
|
||||
|
||||
import io.jsonwebtoken.Clock;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Default {@link Clock} implementation.
|
||||
*
|
||||
* @since 0.7.0
|
||||
*/
|
||||
public class DefaultClock implements Clock {
|
||||
|
||||
/**
|
||||
* Simply returns <code>new {@link Date}()</code>.
|
||||
*
|
||||
* @return a new {@link Date} instance.
|
||||
*/
|
||||
@Override
|
||||
public Date now() {
|
||||
return new Date();
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ 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;
|
||||
|
@ -71,7 +70,7 @@ public class DefaultJwtParser implements JwtParser {
|
|||
|
||||
Claims expectedClaims = new DefaultClaims();
|
||||
|
||||
private Clock clock = new DefaultClock();
|
||||
private Clock clock = Clock.DEFAULT;
|
||||
|
||||
@Override
|
||||
public JwtParser requireIssuedAt(Date issuedAt) {
|
||||
|
@ -133,12 +132,8 @@ public class DefaultJwtParser implements JwtParser {
|
|||
|
||||
@Override
|
||||
public JwtParser setClock(Clock clock) {
|
||||
if (clock == null) {
|
||||
this.clock = new DefaultClock();
|
||||
} else {
|
||||
Assert.notNull(clock, "Clock instance cannot be null.");
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,30 @@ import io.jsonwebtoken.Clock;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A {@code Clock} implementation that is constructed with a seed timestamp and always reports that same
|
||||
* timestamp.
|
||||
*
|
||||
* @since 0.7.0
|
||||
*/
|
||||
public class FixedClock implements Clock {
|
||||
|
||||
private final Date now;
|
||||
|
||||
/**
|
||||
* Creates a new fixed clock using <code>new {@link Date Date}()</code> as the seed timestamp. All calls to
|
||||
* {@link #now now()} will always return this seed Date.
|
||||
*/
|
||||
public FixedClock() {
|
||||
this(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new fixed clock using the specified seed timestamp. All calls to
|
||||
* {@link #now now()} will always return this seed Date.
|
||||
*
|
||||
* @param now the specified Date to always return from all calls to {@link #now now()}.
|
||||
*/
|
||||
public FixedClock(Date now) {
|
||||
this.now = now;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package io.jsonwebtoken
|
||||
|
||||
import io.jsonwebtoken.impl.DefaultClock
|
||||
import io.jsonwebtoken.impl.FixedClock
|
||||
import io.jsonwebtoken.impl.TextCodec
|
||||
import org.junit.Test
|
||||
|
@ -1407,15 +1408,11 @@ class JwtParserTest {
|
|||
|
||||
@Test
|
||||
void testParseClockManipulationWithNullClock() {
|
||||
Date expiry = new Date(System.currentTimeMillis() - 1000)
|
||||
|
||||
String compact = Jwts.builder().setSubject('Joe').setExpiration(expiry).compact()
|
||||
|
||||
JwtParser parser = Jwts.parser();
|
||||
try {
|
||||
Jwts.parser().setClock(null).parse(compact)
|
||||
parser.setClock(null)
|
||||
fail()
|
||||
} catch (ExpiredJwtException e) {
|
||||
assertTrue e.getMessage().startsWith('JWT expired at ')
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package io.jsonwebtoken.impl
|
||||
|
||||
import org.junit.Test
|
||||
import static org.junit.Assert.*
|
||||
|
||||
class FixedClockTest {
|
||||
|
||||
@Test
|
||||
void testFixedClockDefaultConstructor() {
|
||||
|
||||
def clock = new FixedClock()
|
||||
|
||||
def date1 = clock.now()
|
||||
Thread.sleep(100)
|
||||
def date2 = clock.now()
|
||||
|
||||
assertSame date1, date2
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue