Added expectIssuedAt convenience method.

This commit is contained in:
Micah Silverman 2015-09-12 02:53:57 -04:00
parent 8f49666a40
commit 0fab5504cd
3 changed files with 100 additions and 6 deletions

View File

@ -16,6 +16,7 @@
package io.jsonwebtoken; package io.jsonwebtoken;
import java.security.Key; import java.security.Key;
import java.util.Date;
/** /**
* A parser for reading JWT strings, used to convert them into a {@link Jwt} object representing the expanded JWT. * A parser for reading JWT strings, used to convert them into a {@link Jwt} object representing the expanded JWT.
@ -26,6 +27,14 @@ public interface JwtParser {
public static final char SEPARATOR_CHAR = '.'; public static final char SEPARATOR_CHAR = '.';
/**
* Sets an expected value for the issuedAt claim.
*
* @param issuedAt
* @return the parser for method chaining.
*/
JwtParser expectIssuedAt(Date issuedAt);
/** /**
* Sets an expected value for any given claim name. * Sets an expected value for any given claim name.
* *

View File

@ -46,7 +46,6 @@ import java.io.IOException;
import java.security.Key; import java.security.Key;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -63,7 +62,16 @@ public class DefaultJwtParser implements JwtParser {
private SigningKeyResolver signingKeyResolver; private SigningKeyResolver signingKeyResolver;
Map<String, Object> expectedClaims = new LinkedHashMap<String, Object>(); Claims expectedClaims = new DefaultClaims();
@Override
public JwtParser expectIssuedAt(Date issuedAt) {
if (issuedAt != null) {
expectedClaims.setIssuedAt(issuedAt);
}
return this;
}
@Override @Override
public JwtParser expect(String claimName, Object value) { public JwtParser expect(String claimName, Object value) {
@ -329,8 +337,16 @@ public class DefaultJwtParser implements JwtParser {
private void validateExpectedClaims(Header header, Claims claims) { private void validateExpectedClaims(Header header, Claims claims) {
for (String expectedClaimName : expectedClaims.keySet()) { for (String expectedClaimName : expectedClaims.keySet()) {
Object expectedClaimValue = expectedClaims.get(expectedClaimName); Object expectedClaimValue = null;
Object actualClaimValue = claims.get(expectedClaimName); Object actualClaimValue = null;
if (Claims.ISSUED_AT.equals(expectedClaimName)) {
expectedClaimValue = expectedClaims.getIssuedAt();
actualClaimValue = claims.getIssuedAt();
} else {
expectedClaimValue = expectedClaims.get(expectedClaimName);
actualClaimValue = claims.get(expectedClaimName);
}
InvalidClaimException invalidClaimException = null; InvalidClaimException invalidClaimException = null;
if (actualClaimValue == null) { if (actualClaimValue == null) {

View File

@ -22,6 +22,8 @@ import javax.crypto.spec.SecretKeySpec
import java.security.SecureRandom import java.security.SecureRandom
import static org.junit.Assert.* import static org.junit.Assert.*
import static ClaimJwtException.INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE
import static ClaimJwtException.MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE
class JwtParserTest { class JwtParserTest {
@ -819,7 +821,7 @@ class JwtParserTest {
fail() fail()
} catch (IncorrectClaimException e) { } catch (IncorrectClaimException e) {
assertEquals( assertEquals(
String.format(ClaimJwtException.INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, goodClaimName, goodClaimValue, badClaimValue), String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, goodClaimName, goodClaimValue, badClaimValue),
e.getMessage() e.getMessage()
) )
} }
@ -843,7 +845,74 @@ class JwtParserTest {
fail() fail()
} catch (MissingClaimException e) { } catch (MissingClaimException e) {
assertEquals( assertEquals(
String.format(ClaimJwtException.MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, claimName, claimValue), String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, claimName, claimValue),
e.getMessage()
)
}
}
@Test
void testParseExpectIssuedAt_Success() {
def issuedAt = new Date(System.currentTimeMillis())
byte[] key = randomKey()
String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setIssuedAt(issuedAt).
compact()
Jwt<Header,Claims> jwt = Jwts.parser().setSigningKey(key).
expectIssuedAt(issuedAt).
parseClaimsJws(compact)
// system converts to seconds (lopping off millis precision), then returns millis
def issuedAtMillis = ((long)issuedAt.getTime() / 1000) * 1000
assertEquals jwt.getBody().getIssuedAt().getTime(), issuedAtMillis
}
@Test
void testParseExpectIssuedAt_Incorrect_Fail() {
def goodIssuedAt = new Date(System.currentTimeMillis())
def badIssuedAt = new Date(System.currentTimeMillis() - 10000)
byte[] key = randomKey()
String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setIssuedAt(badIssuedAt).
compact()
try {
Jwts.parser().setSigningKey(key).
expectIssuedAt(goodIssuedAt).
parseClaimsJws(compact)
fail()
} catch(IncorrectClaimException e) {
assertEquals(
String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ISSUED_AT, goodIssuedAt, badIssuedAt),
e.getMessage()
)
}
}
@Test
void testParseExpectIssuedAt_Missing_Fail() {
def issuedAt = new Date(System.currentTimeMillis() - 10000)
byte[] key = randomKey()
String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key).
setSubject("Dummy").
compact()
try {
Jwts.parser().setSigningKey(key).
expectIssuedAt(issuedAt).
parseClaimsJws(compact)
fail()
} catch(MissingClaimException e) {
assertEquals(
String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ISSUED_AT, issuedAt),
e.getMessage() e.getMessage()
) )
} }