diff --git a/README.md b/README.md index 98edcac5e..5b44cab87 100644 --- a/README.md +++ b/README.md @@ -2992,7 +2992,7 @@ Jwts.parser() #### Parsing of Custom Claim Types -By default JJWT will only convert simple claim types: String, Date, Long, Integer, Short and Byte. If you need to +By default JJWT will only convert simple claim types: String, Instant, Long, Integer, Short and Byte. If you need to deserialize other types you can configure the `JacksonDeserializer` by passing a `Map` of claim names to types in through a constructor. For example: diff --git a/api/src/main/java/io/jsonwebtoken/Claims.java b/api/src/main/java/io/jsonwebtoken/Claims.java index cd1a79dfd..b6e528696 100644 --- a/api/src/main/java/io/jsonwebtoken/Claims.java +++ b/api/src/main/java/io/jsonwebtoken/Claims.java @@ -147,7 +147,7 @@ public interface Claims extends Map, Identifiable { * Returns the JWTs claim ({@code claimName}) value as a {@code requiredType} instance, or {@code null} if not * present. * - *

JJWT only converts simple String, Date, OffsetDateTime, ZonedDateTime, Long, Integer, Short and Byte types automatically. Anything more + *

JJWT only converts simple String, Instant, Long, Integer, Short and Byte types automatically. Anything more * complex is expected to be already converted to your desired type by the JSON parser. You may specify a custom * JSON processor using the {@code JwtParserBuilder}'s * {@link JwtParserBuilder#json(io.jsonwebtoken.io.Deserializer) json(Deserializer)} method. See the JJWT diff --git a/extensions/orgjson/src/main/java/io/jsonwebtoken/orgjson/io/OrgJsonSerializer.java b/extensions/orgjson/src/main/java/io/jsonwebtoken/orgjson/io/OrgJsonSerializer.java index 79b5d5ac3..eb99adcb1 100644 --- a/extensions/orgjson/src/main/java/io/jsonwebtoken/orgjson/io/OrgJsonSerializer.java +++ b/extensions/orgjson/src/main/java/io/jsonwebtoken/orgjson/io/OrgJsonSerializer.java @@ -31,11 +31,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZonedDateTime; -import java.util.Calendar; import java.util.Collection; -import java.util.Date; import java.util.Map; /** @@ -96,26 +92,10 @@ private Object toJSONInstance(Object object) throws IOException { return object; } - if(object instanceof Instant) { + if (object instanceof Instant) { return DateFormats.formatIso8601((Instant) object); } - if(object instanceof OffsetDateTime) { - return DateFormats.formatIso8601(((OffsetDateTime) object).toInstant()); - } - - if(object instanceof ZonedDateTime) { - return DateFormats.formatIso8601(((ZonedDateTime) object).toInstant()); - } - - if (object instanceof Calendar) { - return DateFormats.formatIso8601(((Calendar) object).getTime().toInstant()); - } - - if (object instanceof Date) { - return DateFormats.formatIso8601(((Date) object).toInstant()); - } - if (object instanceof byte[]) { return Encoders.BASE64.encode((byte[]) object); } diff --git a/extensions/orgjson/src/test/groovy/io/jsonwebtoken/orgjson/io/OrgJsonSerializerTest.groovy b/extensions/orgjson/src/test/groovy/io/jsonwebtoken/orgjson/io/OrgJsonSerializerTest.groovy index ad7a6f458..092c78651 100644 --- a/extensions/orgjson/src/test/groovy/io/jsonwebtoken/orgjson/io/OrgJsonSerializerTest.groovy +++ b/extensions/orgjson/src/test/groovy/io/jsonwebtoken/orgjson/io/OrgJsonSerializerTest.groovy @@ -28,8 +28,6 @@ import org.junit.Before import org.junit.Test import java.time.Instant -import java.time.OffsetDateTime -import java.time.ZonedDateTime import static org.junit.Assert.* @@ -201,22 +199,6 @@ class OrgJsonSerializerTest { assertEquals "\"$formatted\"" as String, ser(instant) } - @Test - void testOffsetDateTime() { - OffsetDateTime offsetDateTime = OffsetDateTime.now() - def now = offsetDateTime.toInstant() - String formatted = DateFormats.formatIso8601(now) - assertEquals "\"$formatted\"" as String, ser(offsetDateTime) - } - - @Test - void testZonedDateTime() { - ZonedDateTime zonedDateTime = ZonedDateTime.now() - def now = zonedDateTime.toInstant() - String formatted = DateFormats.formatIso8601(now) - assertEquals "\"$formatted\"" as String, ser(zonedDateTime) - } - @Test void testDate() { Date date = new Date() @@ -225,14 +207,6 @@ class OrgJsonSerializerTest { assertEquals "\"$formatted\"" as String, ser(date) } - @Test - void testCalendar() { - def cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")) - def now = cal.toInstant() - String formatted = DateFormats.formatIso8601(now) - assertEquals "\"$formatted\"" as String, ser(cal) - } - @Test void testSimpleIntArray() { assertEquals '[1,2]', ser([1, 2] as int[]) diff --git a/impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java index fdb5b5e90..08a19f607 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java @@ -30,7 +30,7 @@ public class DefaultClaims extends ParameterMap implements Claims { private static final String CONVERSION_ERROR_MSG = "Cannot convert existing claim value of type '%s' to desired type " + - "'%s'. JJWT only converts simple String, Date, Instant, OffsetDateTime, ZonedDateTime, Long, Integer, Short " + + "'%s'. JJWT only converts simple String, Instant, Long, Integer, Short " + "and Byte types automatically. Anything more complex is expected to be already converted to your desired type " + "by the JSON Deserializer implementation. You may specify a custom Deserializer for a JwtParser with the " + "desired conversion configuration via the JwtParserBuilder.deserializer() method. " + diff --git a/impl/src/main/java/io/jsonwebtoken/impl/lang/JwtDateConverter.java b/impl/src/main/java/io/jsonwebtoken/impl/lang/JwtDateConverter.java index 7098c2259..c60120b52 100644 --- a/impl/src/main/java/io/jsonwebtoken/impl/lang/JwtDateConverter.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/lang/JwtDateConverter.java @@ -18,11 +18,7 @@ import io.jsonwebtoken.lang.DateFormats; import java.time.Instant; -import java.time.ZonedDateTime; -import java.time.OffsetDateTime; import java.time.format.DateTimeParseException; -import java.util.Date; -import java.util.Calendar; public class JwtDateConverter implements Converter { @@ -51,7 +47,7 @@ public static Instant toSpecInstant(Object value) { long seconds = ((Number) value).longValue(); value = Instant.ofEpochSecond(seconds); } - // would have been normalized to Instant if it was a number value, so perform normal date conversion: + // would have been normalized to Instant if it was a number value, so perform normal instant conversion: return toInstant(value); } @@ -66,20 +62,9 @@ public static Instant toInstant(Object v) { return null; } else if (v instanceof Instant) { return (Instant) v; - } else if (v instanceof ZonedDateTime) { - return ((ZonedDateTime) v).toInstant(); - }else if (v instanceof OffsetDateTime) { - return ((OffsetDateTime) v).toInstant(); - } else if (v instanceof Date) { - //assume UTC - return ((Date) v).toInstant(); - } else if (v instanceof Calendar) { //since 0.10.0 - //assume UTC - return ((Calendar) v).getTime().toInstant(); } else if (v instanceof Number) { //assume millis: long millis = ((Number) v).longValue(); - //assume UTC return Instant.ofEpochMilli(millis); } else if (v instanceof String) { return parseIso8601Date((String) v); //ISO-8601 parsing since 0.10.0 diff --git a/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy index b79f5ff0e..44daee654 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy @@ -53,19 +53,10 @@ class JwtsTest { return new Date(secondOnlyPrecisionMillis) } - private static Instant instantWithOnlySecondPrecision(long millis) { - return instantWithOnlySecondPrecision(Instant.ofEpochMilli(millis)) - } - private static Instant instantWithOnlySecondPrecision(Instant instant) { return instant.truncatedTo(ChronoUnit.SECONDS) } - private static Date now() { - Date date = dateWithOnlySecondPrecision(System.currentTimeMillis()) - return date - } - private static int later() { def date = laterDate(10000) def seconds = date.getTime() / 1000 diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy index a1961d1d4..d29162f7d 100644 --- a/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy @@ -23,11 +23,7 @@ import org.junit.Before import org.junit.Test import java.time.Instant -import java.time.OffsetDateTime -import java.time.ZonedDateTime import java.time.temporal.ChronoUnit -import java.time.temporal.TemporalField -import java.time.temporal.TemporalUnit import static org.junit.Assert.* @@ -192,39 +188,6 @@ class DefaultClaimsTest { assertEquals expected, result } - @Test - void testGetRequiredDateFromOffsetDateTime() { - def expected = OffsetDateTime.now() - claims.put("anOffsetDateTime", expected) - OffsetDateTime result = claims.get("anOffsetDateTime", OffsetDateTime.class) - assertEquals expected, result - } - - @Test - void testGetRequiredDateFromZonedDateTime() { - def expected = ZonedDateTime.now() - claims.put("aZonedDateTime", expected) - ZonedDateTime result = claims.get("aZonedDateTime", ZonedDateTime.class) - assertEquals expected, result - } - - @Test - void testGetRequiredDateFromDate() { - def expected = new Date() - claims.put("aDate", expected) - Date result = claims.get("aDate", Date.class) - assertEquals expected, result - } - - @Test - void testGetRequiredDateFromCalendar() { - def c = Calendar.getInstance(TimeZone.getTimeZone("UTC")) - def expected = c.toInstant() - claims.put("aCalender", c) - Instant result = claims.get('aCalender', Instant.class) - assertEquals expected, result - } - @Test void testGetRequiredDateFromLong() { def expected = Instant.now() @@ -342,13 +305,12 @@ class DefaultClaimsTest { } @Test - void testGetSpecDateWithCalendar() { - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")) - Instant instant = cal.toInstant() + void testGetSpecDateWithInstant() { + Instant instant = Instant.now() long seconds = instant.getEpochSecond() - claims.put(Claims.EXPIRATION, cal) - claims.put(Claims.ISSUED_AT, cal) - claims.put(Claims.NOT_BEFORE, cal) + claims.put(Claims.EXPIRATION, instant) + claims.put(Claims.ISSUED_AT, instant) + claims.put(Claims.NOT_BEFORE, instant) assertEquals instant, claims.getExpiration() assertEquals instant, claims.getIssuedAt() assertEquals instant, claims.getNotBefore() @@ -358,11 +320,10 @@ class DefaultClaimsTest { } @Test - void testToSpecDateWithDate() { - long millis = System.currentTimeMillis() - Date d = new Date(millis) - claims.put('exp', d) - assertEquals d.toInstant(), claims.getExpiration() + void testToSpecDateWithInstant() { + Instant i = Instant.now() + claims.put('exp', i) + assertEquals i, claims.getExpiration() } void trySpecDateNonDate(Parameter param) { @@ -411,7 +372,7 @@ class DefaultClaimsTest { void testPutWithIat() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) claims.put('iat', now) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('iat') //conversion should have happened } @@ -420,7 +381,7 @@ class DefaultClaimsTest { void testPutAllWithIat() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) claims.putAll([iat: now]) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('iat') //conversion should have happened } @@ -429,7 +390,7 @@ class DefaultClaimsTest { void testConstructorWithIat() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) this.claims = new DefaultClaims([iat: now]) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('iat') //conversion should have happened } @@ -438,7 +399,7 @@ class DefaultClaimsTest { void testPutWithNbf() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) claims.put('nbf', now) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('nbf') //conversion should have happened } @@ -447,7 +408,7 @@ class DefaultClaimsTest { void testPutAllWithNbf() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) claims.putAll([nbf: now]) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('nbf') //conversion should have happened } @@ -456,7 +417,7 @@ class DefaultClaimsTest { void testConstructorWithNbf() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) this.claims = new DefaultClaims([nbf: now]) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('nbf') //conversion should have happened } @@ -465,7 +426,7 @@ class DefaultClaimsTest { void testPutWithExp() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) claims.put('exp', now) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('exp') //conversion should have happened } @@ -474,7 +435,7 @@ class DefaultClaimsTest { void testPutAllWithExp() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) claims.putAll([exp: now]) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('exp') //conversion should have happened } @@ -483,7 +444,7 @@ class DefaultClaimsTest { void testConstructorWithExp() { long millis = System.currentTimeMillis() long seconds = millis / 1000 as long - Date now = new Date(millis) + Instant now = Instant.ofEpochMilli(millis) this.claims = new DefaultClaims([exp: now]) //this should convert 'now' to seconds since epoch assertEquals seconds, claims.get('exp') //conversion should have happened }