Hello, I've encountered a problem (similar to
https://groups.google.com/g/pac4j-users/c/aYuLjX3Z2AY/m/8fmi4uaiAQAJ) with the custom "expiration" claim added and used by
OidcProfile to verify profile expiration in
OidcProfile.isExpired. I'll modify slightly the test code above to demonstrate the bug (modifications are in red):
@Test
void contextLoads() {
GoogleOidcProfile googleOidcProfile = new GoogleOidcProfile();
googleOidcProfile.setTokenExpirationAdvance(-1);
final Date expiration = Date.from(Instant.now().plusSeconds(3600));
googleOidcProfile.addAttribute(OidcProfileDefinition.EXPIRATION, expiration); // normally this is set by OidcProfile.setAccessToken
final SecretSignatureConfiguration secretSignatureConfiguration = new SecretSignatureConfiguration("12345678901234567890123456789012");
final JwtGenerator generator = new JwtGenerator();
generator.setSignatureConfiguration(secretSignatureConfiguration);
String token = generator.generate(googleOidcProfile);
JwtAuthenticator jwtAuthenticator = new JwtAuthenticator();
jwtAuthenticator.setSignatureConfiguration(secretSignatureConfiguration);
UserProfile userProfile = jwtAuthenticator.validateToken(token);
assertFalse(userProfile.isExpired()); // this failed
}
The problem here is that Nimbus json serializer turned a Date value into unix epoch time (in seconds) whereas OidcProfile.isExpired (more specifically CommonProfile.getAttributeAsDate) treated the serialized value as unix time in milliseconds and tried to restore a Date object from it, thus falsified the result.
According to the comment in getAttributeAsDate, I believe that conversion has been added in order to mitigate the serialization of Jackson that converts Date
into unix timestamp in milliseconds. Maybe we should just ignore that
particular case and treat "expiration" as number of seconds, as in "exp"
or "iat" of the oidc specs, every time we see it ?