Refactored generic get with required type to handle the official claim types that are dates. Updated javadocs to reflect 'require' language.

This commit is contained in:
Micah Silverman 2015-09-23 17:03:07 -04:00
parent 5d320d22a5
commit 6401727b2a
4 changed files with 69 additions and 29 deletions

View File

@ -28,15 +28,17 @@ public interface JwtParser {
public static final char SEPARATOR_CHAR = '.';
/**
* Sets an expected value for the jti claim.
* Ensures that the specified {@code jti} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* @param id
* @return the parser for method chaining.
* @return the parser method for chaining.
*/
JwtParser requireId(String id);
/**
* Sets an expected value for the subject claim.
* Ensures that the specified {@code sub} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* @param subject
* @return the parser for method chaining.
@ -44,7 +46,8 @@ public interface JwtParser {
JwtParser requireSubject(String subject);
/**
* Sets an expected value for the audience claim.
* Ensures that the specified {@code aud} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* @param audience
* @return the parser for method chaining.
@ -52,7 +55,8 @@ public interface JwtParser {
JwtParser requireAudience(String audience);
/**
* Sets an expected value for the issuer claim.
* Ensures that the specified {@code iss} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* @param issuer
* @return the parser for method chaining.
@ -60,7 +64,8 @@ public interface JwtParser {
JwtParser requireIssuer(String issuer);
/**
* Sets an expected value for the issuedAt claim.
* Ensures that the specified {@code iat} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* @param issuedAt
* @return the parser for method chaining.
@ -68,7 +73,8 @@ public interface JwtParser {
JwtParser requireIssuedAt(Date issuedAt);
/**
* Sets an expected value for the expiration claim.
* Ensures that the specified {@code exp} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* @param expiration
* @return the parser for method chaining.
@ -76,7 +82,8 @@ public interface JwtParser {
JwtParser requireExpiration(Date expiration);
/**
* Sets an expected value for the notBefore claim.
* Ensures that the specified {@code nbf} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* @param notBefore
* @return the parser for method chaining
@ -84,15 +91,14 @@ public interface JwtParser {
JwtParser requireNotBefore(Date notBefore);
/**
* Sets an expected value for any given claim name.
* Ensures that the specified {@code claimName} value is present when parsing the JWT. If not present,
* an exception will be thrown indicating that the JWT is invalid and may not be used.
*
* If an expectation is set for a particular claim name and the JWT being parsed does not have that claim set,
* If a particular claim is required and the JWT being parsed does not have that claim set,
* a {@Link MissingClaimException} will be thrown.
*
* If an expectation is set for a particular claim name and the JWT being parsed has a value that is different than
* the expected value, a {@link IncorrectClaimException} will be thrown.
*
* If either {@code claimName} is null or empty or {@code value} is null, the expectation is simply ignored.
* If a particular claim is required and the JWT being parsed has a value that is different than
* the required value, a {@link IncorrectClaimException} will be thrown.
*
* @param claimName
* @param value

View File

@ -66,7 +66,7 @@ public class DefaultClaims extends JwtMap implements Claims {
@Override
public Date getExpiration() {
return getDate(Claims.EXPIRATION);
return get(Claims.EXPIRATION, Date.class);
}
@Override
@ -77,7 +77,7 @@ public class DefaultClaims extends JwtMap implements Claims {
@Override
public Date getNotBefore() {
return getDate(Claims.NOT_BEFORE);
return get(Claims.NOT_BEFORE, Date.class);
}
@Override
@ -88,7 +88,7 @@ public class DefaultClaims extends JwtMap implements Claims {
@Override
public Date getIssuedAt() {
return getDate(Claims.ISSUED_AT);
return get(Claims.ISSUED_AT, Date.class);
}
@Override
@ -113,6 +113,13 @@ public class DefaultClaims extends JwtMap implements Claims {
Object value = get(claimName);
if (value == null) { return null; }
if (Claims.EXPIRATION.equals(claimName) ||
Claims.ISSUED_AT.equals(claimName) ||
Claims.NOT_BEFORE.equals(claimName)
) {
value = getDate(claimName);
}
if (requiredType == Date.class && value instanceof Long) {
value = new Date((Long)value);
}

View File

@ -381,16 +381,18 @@ public class DefaultJwtParser implements JwtParser {
Object expectedClaimValue = expectedClaims.get(expectedClaimName);
Object actualClaimValue = claims.get(expectedClaimName);
if (Claims.ISSUED_AT.equals(expectedClaimName)) {
expectedClaimValue = expectedClaims.getIssuedAt();
actualClaimValue = claims.getIssuedAt();
} else if (Claims.EXPIRATION.equals(expectedClaimName)) {
expectedClaimValue = expectedClaims.getExpiration();
actualClaimValue = claims.getExpiration();
} else if (Claims.NOT_BEFORE.equals(expectedClaimName)) {
expectedClaimValue = expectedClaims.getNotBefore();
actualClaimValue = claims.getNotBefore();
} else if (expectedClaimValue instanceof Date && actualClaimValue != null && actualClaimValue instanceof Long) {
if (
Claims.ISSUED_AT.equals(expectedClaimName) ||
Claims.EXPIRATION.equals(expectedClaimName) ||
Claims.NOT_BEFORE.equals(expectedClaimName)
) {
expectedClaimValue = expectedClaims.get(expectedClaimName, Date.class);
actualClaimValue = claims.get(expectedClaimName, Date.class);
} else if (
expectedClaimValue instanceof Date &&
actualClaimValue != null &&
actualClaimValue instanceof Long
) {
actualClaimValue = new Date((Long)actualClaimValue);
}

View File

@ -64,7 +64,7 @@ class DefaultClaimsTest {
def actual = new Date();
claims.put("aDate", actual)
Date expected = claims.get("aDate", Date.class);
assertEquals(expected, actual);
assertEquals(expected, actual)
}
@Test
@ -73,6 +73,31 @@ class DefaultClaimsTest {
// note that Long is stored in claim
claims.put("aDate", actual.getTime())
Date expected = claims.get("aDate", Date.class);
assertEquals(expected, actual);
assertEquals(expected, actual)
}
@Test
void testGetClaimExpiration_Success() {
def now = new Date(System.currentTimeMillis())
claims.setExpiration(now)
Date expected = claims.get("exp", Date.class)
assertEquals(expected, claims.getExpiration())
}
@Test
void testGetClaimIssuedAt_Success() {
def now = new Date(System.currentTimeMillis())
claims.setIssuedAt(now)
Date expected = claims.get("iat", Date.class)
assertEquals(expected, claims.getIssuedAt())
}
@Test
void testGetClaimNotBefore_Success() {
def now = new Date(System.currentTimeMillis())
claims.setNotBefore(now)
Date expected = claims.get("nbf", Date.class)
assertEquals(expected, claims.getNotBefore())
}
}