KEYCLOAK-12960 Use Long for time based values in JsonWebToken

This commit is contained in:
stianst 2020-02-14 11:37:16 +01:00 committed by Stian Thorgersen
parent 167f73f54e
commit 536824beb6
5 changed files with 106 additions and 28 deletions

View file

@ -17,6 +17,7 @@
package org.keycloak.representations;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.keycloak.TokenCategory;
@ -61,8 +62,7 @@ public class IDToken extends JsonWebToken {
@JsonProperty(NONCE)
protected String nonce;
@JsonProperty(AUTH_TIME)
protected int authTime;
protected Long auth_time;
@JsonProperty(SESSION_STATE)
protected String sessionState;
@ -149,12 +149,28 @@ public class IDToken extends JsonWebToken {
this.nonce = nonce;
}
public int getAuthTime() {
return authTime;
public Long getAuth_time() {
return auth_time;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #getAuth_time()} instead.
*/
@Deprecated
@JsonIgnore
public int getAuthTime() {
return auth_time != null ? auth_time.intValue() : 0;
}
public void setAuth_time(Long auth_time) {
this.auth_time = auth_time;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #setAuth_time(Long)} ()} instead.
*/
public void setAuthTime(int authTime) {
this.authTime = authTime;
this.auth_time = Long.valueOf(authTime);
}
public String getSessionState() {

View file

@ -41,12 +41,11 @@ import java.util.Map;
public class JsonWebToken implements Serializable, Token {
@JsonProperty("jti")
protected String id;
@JsonProperty("exp")
protected int expiration;
@JsonProperty("nbf")
protected int notBefore;
@JsonProperty("iat")
protected int issuedAt;
protected Long exp;
protected Long nbf;
protected Long iat;
@JsonProperty("iss")
protected String issuer;
@JsonProperty("aud")
@ -70,33 +69,68 @@ public class JsonWebToken implements Serializable, Token {
return this;
}
public int getExpiration() {
return expiration;
public Long getExp() {
return exp;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #getExp()} instead.
*/
@Deprecated
@JsonIgnore
public int getExpiration() {
return exp != null ? exp.intValue() : 0;
}
public JsonWebToken exp(Long exp) {
this.exp = exp;
return this;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #exp(Long)} instead.
*/
public JsonWebToken expiration(int expiration) {
this.expiration = expiration;
this.exp = Long.valueOf(expiration);
return this;
}
@JsonIgnore
public boolean isExpired() {
return Time.currentTime() > expiration;
return exp != null && exp != 0 ? Time.currentTime() > exp : false;
}
public Long getNbf() {
return nbf;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #getNbf()} instead.
*/
@Deprecated
@JsonIgnore
public int getNotBefore() {
return notBefore;
return nbf != null ? nbf.intValue() : 0;
}
public JsonWebToken nbf(Long nbf) {
this.nbf = nbf;
return this;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #nbf(Long)} instead.
*/
@Deprecated
@JsonIgnore
public JsonWebToken notBefore(int notBefore) {
this.notBefore = notBefore;
this.nbf = Long.valueOf(notBefore);
return this;
}
@JsonIgnore
public boolean isNotBefore(int allowedTimeSkew) {
return Time.currentTime() + allowedTimeSkew >= notBefore;
return nbf != null ? Time.currentTime() + allowedTimeSkew >= nbf : true;
}
/**
@ -111,11 +145,20 @@ public class JsonWebToken implements Serializable, Token {
@JsonIgnore
public boolean isActive(int allowedTimeSkew) {
return (!isExpired() || expiration == 0) && (isNotBefore(allowedTimeSkew) || notBefore == 0);
return !isExpired() && isNotBefore(allowedTimeSkew);
}
public Long getIat() {
return iat;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #getIat()} instead.
*/
@Deprecated
@JsonIgnore
public int getIssuedAt() {
return issuedAt;
return iat != null ? iat.intValue() : 0;
}
/**
@ -123,12 +166,22 @@ public class JsonWebToken implements Serializable, Token {
*/
@JsonIgnore
public JsonWebToken issuedNow() {
issuedAt = Time.currentTime();
iat = Long.valueOf(Time.currentTime());
return this;
}
public JsonWebToken iat(Long iat) {
this.iat = iat;
return this;
}
/**
* @deprecated int will overflow with values after 2038. Use {@link #iat(Long)} ()} instead.
*/
@Deprecated
@JsonIgnore
public JsonWebToken issuedAt(int issuedAt) {
this.issuedAt = issuedAt;
this.iat = Long.valueOf(issuedAt);
return this;
}

View file

@ -46,7 +46,7 @@ public class DefaultActionTokenKey extends JsonWebToken implements ActionTokenKe
public DefaultActionTokenKey(String userId, String actionId, int absoluteExpirationInSecs, UUID actionVerificationNonce) {
this.subject = userId;
this.type = actionId;
this.expiration = absoluteExpirationInSecs;
this.exp = Long.valueOf(absoluteExpirationInSecs);
this.actionVerificationNonce = actionVerificationNonce == null ? UUID.randomUUID() : actionVerificationNonce;
}

View file

@ -222,6 +222,15 @@ public class AccessTokenTest extends AbstractKeycloakTest {
assertEquals(sessionId, token.getSessionState());
assertNull(token.getNbf());
assertEquals(0, token.getNotBefore());
assertNotNull(token.getIat());
assertEquals(token.getIat().intValue(), token.getIssuedAt());
assertNotNull(token.getExp());
assertEquals(token.getExp().intValue(), token.getExpiration());
assertEquals(1, token.getRealmAccess().getRoles().size());
assertTrue(token.getRealmAccess().isUserInRole("user"));

View file

@ -108,7 +108,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
assertEquals("test-app", jsonNode.get("client_id").asText());
assertTrue(jsonNode.has("exp"));
assertTrue(jsonNode.has("iat"));
assertTrue(jsonNode.has("nbf"));
assertFalse(jsonNode.has("nbf"));
assertTrue(jsonNode.has("sub"));
assertTrue(jsonNode.has("aud"));
assertTrue(jsonNode.has("iss"));
@ -121,7 +121,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
assertEquals("test-app", rep.getClientId());
assertEquals(jsonNode.get("exp").asInt(), rep.getExpiration());
assertEquals(jsonNode.get("iat").asInt(), rep.getIssuedAt());
assertEquals(jsonNode.get("nbf").asInt(), rep.getNotBefore());
assertEquals(jsonNode.get("nbf"), rep.getNbf());
assertEquals(jsonNode.get("sub").asText(), rep.getSubject());
List<String> audiences = new ArrayList<>();
@ -163,7 +163,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
assertEquals("test-app", jsonNode.get("client_id").asText());
assertTrue(jsonNode.has("exp"));
assertTrue(jsonNode.has("iat"));
assertTrue(jsonNode.has("nbf"));
assertFalse(jsonNode.has("nbf"));
assertTrue(jsonNode.has("sub"));
assertTrue(jsonNode.has("aud"));
assertTrue(jsonNode.has("iss"));
@ -177,7 +177,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
assertEquals(jsonNode.get("session_state").asText(), rep.getSessionState());
assertEquals(jsonNode.get("exp").asInt(), rep.getExpiration());
assertEquals(jsonNode.get("iat").asInt(), rep.getIssuedAt());
assertEquals(jsonNode.get("nbf").asInt(), rep.getNotBefore());
assertEquals(jsonNode.get("nbf"), rep.getNbf());
assertEquals(jsonNode.get("iss").asText(), rep.getIssuer());
assertEquals(jsonNode.get("jti").asText(), rep.getId());
assertEquals(jsonNode.get("typ").asText(), "Refresh");