replaced and removed deprecated token methods (#27715)
closes #19671 Signed-off-by: Mark Banierink <mark.banierink@nedap.com> Co-authored-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
8e48bac278
commit
ad32896725
42 changed files with 216 additions and 259 deletions
|
@ -110,7 +110,7 @@ public class BearerTokenRequestAuthenticator {
|
||||||
challenge = challengeResponse(exchange, OIDCAuthenticationError.Reason.INVALID_TOKEN, "invalid_token", e.getMessage());
|
challenge = challengeResponse(exchange, OIDCAuthenticationError.Reason.INVALID_TOKEN, "invalid_token", e.getMessage());
|
||||||
return AuthOutcome.FAILED;
|
return AuthOutcome.FAILED;
|
||||||
}
|
}
|
||||||
if (token.getIssuedAt() < deployment.getNotBefore()) {
|
if (token.getIat() < deployment.getNotBefore()) {
|
||||||
log.debug("Stale token");
|
log.debug("Stale token");
|
||||||
challenge = challengeResponse(exchange, OIDCAuthenticationError.Reason.STALE_TOKEN, "invalid_token", "Stale token");
|
challenge = challengeResponse(exchange, OIDCAuthenticationError.Reason.STALE_TOKEN, "invalid_token", "Stale token");
|
||||||
return AuthOutcome.FAILED;
|
return AuthOutcome.FAILED;
|
||||||
|
|
|
@ -369,7 +369,7 @@ public class OAuthRequestAuthenticator {
|
||||||
if (tokenResponse.getNotBeforePolicy() > deployment.getNotBefore()) {
|
if (tokenResponse.getNotBeforePolicy() > deployment.getNotBefore()) {
|
||||||
deployment.updateNotBefore(tokenResponse.getNotBeforePolicy());
|
deployment.updateNotBefore(tokenResponse.getNotBeforePolicy());
|
||||||
}
|
}
|
||||||
if (token.getIssuedAt() < deployment.getNotBefore()) {
|
if (token.getIat() < deployment.getNotBefore()) {
|
||||||
log.error("Stale token");
|
log.error("Stale token");
|
||||||
return challenge(403, OIDCAuthenticationError.Reason.STALE_TOKEN, null);
|
return challenge(403, OIDCAuthenticationError.Reason.STALE_TOKEN, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,11 +88,11 @@ public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return token != null && this.token.isActive() && deployment!=null && this.token.getIssuedAt() >= deployment.getNotBefore();
|
return token != null && this.token.isActive() && deployment!=null && this.token.getIat() >= deployment.getNotBefore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTokenTimeToLiveSufficient(AccessToken token) {
|
public boolean isTokenTimeToLiveSufficient(AccessToken token) {
|
||||||
return token != null && (token.getExpiration() - this.deployment.getTokenMinimumTimeToLive()) > Time.currentTime();
|
return token != null && (token.getExp() - this.deployment.getTokenMinimumTimeToLive()) > Time.currentTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeycloakDeployment getDeployment() {
|
public KeycloakDeployment getDeployment() {
|
||||||
|
|
|
@ -43,13 +43,13 @@ public class RefreshableKeycloakSecurityContextTest {
|
||||||
|
|
||||||
TokenMetadataRepresentation token = new TokenMetadataRepresentation();
|
TokenMetadataRepresentation token = new TokenMetadataRepresentation();
|
||||||
token.setActive(true);
|
token.setActive(true);
|
||||||
token.issuedAt(4999);
|
token.iat(4999L);
|
||||||
|
|
||||||
RefreshableKeycloakSecurityContext sut = new RefreshableKeycloakSecurityContext(keycloakDeployment,null,null,token,null, null, null);
|
RefreshableKeycloakSecurityContext sut = new RefreshableKeycloakSecurityContext(keycloakDeployment,null,null,token,null, null, null);
|
||||||
|
|
||||||
assertFalse(sut.isActive());
|
assertFalse(sut.isActive());
|
||||||
|
|
||||||
token.issuedAt(5000);
|
token.iat(5000L);
|
||||||
assertTrue(sut.isActive());
|
assertTrue(sut.isActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,10 @@
|
||||||
package org.keycloak.adapters.installed;
|
package org.keycloak.adapters.installed;
|
||||||
|
|
||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -37,16 +35,9 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ForkJoinPool;
|
import java.util.concurrent.ForkJoinPool;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.ws.rs.client.Entity;
|
|
||||||
import javax.ws.rs.core.Form;
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
|
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.OAuthErrorException;
|
import org.keycloak.OAuthErrorException;
|
||||||
import org.keycloak.adapters.KeycloakDeployment;
|
import org.keycloak.adapters.KeycloakDeployment;
|
||||||
|
@ -314,7 +305,7 @@ public class KeycloakInstalled {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTokenString(long minValidity, TimeUnit unit) throws VerificationException, IOException, ServerRequest.HttpFailure {
|
public String getTokenString(long minValidity, TimeUnit unit) throws VerificationException, IOException, ServerRequest.HttpFailure {
|
||||||
long expires = ((long) token.getExpiration()) * 1000 - unit.toMillis(minValidity);
|
long expires = ((long) token.getExp()) * 1000 - unit.toMillis(minValidity);
|
||||||
if (expires < System.currentTimeMillis()) {
|
if (expires < System.currentTimeMillis()) {
|
||||||
refreshToken();
|
refreshToken();
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class TokenCallable implements Callable<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTokenTimeToLiveSufficient(AccessToken token) {
|
public boolean isTokenTimeToLiveSufficient(AccessToken token) {
|
||||||
return token != null && (token.getExpiration() - getConfiguration().getTokenMinimumTimeToLive()) > Time.currentTime();
|
return token != null && (token.getExp() - getConfiguration().getTokenMinimumTimeToLive()) > Time.currentTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -182,10 +182,10 @@ public class JWTClientCredentialsProvider implements ClientCredentialsProvider {
|
||||||
reqToken.subject(clientId);
|
reqToken.subject(clientId);
|
||||||
reqToken.audience(realmInfoUrl);
|
reqToken.audience(realmInfoUrl);
|
||||||
|
|
||||||
int now = Time.currentTime();
|
long now = Time.currentTime();
|
||||||
reqToken.issuedAt(now);
|
reqToken.iat(now);
|
||||||
reqToken.expiration(now + this.tokenTimeout);
|
reqToken.exp(now + this.tokenTimeout);
|
||||||
reqToken.notBefore(now);
|
reqToken.nbf(now);
|
||||||
|
|
||||||
return reqToken;
|
return reqToken;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,11 +131,11 @@ public class JWTClientSecretCredentialsProvider implements ClientCredentialsProv
|
||||||
reqToken.subject(clientId);
|
reqToken.subject(clientId);
|
||||||
reqToken.audience(realmInfoUrl);
|
reqToken.audience(realmInfoUrl);
|
||||||
|
|
||||||
int now = Time.currentTime();
|
long now = Time.currentTime();
|
||||||
reqToken.issuedAt(now);
|
reqToken.iat(now);
|
||||||
// the same as in KEYCLOAK-2986, JWTClientCredentialsProvider's timeout field
|
// the same as in KEYCLOAK-2986, JWTClientCredentialsProvider's timeout field
|
||||||
reqToken.expiration(now + 10);
|
reqToken.exp(now + 10);
|
||||||
reqToken.notBefore(now);
|
reqToken.nbf(now);
|
||||||
return reqToken;
|
return reqToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,22 +205,6 @@ public class AccessToken extends IDToken {
|
||||||
return (AccessToken) super.id(id);
|
return (AccessToken) super.id(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessToken expiration(int expiration) {
|
|
||||||
return (AccessToken) super.expiration(expiration);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessToken notBefore(int notBefore) {
|
|
||||||
return (AccessToken) super.notBefore(notBefore);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AccessToken issuedAt(int issuedAt) {
|
|
||||||
return (AccessToken) super.issuedAt(issuedAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AccessToken issuer(String issuer) {
|
public AccessToken issuer(String issuer) {
|
||||||
return (AccessToken) super.issuer(issuer);
|
return (AccessToken) super.issuer(issuer);
|
||||||
|
|
|
@ -154,27 +154,10 @@ public class IDToken extends JsonWebToken {
|
||||||
return auth_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) {
|
public void setAuth_time(Long auth_time) {
|
||||||
this.auth_time = 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.auth_time = Long.valueOf(authTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getSessionId() {
|
public String getSessionId() {
|
||||||
return sessionId;
|
return sessionId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,64 +77,28 @@ public class JsonWebToken implements Serializable, Token {
|
||||||
return exp;
|
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) {
|
public JsonWebToken exp(Long exp) {
|
||||||
this.exp = exp;
|
this.exp = exp;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated int will overflow with values after 2038. Use {@link #exp(Long)} instead.
|
|
||||||
*/
|
|
||||||
public JsonWebToken expiration(int expiration) {
|
|
||||||
this.exp = Long.valueOf(expiration);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
return exp != null && exp != 0 ? Time.currentTime() > exp : false;
|
return exp != null && exp != 0 && Time.currentTime() > exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getNbf() {
|
public Long getNbf() {
|
||||||
return nbf;
|
return nbf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated int will overflow with values after 2038. Use {@link #getNbf()} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@JsonIgnore
|
|
||||||
public int getNotBefore() {
|
|
||||||
return nbf != null ? nbf.intValue() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonWebToken nbf(Long nbf) {
|
public JsonWebToken nbf(Long nbf) {
|
||||||
this.nbf = nbf;
|
this.nbf = nbf;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated int will overflow with values after 2038. Use {@link #nbf(Long)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public JsonWebToken notBefore(int notBefore) {
|
public boolean isNotBefore(long allowedTimeSkew) {
|
||||||
this.nbf = Long.valueOf(notBefore);
|
return nbf == null || Time.currentTime() + allowedTimeSkew >= nbf;
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
public boolean isNotBefore(int allowedTimeSkew) {
|
|
||||||
return nbf != null ? Time.currentTime() + allowedTimeSkew >= nbf : true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,21 +129,12 @@ public class JsonWebToken implements Serializable, Token {
|
||||||
return iat;
|
return iat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated int will overflow with values after 2038. Use {@link #getIat()} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@JsonIgnore
|
|
||||||
public int getIssuedAt() {
|
|
||||||
return iat != null ? iat.intValue() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set issuedAt to the current time
|
* Set issuedAt to the current time
|
||||||
*/
|
*/
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public JsonWebToken issuedNow() {
|
public JsonWebToken issuedNow() {
|
||||||
iat = Long.valueOf(Time.currentTime());
|
iat = (long) Time.currentTime();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,17 +143,6 @@ public class JsonWebToken implements Serializable, Token {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated int will overflow with values after 2038. Use {@link #iat(Long)} ()} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@JsonIgnore
|
|
||||||
public JsonWebToken issuedAt(int issuedAt) {
|
|
||||||
this.iat = Long.valueOf(issuedAt);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getIssuer() {
|
public String getIssuer() {
|
||||||
return issuer;
|
return issuer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,14 +42,14 @@ public class DockerResponseToken extends JsonWebToken {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DockerResponseToken expiration(final int expiration) {
|
public DockerResponseToken exp(final Long expiration) {
|
||||||
super.expiration(expiration);
|
super.exp(expiration);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DockerResponseToken notBefore(final int notBefore) {
|
public DockerResponseToken nbf(final Long notBefore) {
|
||||||
super.notBefore(notBefore);
|
super.nbf(notBefore);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +60,8 @@ public class DockerResponseToken extends JsonWebToken {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DockerResponseToken issuedAt(final int issuedAt) {
|
public DockerResponseToken iat(final Long issuedAt) {
|
||||||
super.issuedAt(issuedAt);
|
super.iat(issuedAt);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,9 @@ public class PermissionTicketToken extends JsonWebToken {
|
||||||
if (accessToken != null) {
|
if (accessToken != null) {
|
||||||
id(TokenIdGenerator.generateId());
|
id(TokenIdGenerator.generateId());
|
||||||
subject(accessToken.getSubject());
|
subject(accessToken.getSubject());
|
||||||
expiration(accessToken.getExpiration());
|
this.exp(accessToken.getExp());
|
||||||
notBefore(accessToken.getNotBefore());
|
this.nbf(accessToken.getNbf());
|
||||||
issuedAt(accessToken.getIssuedAt());
|
iat(accessToken.getIat());
|
||||||
issuedFor(accessToken.getIssuedFor());
|
issuedFor(accessToken.getIssuedFor());
|
||||||
}
|
}
|
||||||
if (audience != null) {
|
if (audience != null) {
|
||||||
|
|
|
@ -120,7 +120,7 @@ public abstract class RSAVerifierTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotBeforeGood() throws Exception {
|
public void testNotBeforeGood() throws Exception {
|
||||||
token.notBefore(Time.currentTime() - 100);
|
token.nbf(Time.currentTime() - 100L);
|
||||||
|
|
||||||
String encoded = new JWSBuilder()
|
String encoded = new JWSBuilder()
|
||||||
.jsonContent(token)
|
.jsonContent(token)
|
||||||
|
@ -136,7 +136,7 @@ public abstract class RSAVerifierTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotBeforeBad() {
|
public void testNotBeforeBad() {
|
||||||
token.notBefore(Time.currentTime() + 100);
|
token.nbf(Time.currentTime() + 100L);
|
||||||
|
|
||||||
String encoded = new JWSBuilder()
|
String encoded = new JWSBuilder()
|
||||||
.jsonContent(token)
|
.jsonContent(token)
|
||||||
|
@ -153,7 +153,7 @@ public abstract class RSAVerifierTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExpirationGood() throws Exception {
|
public void testExpirationGood() throws Exception {
|
||||||
token.expiration(Time.currentTime() + 100);
|
token.exp(Time.currentTime() + 100L);
|
||||||
|
|
||||||
String encoded = new JWSBuilder()
|
String encoded = new JWSBuilder()
|
||||||
.jsonContent(token)
|
.jsonContent(token)
|
||||||
|
@ -169,7 +169,7 @@ public abstract class RSAVerifierTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExpirationBad() {
|
public void testExpirationBad() {
|
||||||
token.expiration(Time.currentTime() - 100);
|
token.exp(Time.currentTime() - 100L);
|
||||||
|
|
||||||
String encoded = new JWSBuilder()
|
String encoded = new JWSBuilder()
|
||||||
.jsonContent(token)
|
.jsonContent(token)
|
||||||
|
|
|
@ -82,37 +82,37 @@ public class JsonWebTokenTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isActiveReturnFalseWhenBeforeTimeInFuture() {
|
public void isActiveReturnFalseWhenBeforeTimeInFuture() {
|
||||||
int currentTime = Time.currentTime();
|
long currentTime = Time.currentTime();
|
||||||
int futureTime = currentTime + 10;
|
long futureTime = currentTime + 10;
|
||||||
JsonWebToken jsonWebToken = new JsonWebToken();
|
JsonWebToken jsonWebToken = new JsonWebToken();
|
||||||
jsonWebToken.notBefore(futureTime);
|
jsonWebToken.nbf(futureTime);
|
||||||
assertFalse(jsonWebToken.isActive());
|
assertFalse(jsonWebToken.isActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isActiveReturnTrueWhenBeforeTimeInPast() {
|
public void isActiveReturnTrueWhenBeforeTimeInPast() {
|
||||||
int currentTime = Time.currentTime();
|
long currentTime = Time.currentTime();
|
||||||
int pastTime = currentTime - 10;
|
long pastTime = currentTime - 10;
|
||||||
JsonWebToken jsonWebToken = new JsonWebToken();
|
JsonWebToken jsonWebToken = new JsonWebToken();
|
||||||
jsonWebToken.notBefore(pastTime);
|
jsonWebToken.nbf(pastTime);
|
||||||
assertTrue(jsonWebToken.isActive());
|
assertTrue(jsonWebToken.isActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isActiveShouldReturnTrueWhenBeforeTimeInFutureWithinTimeSkew() {
|
public void isActiveShouldReturnTrueWhenBeforeTimeInFutureWithinTimeSkew() {
|
||||||
int notBeforeTime = Time.currentTime() + 5;
|
long notBeforeTime = Time.currentTime() + 5;
|
||||||
int allowedClockSkew = 10;
|
int allowedClockSkew = 10;
|
||||||
JsonWebToken jsonWebToken = new JsonWebToken();
|
JsonWebToken jsonWebToken = new JsonWebToken();
|
||||||
jsonWebToken.notBefore(notBeforeTime);
|
jsonWebToken.nbf(notBeforeTime);
|
||||||
assertTrue(jsonWebToken.isActive(allowedClockSkew));
|
assertTrue(jsonWebToken.isActive(allowedClockSkew));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isActiveShouldReturnFalseWhenWhenBeforeTimeInFutureOutsideTimeSkew() {
|
public void isActiveShouldReturnFalseWhenWhenBeforeTimeInFutureOutsideTimeSkew() {
|
||||||
int notBeforeTime = Time.currentTime() + 10;
|
long notBeforeTime = Time.currentTime() + 10;
|
||||||
int allowedClockSkew = 5;
|
int allowedClockSkew = 5;
|
||||||
JsonWebToken jsonWebToken = new JsonWebToken();
|
JsonWebToken jsonWebToken = new JsonWebToken();
|
||||||
jsonWebToken.notBefore(notBeforeTime);
|
jsonWebToken.nbf(notBeforeTime);
|
||||||
assertFalse(jsonWebToken.isActive(allowedClockSkew));
|
assertFalse(jsonWebToken.isActive(allowedClockSkew));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,3 +131,20 @@ It is now possible to specify the `cache`, `cache-stack`, and `cache-config-file
|
||||||
This eliminates the need to execute the build phase and rebuild your image due to them.
|
This eliminates the need to execute the build phase and rebuild your image due to them.
|
||||||
|
|
||||||
For more details, see the link:{upgradingguide_link}[{upgradingguide_name}].
|
For more details, see the link:{upgradingguide_link}[{upgradingguide_name}].
|
||||||
|
|
||||||
|
= Removing deprecated methods from `AccessToken`, `IDToken`, and `JsonWebToken` classes
|
||||||
|
|
||||||
|
In this release, we are finally removing deprecated methods from the following classes:
|
||||||
|
|
||||||
|
* `AccessToken`
|
||||||
|
* `IDToken`
|
||||||
|
* `JsonWebToken`
|
||||||
|
|
||||||
|
For more details, see the link:{upgradingguide_link}[{upgradingguide_name}].
|
||||||
|
|
||||||
|
= Method `getExp` added to `SingleUseObjectKeyModel`
|
||||||
|
|
||||||
|
As a consequence of the removal of deprecated methods from `AccessToken`, `IDToken`, and `JsonWebToken`,
|
||||||
|
the `SingleUseObjectKeyModel` also changed to keep consistency with the method names related to expiration values.
|
||||||
|
|
||||||
|
For more details, see the link:{upgradingguide_link}[{upgradingguide_name}].
|
|
@ -269,3 +269,35 @@ The new indexes are both applied to the `RESOURCE_SERVER_PERM_TICKET` table. If
|
||||||
on the console during migration. In this case, the statements must be run manually in the DB after {project_name}'s startup.
|
on the console during migration. In this case, the statements must be run manually in the DB after {project_name}'s startup.
|
||||||
|
|
||||||
See the link:{upgradingguide_link}[{upgradingguide_name}] for details on how to configure a different limit.
|
See the link:{upgradingguide_link}[{upgradingguide_name}] for details on how to configure a different limit.
|
||||||
|
|
||||||
|
= Removing deprecated methods from `AccessToken`, `IDToken`, and `JsonWebToken` classes
|
||||||
|
|
||||||
|
The following methods were removed from the `AccessToken` class:
|
||||||
|
|
||||||
|
* `expiration`. Use the `exp` method instead.
|
||||||
|
* `notBefore`. Use the `nbf` method instead.
|
||||||
|
* `issuedAt`. Use the `iat` method instead.
|
||||||
|
|
||||||
|
The following methods were removed from the `IDToken` class:
|
||||||
|
|
||||||
|
* `getAuthTime` and `setAuthTime`. Use the `getAuth_time` and `setAuth_time` methods, respectively.
|
||||||
|
* `notBefore`. Use the `nbf` method instead.
|
||||||
|
* `issuedAt`. Use the `iat` method instead.
|
||||||
|
* `setSessionState`. Use the `setSessionId` method instead (See the details above in the section about `session_state` claim)
|
||||||
|
|
||||||
|
The following methods were removed from the `JsonWebToken` class:
|
||||||
|
|
||||||
|
* `expiration`. Use the `exp` method instead.
|
||||||
|
* `notBefore`. Use the `nbf` method instead.
|
||||||
|
* `issuedAt`. Use the `iat` method instead.
|
||||||
|
|
||||||
|
You should also expect both `exp` and `nbf` claims not set in tokens as they are optional. Previously, these claims were
|
||||||
|
being set with a value of `0` what does not make mush sense because their value should be a valid `NumericDate`.
|
||||||
|
|
||||||
|
= Method `getExp` added to `SingleUseObjectKeyModel`
|
||||||
|
|
||||||
|
As a consequence of the removal of deprecated methods from `AccessToken`, `IDToken`, and `JsonWebToken`,
|
||||||
|
the `SingleUseObjectKeyModel` also changed to keep consistency with the method names related to expiration values.
|
||||||
|
|
||||||
|
The previous `getExpiration` method is now deprecated and you should prefer using new newly introduced `getExp` method
|
||||||
|
to avoid overflow after 2038.
|
|
@ -200,10 +200,10 @@ public class AuthUtil {
|
||||||
reqToken.subject(clientId);
|
reqToken.subject(clientId);
|
||||||
reqToken.audience(realmInfoUrl);
|
reqToken.audience(realmInfoUrl);
|
||||||
|
|
||||||
int now = Time.currentTime();
|
long now = Time.currentTime();
|
||||||
reqToken.issuedAt(now);
|
reqToken.iat(now);
|
||||||
reqToken.expiration(now + sigLifetime);
|
reqToken.exp(now + sigLifetime);
|
||||||
reqToken.notBefore(now);
|
reqToken.nbf(now);
|
||||||
|
|
||||||
String signedRequestToken = new JWSBuilder()
|
String signedRequestToken = new JWSBuilder()
|
||||||
.jsonContent(reqToken)
|
.jsonContent(reqToken)
|
||||||
|
|
|
@ -39,7 +39,15 @@ public interface SingleUseObjectKeyModel {
|
||||||
/**
|
/**
|
||||||
* Returns absolute number of seconds since the epoch in UTC timezone when the token expires.
|
* Returns absolute number of seconds since the epoch in UTC timezone when the token expires.
|
||||||
*/
|
*/
|
||||||
int getExpiration();
|
Long getExp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated int will overflow with values after 2038. Use {@link #getExp()} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default int getExpiration() {
|
||||||
|
return getExp().intValue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Single-use random value used for verification whether the relevant action is allowed.
|
* @return Single-use random value used for verification whether the relevant action is allowed.
|
||||||
|
@ -49,6 +57,6 @@ public interface SingleUseObjectKeyModel {
|
||||||
default String serializeKey() {
|
default String serializeKey() {
|
||||||
String userId = getUserId();
|
String userId = getUserId();
|
||||||
String encodedUserId = userId == null ? "" : Base64.encodeBytes(userId.getBytes(StandardCharsets.UTF_8));
|
String encodedUserId = userId == null ? "" : Base64.encodeBytes(userId.getBytes(StandardCharsets.UTF_8));
|
||||||
return String.format("%s.%d.%s.%s", encodedUserId, getExpiration(), getActionVerificationNonce(), getActionId());
|
return String.format("%s.%d.%s.%s", encodedUserId, getExp(), getActionVerificationNonce(), getActionId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class DefaultActionToken extends DefaultActionTokenKey implements SingleU
|
||||||
String issuerUri = getIssuer(realm, uri);
|
String issuerUri = getIssuer(realm, uri);
|
||||||
|
|
||||||
this
|
this
|
||||||
.issuedAt(Time.currentTime())
|
.issuedNow()
|
||||||
.id(getActionVerificationNonce().toString())
|
.id(getActionVerificationNonce().toString())
|
||||||
.issuer(issuerUri)
|
.issuer(issuerUri)
|
||||||
.audience(issuerUri);
|
.audience(issuerUri);
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
package org.keycloak.authentication.authenticators.client;
|
package org.keycloak.authentication.authenticators.client;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.MultivaluedMap;
|
import jakarta.ws.rs.core.MultivaluedMap;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
@ -166,7 +168,7 @@ public class JWTClientValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// KEYCLOAK-2986, token-timeout or token-expiration in keycloak.json might not be used
|
// KEYCLOAK-2986, token-timeout or token-expiration in keycloak.json might not be used
|
||||||
if (token.getExpiration() == 0 && token.getIssuedAt() + 10 < currentTime) {
|
if ((token.getExp() == null || token.getExp() <= 0) && token.getIat() + 10 < currentTime) {
|
||||||
throw new RuntimeException("Token is not active");
|
throw new RuntimeException("Token is not active");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +182,7 @@ public class JWTClientValidator {
|
||||||
if (client == null) throw new IllegalStateException("Incorrect usage. Variable 'client' is null. Need to validate client first before validateToken reuse");
|
if (client == null) throw new IllegalStateException("Incorrect usage. Variable 'client' is null. Need to validate client first before validateToken reuse");
|
||||||
|
|
||||||
SingleUseObjectProvider singleUseCache = context.getSession().singleUseObjects();
|
SingleUseObjectProvider singleUseCache = context.getSession().singleUseObjects();
|
||||||
int lifespanInSecs = Math.max(token.getExpiration() - currentTime, 10);
|
long lifespanInSecs = Math.max(Optional.ofNullable(token.getExp()).orElse(0L) - currentTime, 10);
|
||||||
if (singleUseCache.putIfAbsent(token.getId(), lifespanInSecs)) {
|
if (singleUseCache.putIfAbsent(token.getId(), lifespanInSecs)) {
|
||||||
logger.tracef("Added token '%s' to single-use cache. Lifespan: %d seconds, client: %s", token.getId(), lifespanInSecs, client.getClientId());
|
logger.tracef("Added token '%s' to single-use cache. Lifespan: %d seconds, client: %s", token.getId(), lifespanInSecs, client.getClientId());
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,10 @@ public class RPTIntrospectionProvider extends AccessTokenIntrospectionProvider {
|
||||||
metadata.id(accessToken.getId());
|
metadata.id(accessToken.getId());
|
||||||
metadata.setAcr(accessToken.getAcr());
|
metadata.setAcr(accessToken.getAcr());
|
||||||
metadata.type(accessToken.getType());
|
metadata.type(accessToken.getType());
|
||||||
metadata.expiration(accessToken.getExpiration());
|
metadata.exp(accessToken.getExp());
|
||||||
metadata.issuedAt(accessToken.getIssuedAt());
|
metadata.iat(accessToken.getIat());
|
||||||
metadata.audience(accessToken.getAudience());
|
metadata.audience(accessToken.getAudience());
|
||||||
metadata.notBefore(accessToken.getNotBefore());
|
metadata.nbf(accessToken.getNbf());
|
||||||
metadata.setRealmAccess(null);
|
metadata.setRealmAccess(null);
|
||||||
metadata.setResourceAccess(null);
|
metadata.setResourceAccess(null);
|
||||||
|
|
||||||
|
|
|
@ -458,8 +458,8 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||||
audience = getConfig().getTokenUrl();
|
audience = getConfig().getTokenUrl();
|
||||||
}
|
}
|
||||||
jwt.audience(audience);
|
jwt.audience(audience);
|
||||||
int expirationDelay = session.getContext().getRealm().getAccessCodeLifespan();
|
long expirationDelay = session.getContext().getRealm().getAccessCodeLifespan();
|
||||||
jwt.expiration(Time.currentTime() + expirationDelay);
|
jwt.exp(Time.currentTime() + expirationDelay);
|
||||||
jwt.issuedNow();
|
jwt.issuedNow();
|
||||||
return jwt;
|
return jwt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,8 +105,8 @@ public class DockerAuthV2Protocol implements LoginProtocol {
|
||||||
|
|
||||||
// since realm access token is given in seconds
|
// since realm access token is given in seconds
|
||||||
final int accessTokenLifespan = realm.getAccessTokenLifespan();
|
final int accessTokenLifespan = realm.getAccessTokenLifespan();
|
||||||
responseToken.notBefore(responseToken.getIssuedAt())
|
responseToken.nbf(responseToken.getIat())
|
||||||
.expiration(responseToken.getIssuedAt() + accessTokenLifespan);
|
.exp(responseToken.getIat() + accessTokenLifespan);
|
||||||
|
|
||||||
// Next, allow mappers to decorate the token to add/remove scopes as appropriate
|
// Next, allow mappers to decorate the token to add/remove scopes as appropriate
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ public class DockerAuthV2Protocol implements LoginProtocol {
|
||||||
.type("JWT")
|
.type("JWT")
|
||||||
.jsonContent(responseToken)
|
.jsonContent(responseToken)
|
||||||
.rsa256(activeKey.getPrivateKey());
|
.rsa256(activeKey.getPrivateKey());
|
||||||
final String expiresInIso8601String = new SimpleDateFormat(ISO_8601_DATE_FORMAT).format(new Date(responseToken.getIssuedAt() * 1000L));
|
final String expiresInIso8601String = new SimpleDateFormat(ISO_8601_DATE_FORMAT).format(new Date(responseToken.getIat() * 1000L));
|
||||||
|
|
||||||
final DockerResponse responseEntity = new DockerResponse()
|
final DockerResponse responseEntity = new DockerResponse()
|
||||||
.setToken(encodedToken)
|
.setToken(encodedToken)
|
||||||
|
|
|
@ -126,7 +126,6 @@ import static org.keycloak.representations.IDToken.NONCE;
|
||||||
*/
|
*/
|
||||||
public class TokenManager {
|
public class TokenManager {
|
||||||
private static final Logger logger = Logger.getLogger(TokenManager.class);
|
private static final Logger logger = Logger.getLogger(TokenManager.class);
|
||||||
private static final String JWT = "JWT";
|
|
||||||
|
|
||||||
public static class TokenValidation {
|
public static class TokenValidation {
|
||||||
public final UserModel user;
|
public final UserModel user;
|
||||||
|
@ -457,7 +456,7 @@ public class TokenManager {
|
||||||
|
|
||||||
if (clientSession.getCurrentRefreshToken() != null
|
if (clientSession.getCurrentRefreshToken() != null
|
||||||
&& !refreshToken.getId().equals(clientSession.getCurrentRefreshToken())
|
&& !refreshToken.getId().equals(clientSession.getCurrentRefreshToken())
|
||||||
&& refreshToken.getIssuedAt() < clientSession.getTimestamp()
|
&& refreshToken.getIat() < clientSession.getTimestamp()
|
||||||
&& startupTime <= clientSession.getTimestamp()) {
|
&& startupTime <= clientSession.getTimestamp()) {
|
||||||
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Stale token");
|
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Stale token");
|
||||||
}
|
}
|
||||||
|
@ -476,7 +475,6 @@ public class TokenManager {
|
||||||
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Maximum allowed refresh token reuse exceeded",
|
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Maximum allowed refresh token reuse exceeded",
|
||||||
"Maximum allowed refresh token reuse exceeded");
|
"Maximum allowed refresh token reuse exceeded");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RefreshToken verifyRefreshToken(KeycloakSession session, RealmModel realm, ClientModel client, HttpRequest request, String encodedRefreshToken, boolean checkExpiration) throws OAuthErrorException {
|
public RefreshToken verifyRefreshToken(KeycloakSession session, RealmModel realm, ClientModel client, HttpRequest request, String encodedRefreshToken, boolean checkExpiration) throws OAuthErrorException {
|
||||||
|
@ -974,12 +972,12 @@ public class TokenManager {
|
||||||
ClientScopeModel offlineAccessScope = KeycloakModelUtils.getClientScopeByName(realm, OAuth2Constants.OFFLINE_ACCESS);
|
ClientScopeModel offlineAccessScope = KeycloakModelUtils.getClientScopeByName(realm, OAuth2Constants.OFFLINE_ACCESS);
|
||||||
boolean offlineTokenRequested = offlineAccessScope == null ? false
|
boolean offlineTokenRequested = offlineAccessScope == null ? false
|
||||||
: clientSessionCtx.getClientScopeIds().contains(offlineAccessScope.getId());
|
: clientSessionCtx.getClientScopeIds().contains(offlineAccessScope.getId());
|
||||||
token.expiration(getTokenExpiration(realm, client, session, clientSession, offlineTokenRequested));
|
token.exp(getTokenExpiration(realm, client, session, clientSession, offlineTokenRequested));
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getTokenExpiration(RealmModel realm, ClientModel client, UserSessionModel userSession,
|
private Long getTokenExpiration(RealmModel realm, ClientModel client, UserSessionModel userSession,
|
||||||
AuthenticatedClientSessionModel clientSession, boolean offlineTokenRequested) {
|
AuthenticatedClientSessionModel clientSession, boolean offlineTokenRequested) {
|
||||||
boolean implicitFlow = false;
|
boolean implicitFlow = false;
|
||||||
String responseType = clientSession.getNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
|
String responseType = clientSession.getNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
|
||||||
|
@ -1016,7 +1014,7 @@ public class TokenManager {
|
||||||
realm, client);
|
realm, client);
|
||||||
expiration = sessionExpires > 0? Math.min(expiration, sessionExpires) : expiration;
|
expiration = sessionExpires > 0? Math.min(expiration, sessionExpires) : expiration;
|
||||||
|
|
||||||
return (int) TimeUnit.MILLISECONDS.toSeconds(expiration);
|
return TimeUnit.MILLISECONDS.toSeconds(expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1131,15 +1129,15 @@ public class TokenManager {
|
||||||
}
|
}
|
||||||
refreshToken.type(TokenUtil.TOKEN_TYPE_OFFLINE);
|
refreshToken.type(TokenUtil.TOKEN_TYPE_OFFLINE);
|
||||||
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
||||||
refreshToken.expiration(getExpiration(true));
|
refreshToken.exp(getExpiration(true));
|
||||||
}
|
}
|
||||||
sessionManager.createOrUpdateOfflineSession(clientSessionCtx.getClientSession(), userSession);
|
sessionManager.createOrUpdateOfflineSession(clientSessionCtx.getClientSession(), userSession);
|
||||||
} else {
|
} else {
|
||||||
refreshToken.expiration(getExpiration(false));
|
refreshToken.exp(getExpiration(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getExpiration(boolean offline) {
|
private Long getExpiration(boolean offline) {
|
||||||
long expiration = SessionExpirationUtils.calculateClientSessionIdleTimestamp(
|
long expiration = SessionExpirationUtils.calculateClientSessionIdleTimestamp(
|
||||||
offline, userSession.isRememberMe(),
|
offline, userSession.isRememberMe(),
|
||||||
TimeUnit.SECONDS.toMillis(clientSessionCtx.getClientSession().getTimestamp()),
|
TimeUnit.SECONDS.toMillis(clientSessionCtx.getClientSession().getTimestamp()),
|
||||||
|
@ -1151,7 +1149,7 @@ public class TokenManager {
|
||||||
realm, client);
|
realm, client);
|
||||||
expiration = lifespan > 0? Math.min(expiration, lifespan) : expiration;
|
expiration = lifespan > 0? Math.min(expiration, lifespan) : expiration;
|
||||||
|
|
||||||
return (int) TimeUnit.MILLISECONDS.toSeconds(expiration);
|
return TimeUnit.MILLISECONDS.toSeconds(expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccessTokenResponseBuilder generateIDToken() {
|
public AccessTokenResponseBuilder generateIDToken() {
|
||||||
|
@ -1172,7 +1170,7 @@ public class TokenManager {
|
||||||
idToken.issuer(accessToken.getIssuer());
|
idToken.issuer(accessToken.getIssuer());
|
||||||
idToken.setNonce(clientSessionCtx.getAttribute(OIDCLoginProtocol.NONCE_PARAM, String.class));
|
idToken.setNonce(clientSessionCtx.getAttribute(OIDCLoginProtocol.NONCE_PARAM, String.class));
|
||||||
idToken.setSessionId(accessToken.getSessionId());
|
idToken.setSessionId(accessToken.getSessionId());
|
||||||
idToken.expiration(accessToken.getExpiration());
|
idToken.exp(accessToken.getExp());
|
||||||
|
|
||||||
// Protocol mapper is supposed to set this in case "step_up_authentication" feature enabled
|
// Protocol mapper is supposed to set this in case "step_up_authentication" feature enabled
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.STEP_UP_AUTHENTICATION)) {
|
if (!Profile.isFeatureEnabled(Profile.Feature.STEP_UP_AUTHENTICATION)) {
|
||||||
|
@ -1229,8 +1227,8 @@ public class TokenManager {
|
||||||
res.setToken(encodedToken);
|
res.setToken(encodedToken);
|
||||||
res.setTokenType(responseTokenType);
|
res.setTokenType(responseTokenType);
|
||||||
res.setSessionState(accessToken.getSessionState());
|
res.setSessionState(accessToken.getSessionState());
|
||||||
if (accessToken.getExpiration() != 0) {
|
if (accessToken.getExp() != 0) {
|
||||||
res.setExpiresIn(accessToken.getExpiration() - Time.currentTime());
|
res.setExpiresIn(accessToken.getExp() - Time.currentTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1253,8 +1251,9 @@ public class TokenManager {
|
||||||
if (refreshToken != null) {
|
if (refreshToken != null) {
|
||||||
String encodedToken = session.tokens().encode(refreshToken);
|
String encodedToken = session.tokens().encode(refreshToken);
|
||||||
res.setRefreshToken(encodedToken);
|
res.setRefreshToken(encodedToken);
|
||||||
if (refreshToken.getExpiration() != 0) {
|
Long exp = refreshToken.getExp();
|
||||||
res.setRefreshExpiresIn(refreshToken.getExpiration() - Time.currentTime());
|
if (exp != null && exp > 0) {
|
||||||
|
res.setRefreshExpiresIn(exp - Time.currentTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,7 +1308,7 @@ public class TokenManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(JsonWebToken t) throws VerificationException {
|
public boolean test(JsonWebToken t) throws VerificationException {
|
||||||
if (t.getIssuedAt() < notBefore) {
|
if (t.getIat() < notBefore) {
|
||||||
throw new VerificationException("Stale token");
|
throw new VerificationException("Stale token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,7 +1366,7 @@ public class TokenManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
LogoutToken logoutToken = logoutTokenOptional.get();
|
LogoutToken logoutToken = logoutTokenOptional.get();
|
||||||
List<OIDCIdentityProvider> identityProviders = getOIDCIdentityProviders(realm, session).collect(Collectors.toList());
|
List<OIDCIdentityProvider> identityProviders = getOIDCIdentityProviders(realm, session).toList();
|
||||||
if (identityProviders.isEmpty()) {
|
if (identityProviders.isEmpty()) {
|
||||||
return LogoutTokenValidationCode.COULD_NOT_FIND_IDP;
|
return LogoutTokenValidationCode.COULD_NOT_FIND_IDP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,7 +524,7 @@ public class LogoutEndpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userSessionModel != null) {
|
if (userSessionModel != null) {
|
||||||
checkTokenIssuedAt(token.getIssuedAt(), userSessionModel);
|
checkTokenIssuedAt(token.getIat(), userSessionModel);
|
||||||
logout(userSessionModel, offline);
|
logout(userSessionModel, offline);
|
||||||
}
|
}
|
||||||
} catch (OAuthErrorException e) {
|
} catch (OAuthErrorException e) {
|
||||||
|
@ -727,7 +727,7 @@ public class LogoutEndpoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkTokenIssuedAt(int idTokenIssuedAt, UserSessionModel userSession) throws OAuthErrorException {
|
private void checkTokenIssuedAt(long idTokenIssuedAt, UserSessionModel userSession) throws OAuthErrorException {
|
||||||
if (idTokenIssuedAt + 1 < userSession.getStarted()) {
|
if (idTokenIssuedAt + 1 < userSession.getStarted()) {
|
||||||
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Toked issued before the user session started");
|
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Toked issued before the user session started");
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,7 @@ public class ClientRegistrationTokenUtils {
|
||||||
|
|
||||||
regToken.type(auth.getJwt().getType());
|
regToken.type(auth.getJwt().getType());
|
||||||
regToken.id(auth.getJwt().getId());
|
regToken.id(auth.getJwt().getId());
|
||||||
regToken.issuedAt(Time.currentTime());
|
regToken.issuedNow();
|
||||||
regToken.expiration(0);
|
|
||||||
regToken.issuer(auth.getJwt().getIssuer());
|
regToken.issuer(auth.getJwt().getIssuer());
|
||||||
regToken.audience(auth.getJwt().getIssuer());
|
regToken.audience(auth.getJwt().getIssuer());
|
||||||
|
|
||||||
|
@ -117,13 +116,13 @@ public class ClientRegistrationTokenUtils {
|
||||||
return TokenVerification.success(kid, jwt);
|
return TokenVerification.success(kid, jwt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String setupToken(JsonWebToken jwt, KeycloakSession session, RealmModel realm, String id, String type, int expiration) {
|
private static String setupToken(JsonWebToken jwt, KeycloakSession session, RealmModel realm, String id, String type, long expiration) {
|
||||||
String issuer = getIssuer(session, realm);
|
String issuer = getIssuer(session, realm);
|
||||||
|
|
||||||
jwt.type(type);
|
jwt.type(type);
|
||||||
jwt.id(id);
|
jwt.id(id);
|
||||||
jwt.issuedAt(Time.currentTime());
|
jwt.issuedNow();
|
||||||
jwt.expiration(expiration);
|
jwt.exp(expiration);
|
||||||
jwt.issuer(issuer);
|
jwt.issuer(issuer);
|
||||||
jwt.audience(issuer);
|
jwt.audience(issuer);
|
||||||
|
|
||||||
|
|
|
@ -759,9 +759,9 @@ public class AuthenticationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session != null && session.isRememberMe() && realm.getSsoSessionMaxLifespanRememberMe() > 0) {
|
if (session != null && session.isRememberMe() && realm.getSsoSessionMaxLifespanRememberMe() > 0) {
|
||||||
token.expiration(Time.currentTime() + realm.getSsoSessionMaxLifespanRememberMe());
|
token.exp((long) Time.currentTime() + realm.getSsoSessionMaxLifespanRememberMe());
|
||||||
} else if (realm.getSsoSessionMaxLifespan() > 0) {
|
} else if (realm.getSsoSessionMaxLifespan() > 0) {
|
||||||
token.expiration(Time.currentTime() + realm.getSsoSessionMaxLifespan());
|
token.exp((long) Time.currentTime() + realm.getSsoSessionMaxLifespan());
|
||||||
}
|
}
|
||||||
|
|
||||||
String stateChecker = (String) keycloakSession.getAttribute("state_checker");
|
String stateChecker = (String) keycloakSession.getAttribute("state_checker");
|
||||||
|
@ -999,7 +999,7 @@ public class AuthenticationManager {
|
||||||
SingleUseObjectKeyModel actionTokenKey = DefaultActionTokenKey.from(actionTokenKeyToInvalidate);
|
SingleUseObjectKeyModel actionTokenKey = DefaultActionTokenKey.from(actionTokenKeyToInvalidate);
|
||||||
if (actionTokenKey != null) {
|
if (actionTokenKey != null) {
|
||||||
SingleUseObjectProvider singleUseObjectProvider = session.singleUseObjects();
|
SingleUseObjectProvider singleUseObjectProvider = session.singleUseObjects();
|
||||||
singleUseObjectProvider.put(actionTokenKeyToInvalidate, actionTokenKey.getExpiration() - Time.currentTime(), null); // Token is invalidated
|
singleUseObjectProvider.put(actionTokenKeyToInvalidate, actionTokenKey.getExp() - Time.currentTime(), null); // Token is invalidated
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1400,8 +1400,8 @@ public class AuthenticationManager {
|
||||||
|
|
||||||
AccessToken token = verifier.verify().getToken();
|
AccessToken token = verifier.verify().getToken();
|
||||||
if (checkActive) {
|
if (checkActive) {
|
||||||
if (!token.isActive() || token.getIssuedAt() < realm.getNotBefore()) {
|
if (!token.isActive() || token.getIat() < realm.getNotBefore()) {
|
||||||
logger.debugf("Identity cookie expired. Token expiration: %d, Current Time: %d. token issued at: %d, realm not before: %d", token.getExp(), Time.currentTime(), token.getIssuedAt(), realm.getNotBefore());
|
logger.debugf("Identity cookie expired. Token expiration: %d, Current Time: %d. token issued at: %d, realm not before: %d", token.getExp(), Time.currentTime(), token.getIat(), realm.getNotBefore());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1467,7 +1467,7 @@ public class AuthenticationManager {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.getIssuedAt() < client.getNotBefore()) {
|
if (token.getIat() < client.getNotBefore()) {
|
||||||
logger.debug("Client notBefore newer than token");
|
logger.debug("Client notBefore newer than token");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -755,13 +755,13 @@ public class DemoServletsAdapterTest extends AbstractServletsAdapterTest {
|
||||||
|
|
||||||
// Get time of token
|
// Get time of token
|
||||||
AccessToken token = tokenMinTTLPage.getAccessToken();
|
AccessToken token = tokenMinTTLPage.getAccessToken();
|
||||||
int tokenIssued1 = token.getIssuedAt();
|
long tokenIssued1 = token.getIat();
|
||||||
|
|
||||||
// Sets 5 minutes offset and assert access token will be still the same
|
// Sets 5 minutes offset and assert access token will be still the same
|
||||||
setAdapterAndServerTimeOffset(300, tokenMinTTLPage.toString());
|
setAdapterAndServerTimeOffset(300, tokenMinTTLPage.toString());
|
||||||
tokenMinTTLPage.navigateTo();
|
tokenMinTTLPage.navigateTo();
|
||||||
token = tokenMinTTLPage.getAccessToken();
|
token = tokenMinTTLPage.getAccessToken();
|
||||||
int tokenIssued2 = token.getIssuedAt();
|
long tokenIssued2 = token.getIat();
|
||||||
Assert.assertEquals(tokenIssued1, tokenIssued2);
|
Assert.assertEquals(tokenIssued1, tokenIssued2);
|
||||||
assertFalse(token.isExpired());
|
assertFalse(token.isExpired());
|
||||||
|
|
||||||
|
@ -769,7 +769,7 @@ public class DemoServletsAdapterTest extends AbstractServletsAdapterTest {
|
||||||
setAdapterAndServerTimeOffset(540, tokenMinTTLPage.toString());
|
setAdapterAndServerTimeOffset(540, tokenMinTTLPage.toString());
|
||||||
tokenMinTTLPage.navigateTo();
|
tokenMinTTLPage.navigateTo();
|
||||||
token = tokenMinTTLPage.getAccessToken();
|
token = tokenMinTTLPage.getAccessToken();
|
||||||
int tokenIssued3 = token.getIssuedAt();
|
long tokenIssued3 = token.getIat();
|
||||||
Assert.assertTrue(tokenIssued3 > tokenIssued1);
|
Assert.assertTrue(tokenIssued3 > tokenIssued1);
|
||||||
|
|
||||||
// Revert times
|
// Revert times
|
||||||
|
@ -853,8 +853,8 @@ public class DemoServletsAdapterTest extends AbstractServletsAdapterTest {
|
||||||
testRealmLoginPage.form().setPassword("password");
|
testRealmLoginPage.form().setPassword("password");
|
||||||
testRealmLoginPage.form().login();
|
testRealmLoginPage.form().login();
|
||||||
AccessToken token = tokenMinTTLPage.getAccessToken();
|
AccessToken token = tokenMinTTLPage.getAccessToken();
|
||||||
int authTime = token.getAuthTime();
|
long authTime = token.getAuth_time();
|
||||||
assertThat(authTime, is(greaterThanOrEqualTo(currentTime + 10)));
|
assertThat(authTime, is(greaterThanOrEqualTo(currentTime + 10L)));
|
||||||
} finally {
|
} finally {
|
||||||
setAdapterAndServerTimeOffset(0, securePortal.toString());
|
setAdapterAndServerTimeOffset(0, securePortal.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2381,7 +2381,7 @@ public class UserTest extends AbstractAdminTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final AccessToken accessToken = TokenVerifier.create(token, AccessToken.class).getToken();
|
final AccessToken accessToken = TokenVerifier.create(token, AccessToken.class).getToken();
|
||||||
assertEquals(lifespan, accessToken.getExpiration() - accessToken.getIssuedAt());
|
assertEquals(lifespan, accessToken.getExp() - accessToken.getIat());
|
||||||
} catch (VerificationException e) {
|
} catch (VerificationException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_CONS_NAME;
|
||||||
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PROV_NAME;
|
import static org.keycloak.testsuite.broker.BrokerTestConstants.REALM_PROV_NAME;
|
||||||
|
@ -614,7 +615,7 @@ public final class KcOidcBrokerTransientSessionsTest extends AbstractAdvancedBro
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
assertEquals(0, offlineToken.getExpiration());
|
assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
assertTrue(tokenResponse.getScope().contains(OAuth2Constants.OFFLINE_ACCESS));
|
assertTrue(tokenResponse.getScope().contains(OAuth2Constants.OFFLINE_ACCESS));
|
||||||
|
|
||||||
|
|
|
@ -397,11 +397,11 @@ public class OIDCPairwiseClientRegistrationTest extends AbstractClientRegistrati
|
||||||
Assert.assertEquals(idToken.getSubject(), refreshedRefreshToken.getSubject());
|
Assert.assertEquals(idToken.getSubject(), refreshedRefreshToken.getSubject());
|
||||||
|
|
||||||
// its iat Claim MUST represent the time that the new ID Token is issued
|
// its iat Claim MUST represent the time that the new ID Token is issued
|
||||||
Assert.assertEquals(refreshedIdToken.getIssuedAt(), refreshedRefreshToken.getIssuedAt());
|
Assert.assertEquals(refreshedIdToken.getIat(), refreshedRefreshToken.getIat());
|
||||||
|
|
||||||
// if the ID Token contains an auth_time Claim, its value MUST represent the time of the original authentication
|
// if the ID Token contains an auth_time Claim, its value MUST represent the time of the original authentication
|
||||||
// - not the time that the new ID token is issued
|
// - not the time that the new ID token is issued
|
||||||
Assert.assertEquals(idToken.getAuthTime(), refreshedIdToken.getAuthTime());
|
Assert.assertEquals(idToken.getAuth_time(), refreshedIdToken.getAuth_time());
|
||||||
|
|
||||||
// its azp Claim Value MUST be the same as in the ID Token issued when the original authentication occurred; if
|
// its azp Claim Value MUST be the same as in the ID Token issued when the original authentication occurred; if
|
||||||
// no azp Claim was present in the original ID Token, one MUST NOT be present in the new ID Token
|
// no azp Claim was present in the original ID Token, one MUST NOT be present in the new ID Token
|
||||||
|
|
|
@ -478,7 +478,7 @@ public class ClientStorageTest extends AbstractTestRealmKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
Assert.assertEquals(0, offlineToken.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
|
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
|
||||||
|
|
||||||
|
|
|
@ -856,7 +856,7 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
||||||
private void assertOfflineToken(String offlineToken) {
|
private void assertOfflineToken(String offlineToken) {
|
||||||
RefreshToken offlineTokenParsed = oauth.parseRefreshToken(offlineToken);
|
RefreshToken offlineTokenParsed = oauth.parseRefreshToken(offlineToken);
|
||||||
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineTokenParsed.getType());
|
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineTokenParsed.getType());
|
||||||
assertEquals(0, offlineTokenParsed.getExpiration());
|
assertNull(offlineTokenParsed.getExp());
|
||||||
assertTrue(TokenUtil.hasScope(offlineTokenParsed.getScope(), OAuth2Constants.OFFLINE_ACCESS));
|
assertTrue(TokenUtil.hasScope(offlineTokenParsed.getScope(), OAuth2Constants.OFFLINE_ACCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,6 @@ import org.keycloak.common.util.KeystoreUtil.KeystoreFormat;
|
||||||
import org.keycloak.constants.ServiceUrlConstants;
|
import org.keycloak.constants.ServiceUrlConstants;
|
||||||
import org.keycloak.crypto.Algorithm;
|
import org.keycloak.crypto.Algorithm;
|
||||||
import org.keycloak.crypto.ECDSAAlgorithm;
|
import org.keycloak.crypto.ECDSAAlgorithm;
|
||||||
import org.keycloak.crypto.ECDSASignatureProvider;
|
|
||||||
import org.keycloak.crypto.KeyType;
|
import org.keycloak.crypto.KeyType;
|
||||||
import org.keycloak.crypto.SignatureSignerContext;
|
import org.keycloak.crypto.SignatureSignerContext;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
|
@ -806,10 +805,10 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
|
||||||
if (isClaimEnabled("subject")) reqToken.subject(clientId);
|
if (isClaimEnabled("subject")) reqToken.subject(clientId);
|
||||||
if (isClaimEnabled("audience")) reqToken.audience(realmInfoUrl);
|
if (isClaimEnabled("audience")) reqToken.audience(realmInfoUrl);
|
||||||
|
|
||||||
int now = Time.currentTime();
|
long now = Time.currentTime();
|
||||||
if (isClaimEnabled("issuedAt")) reqToken.issuedAt(now);
|
if (isClaimEnabled("issuedAt")) reqToken.iat(now);
|
||||||
if (isClaimEnabled("expiration")) reqToken.expiration(now + getTokenTimeout());
|
if (isClaimEnabled("expiration")) reqToken.exp(now + getTokenTimeout());
|
||||||
if (isClaimEnabled("notBefore")) reqToken.notBefore(now);
|
if (isClaimEnabled("notBefore")) reqToken.nbf(now);
|
||||||
|
|
||||||
return reqToken;
|
return reqToken;
|
||||||
}
|
}
|
||||||
|
@ -934,10 +933,10 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
|
||||||
reqToken.subject(clientId);
|
reqToken.subject(clientId);
|
||||||
reqToken.audience(realmInfoUrl);
|
reqToken.audience(realmInfoUrl);
|
||||||
|
|
||||||
int now = Time.currentTime();
|
long now = Time.currentTime();
|
||||||
reqToken.issuedAt(now);
|
reqToken.iat(now);
|
||||||
reqToken.expiration(now + 10);
|
reqToken.exp(now + 10);
|
||||||
reqToken.notBefore(now);
|
reqToken.nbf(now);
|
||||||
|
|
||||||
return reqToken;
|
return reqToken;
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,13 +235,10 @@ public class AccessTokenTest extends AbstractKeycloakTest {
|
||||||
assertEquals(sessionId, sid);
|
assertEquals(sessionId, sid);
|
||||||
|
|
||||||
assertNull(token.getNbf());
|
assertNull(token.getNbf());
|
||||||
assertEquals(0, token.getNotBefore());
|
|
||||||
|
|
||||||
assertNotNull(token.getIat());
|
assertNotNull(token.getIat());
|
||||||
assertEquals(token.getIat().intValue(), token.getIssuedAt());
|
|
||||||
|
|
||||||
assertNotNull(token.getExp());
|
assertNotNull(token.getExp());
|
||||||
assertEquals(token.getExp().intValue(), token.getExpiration());
|
|
||||||
|
|
||||||
assertEquals(1, token.getRealmAccess().getRoles().size());
|
assertEquals(1, token.getRealmAccess().getRoles().size());
|
||||||
assertTrue(token.getRealmAccess().isUserInRole("user"));
|
assertTrue(token.getRealmAccess().isUserInRole("user"));
|
||||||
|
|
|
@ -493,9 +493,9 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest {
|
||||||
RefreshToken refreshToken = oauth.parseRefreshToken(refreshTokenString);
|
RefreshToken refreshToken = oauth.parseRefreshToken(refreshTokenString);
|
||||||
|
|
||||||
Assert.assertNotNull(refreshTokenString);
|
Assert.assertNotNull(refreshTokenString);
|
||||||
assertThat(token.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(200), lessThanOrEqualTo(350)));
|
assertThat(token.getExp() - getCurrentTime(), allOf(greaterThanOrEqualTo(200L), lessThanOrEqualTo(350L)));
|
||||||
int actual = refreshToken.getExpiration() - getCurrentTime();
|
long actual = refreshToken.getExp() - getCurrentTime();
|
||||||
assertThat(actual, allOf(greaterThanOrEqualTo(1799 - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800 + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
assertThat(actual, allOf(greaterThanOrEqualTo(1799L - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800L + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
||||||
assertEquals(sessionId, refreshToken.getSessionState());
|
assertEquals(sessionId, refreshToken.getSessionState());
|
||||||
|
|
||||||
setTimeOffset(2);
|
setTimeOffset(2);
|
||||||
|
@ -510,10 +510,10 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest {
|
||||||
assertEquals(sessionId, refreshedRefreshToken.getSessionState());
|
assertEquals(sessionId, refreshedRefreshToken.getSessionState());
|
||||||
|
|
||||||
assertThat(refreshResponse.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
|
assertThat(refreshResponse.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
|
||||||
assertThat(refreshedToken.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(250 - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(300 + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
assertThat(refreshedToken.getExp() - getCurrentTime(), allOf(greaterThanOrEqualTo(250L - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(300L + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
||||||
|
|
||||||
assertThat(refreshedToken.getExpiration() - token.getExpiration(), allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(10)));
|
assertThat(refreshedToken.getExp() - token.getExp(), allOf(greaterThanOrEqualTo(1L), lessThanOrEqualTo(10L)));
|
||||||
assertThat(refreshedRefreshToken.getExpiration() - refreshToken.getExpiration(), allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(10)));
|
assertThat(refreshedRefreshToken.getExp() - refreshToken.getExp(), allOf(greaterThanOrEqualTo(1L), lessThanOrEqualTo(10L)));
|
||||||
|
|
||||||
Assert.assertNotEquals(token.getId(), refreshedToken.getId());
|
Assert.assertNotEquals(token.getId(), refreshedToken.getId());
|
||||||
Assert.assertNotEquals(refreshToken.getId(), refreshedRefreshToken.getId());
|
Assert.assertNotEquals(refreshToken.getId(), refreshedRefreshToken.getId());
|
||||||
|
|
|
@ -256,7 +256,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
assertEquals(0, offlineToken.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
assertTrue(tokenResponse.getScope().contains(OAuth2Constants.OFFLINE_ACCESS));
|
assertTrue(tokenResponse.getScope().contains(OAuth2Constants.OFFLINE_ACCESS));
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
Assert.assertEquals(0, offlineToken.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
|
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
Assert.assertEquals(0, offlineToken.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
String offlineTokenString2 = testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
|
String offlineTokenString2 = testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
|
||||||
RefreshToken offlineToken2 = oauth.parseRefreshToken(offlineTokenString2);
|
RefreshToken offlineToken2 = oauth.parseRefreshToken(offlineTokenString2);
|
||||||
|
@ -440,7 +440,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
Assert.assertEquals(0, offlineToken.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
|
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
|
||||||
|
|
||||||
|
@ -677,7 +677,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
assertEquals(0, offlineToken.getExpiration());
|
assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
String offlineUserSessionId = testingClient.server().fetch((KeycloakSession session) ->
|
String offlineUserSessionId = testingClient.server().fetch((KeycloakSession session) ->
|
||||||
session.sessions().getOfflineUserSession(session.realms().getRealmByName("test"), offlineToken.getSessionState()).getId(), String.class);
|
session.sessions().getOfflineUserSession(session.realms().getRealmByName("test"), offlineToken.getSessionState()).getId(), String.class);
|
||||||
|
@ -714,7 +714,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken2.getType());
|
assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken2.getType());
|
||||||
assertEquals(0, offlineToken2.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
// Assert session changed
|
// Assert session changed
|
||||||
assertNotEquals(offlineToken.getSessionState(), offlineToken2.getSessionState());
|
assertNotEquals(offlineToken.getSessionState(), offlineToken2.getSessionState());
|
||||||
|
@ -977,7 +977,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
Assert.assertEquals(0, offlineToken.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
|
|
||||||
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
|
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
|
||||||
|
|
||||||
|
@ -1049,7 +1049,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||||
.assertEvent();
|
.assertEvent();
|
||||||
|
|
||||||
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
|
||||||
Assert.assertEquals(0, offlineToken.getExpiration());
|
Assert.assertNull(offlineToken.getExp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -247,9 +247,9 @@ public class RefreshTokenTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
assertEquals("Bearer", tokenResponse.getTokenType());
|
assertEquals("Bearer", tokenResponse.getTokenType());
|
||||||
|
|
||||||
assertThat(token.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(200), lessThanOrEqualTo(350)));
|
assertThat(token.getExp() - getCurrentTime(), allOf(greaterThanOrEqualTo(200L), lessThanOrEqualTo(350L)));
|
||||||
int actual = refreshToken.getExpiration() - getCurrentTime();
|
long actual = refreshToken.getExp() - getCurrentTime();
|
||||||
assertThat(actual, allOf(greaterThanOrEqualTo(1799 - ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800 + ALLOWED_CLOCK_SKEW)));
|
assertThat(actual, allOf(greaterThanOrEqualTo(1799L - ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800L + ALLOWED_CLOCK_SKEW)));
|
||||||
|
|
||||||
assertEquals(sessionId, refreshToken.getSessionState());
|
assertEquals(sessionId, refreshToken.getSessionState());
|
||||||
assertNull(refreshToken.getNonce());
|
assertNull(refreshToken.getNonce());
|
||||||
|
@ -264,10 +264,10 @@ public class RefreshTokenTest extends AbstractKeycloakTest {
|
||||||
assertEquals(sessionId, refreshedRefreshToken.getSessionState());
|
assertEquals(sessionId, refreshedRefreshToken.getSessionState());
|
||||||
|
|
||||||
assertThat(response.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
|
assertThat(response.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
|
||||||
assertThat(refreshedToken.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(250 - ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(300 + ALLOWED_CLOCK_SKEW)));
|
assertThat(refreshedToken.getExp() - getCurrentTime(), allOf(greaterThanOrEqualTo(250L - ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(300L + ALLOWED_CLOCK_SKEW)));
|
||||||
|
|
||||||
assertThat(refreshedToken.getExpiration() - token.getExpiration(), allOf(greaterThanOrEqualTo(0), lessThanOrEqualTo(10)));
|
assertThat(refreshedToken.getExp() - token.getExp(), allOf(greaterThanOrEqualTo(0L), lessThanOrEqualTo(10L)));
|
||||||
assertThat(refreshedRefreshToken.getExpiration() - refreshToken.getExpiration(), allOf(greaterThanOrEqualTo(0), lessThanOrEqualTo(10)));
|
assertThat(refreshedRefreshToken.getExp() - refreshToken.getExp(), allOf(greaterThanOrEqualTo(0L), lessThanOrEqualTo(10L)));
|
||||||
|
|
||||||
// "test-app" should not be an audience in the refresh token
|
// "test-app" should not be an audience in the refresh token
|
||||||
assertEquals("test-app", refreshedRefreshToken.getIssuedFor());
|
assertEquals("test-app", refreshedRefreshToken.getIssuedFor());
|
||||||
|
|
|
@ -69,6 +69,7 @@ import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
@ -170,9 +171,9 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
|
||||||
assertTrue(rep.isActive());
|
assertTrue(rep.isActive());
|
||||||
assertEquals("test-user@localhost", rep.getUserName());
|
assertEquals("test-user@localhost", rep.getUserName());
|
||||||
assertEquals("test-app", rep.getClientId());
|
assertEquals("test-app", rep.getClientId());
|
||||||
assertEquals(jsonNode.get("exp").asInt(), rep.getExpiration());
|
assertEquals(Long.valueOf(jsonNode.get("exp").asLong()), rep.getExp());
|
||||||
assertEquals(jsonNode.get("iat").asInt(), rep.getIssuedAt());
|
assertEquals(Long.valueOf(jsonNode.get("iat").asLong()), rep.getIat());
|
||||||
assertEquals(jsonNode.get("nbf"), rep.getNbf());
|
assertEquals(Optional.ofNullable(jsonNode.get("nbf")).map(JsonNode::asLong).orElse(null), rep.getNbf());
|
||||||
assertEquals(jsonNode.get("sub").asText(), rep.getSubject());
|
assertEquals(jsonNode.get("sub").asText(), rep.getSubject());
|
||||||
|
|
||||||
List<String> audiences = new ArrayList<>();
|
List<String> audiences = new ArrayList<>();
|
||||||
|
@ -226,9 +227,9 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
|
||||||
assertTrue(rep.isActive());
|
assertTrue(rep.isActive());
|
||||||
assertEquals("test-app", rep.getClientId());
|
assertEquals("test-app", rep.getClientId());
|
||||||
assertEquals(jsonNode.get("sid").asText(), rep.getSessionState());
|
assertEquals(jsonNode.get("sid").asText(), rep.getSessionState());
|
||||||
assertEquals(jsonNode.get("exp").asInt(), rep.getExpiration());
|
assertEquals(Long.valueOf(jsonNode.get("exp").asLong()), rep.getExp());
|
||||||
assertEquals(jsonNode.get("iat").asInt(), rep.getIssuedAt());
|
assertEquals(Long.valueOf(jsonNode.get("iat").asLong()), rep.getIat());
|
||||||
assertEquals(jsonNode.get("nbf"), rep.getNbf());
|
assertEquals(Optional.ofNullable(jsonNode.get("nbf")).map(JsonNode::asLong).orElse(null), rep.getNbf());
|
||||||
assertEquals(jsonNode.get("iss").asText(), rep.getIssuer());
|
assertEquals(jsonNode.get("iss").asText(), rep.getIssuer());
|
||||||
assertEquals(jsonNode.get("jti").asText(), rep.getId());
|
assertEquals(jsonNode.get("jti").asText(), rep.getId());
|
||||||
assertEquals(jsonNode.get("typ").asText(), "Refresh");
|
assertEquals(jsonNode.get("typ").asText(), "Refresh");
|
||||||
|
|
|
@ -335,9 +335,9 @@ public class HoKTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
Assert.assertNotNull(refreshTokenString);
|
Assert.assertNotNull(refreshTokenString);
|
||||||
assertEquals("Bearer", tokenResponse.getTokenType());
|
assertEquals("Bearer", tokenResponse.getTokenType());
|
||||||
assertThat(token.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(200), lessThanOrEqualTo(350)));
|
assertThat(token.getExp() - getCurrentTime(), allOf(greaterThanOrEqualTo(200L), lessThanOrEqualTo(350L)));
|
||||||
int actual = refreshToken.getExpiration() - getCurrentTime();
|
long actual = refreshToken.getExp() - getCurrentTime();
|
||||||
assertThat(actual, allOf(greaterThanOrEqualTo(1799 - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800 + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
assertThat(actual, allOf(greaterThanOrEqualTo(1799L - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800L + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
||||||
assertEquals(sessionId, refreshToken.getSessionState());
|
assertEquals(sessionId, refreshToken.getSessionState());
|
||||||
|
|
||||||
setTimeOffset(2);
|
setTimeOffset(2);
|
||||||
|
@ -372,9 +372,9 @@ public class HoKTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
Assert.assertNotNull(refreshTokenString);
|
Assert.assertNotNull(refreshTokenString);
|
||||||
assertEquals("Bearer", tokenResponse.getTokenType());
|
assertEquals("Bearer", tokenResponse.getTokenType());
|
||||||
assertThat(token.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(200), lessThanOrEqualTo(350)));
|
assertThat(token.getExp() - getCurrentTime(), allOf(greaterThanOrEqualTo(200L), lessThanOrEqualTo(350L)));
|
||||||
int actual = refreshToken.getExpiration() - getCurrentTime();
|
long actual = refreshToken.getExp() - getCurrentTime();
|
||||||
assertThat(actual, allOf(greaterThanOrEqualTo(1799 - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800 + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
assertThat(actual, allOf(greaterThanOrEqualTo(1799L - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800L + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
||||||
assertEquals(sessionId, refreshToken.getSessionState());
|
assertEquals(sessionId, refreshToken.getSessionState());
|
||||||
|
|
||||||
setTimeOffset(2);
|
setTimeOffset(2);
|
||||||
|
@ -410,10 +410,10 @@ public class HoKTest extends AbstractTestRealmKeycloakTest {
|
||||||
assertEquals(sessionId, refreshedRefreshToken.getSessionState());
|
assertEquals(sessionId, refreshedRefreshToken.getSessionState());
|
||||||
|
|
||||||
assertThat(response.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
|
assertThat(response.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
|
||||||
assertThat(refreshedToken.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(250 - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(300 + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
assertThat(refreshedToken.getExp() - getCurrentTime(), allOf(greaterThanOrEqualTo(250L - RefreshTokenTest.ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(300L + RefreshTokenTest.ALLOWED_CLOCK_SKEW)));
|
||||||
|
|
||||||
assertThat(refreshedToken.getExpiration() - token.getExpiration(), allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(10)));
|
assertThat(refreshedToken.getExp() - token.getExp(), allOf(greaterThanOrEqualTo(1L), lessThanOrEqualTo(10L)));
|
||||||
assertThat(refreshedRefreshToken.getExpiration() - refreshToken.getExpiration(), allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(10)));
|
assertThat(refreshedRefreshToken.getExp() - refreshToken.getExp(), allOf(greaterThanOrEqualTo(1L), lessThanOrEqualTo(10L)));
|
||||||
|
|
||||||
Assert.assertNotEquals(token.getId(), refreshedToken.getId());
|
Assert.assertNotEquals(token.getId(), refreshedToken.getId());
|
||||||
Assert.assertNotEquals(refreshToken.getId(), refreshedRefreshToken.getId());
|
Assert.assertNotEquals(refreshToken.getId(), refreshedRefreshToken.getId());
|
||||||
|
|
|
@ -205,8 +205,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
|
|
||||||
// Check that authTime is available and set to current time
|
// Check that authTime is available and set to current time
|
||||||
int authTime = idToken.getAuthTime();
|
long authTime = idToken.getAuth_time();
|
||||||
int currentTime = Time.currentTime();
|
long currentTime = Time.currentTime();
|
||||||
Assert.assertTrue(authTime <= currentTime && authTime + 3 >= currentTime);
|
Assert.assertTrue(authTime <= currentTime && authTime + 3 >= currentTime);
|
||||||
|
|
||||||
// Set time offset
|
// Set time offset
|
||||||
|
@ -225,7 +225,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
|
|
||||||
// Assert that authTime was updated
|
// Assert that authTime was updated
|
||||||
int authTimeUpdated = idToken.getAuthTime();
|
long authTimeUpdated = idToken.getAuth_time();
|
||||||
Assert.assertTrue(authTime + 10 <= authTimeUpdated);
|
Assert.assertTrue(authTime + 10 <= authTimeUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,8 +238,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
|
|
||||||
// Check that authTime is available and set to current time
|
// Check that authTime is available and set to current time
|
||||||
int authTime = idToken.getAuthTime();
|
long authTime = idToken.getAuth_time();
|
||||||
int currentTime = Time.currentTime();
|
long currentTime = Time.currentTime();
|
||||||
Assert.assertTrue(authTime <= currentTime && authTime + 3 >= currentTime);
|
Assert.assertTrue(authTime <= currentTime && authTime + 3 >= currentTime);
|
||||||
|
|
||||||
// Set time offset
|
// Set time offset
|
||||||
|
@ -255,7 +255,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
|
|
||||||
// Assert that authTime is still the same
|
// Assert that authTime is still the same
|
||||||
int authTimeUpdated = idToken.getAuthTime();
|
long authTimeUpdated = idToken.getAuth_time();
|
||||||
Assert.assertEquals(authTime, authTimeUpdated);
|
Assert.assertEquals(authTime, authTimeUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
|
|
||||||
EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent();
|
EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent();
|
||||||
IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
int authTime = idToken.getAuthTime();
|
long authTime = idToken.getAuth_time();
|
||||||
|
|
||||||
// Set time offset
|
// Set time offset
|
||||||
setTimeOffset(10);
|
setTimeOffset(10);
|
||||||
|
@ -304,7 +304,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
|
|
||||||
loginEvent = events.expectLogin().removeDetail(Details.USERNAME).assertEvent();
|
loginEvent = events.expectLogin().removeDetail(Details.USERNAME).assertEvent();
|
||||||
idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
idToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
int authTime2 = idToken.getAuthTime();
|
long authTime2 = idToken.getAuth_time();
|
||||||
|
|
||||||
Assert.assertEquals(authTime, authTime2);
|
Assert.assertEquals(authTime, authTime2);
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
IDToken newIdToken = sendTokenRequestAndGetIDToken(loginEvent);
|
IDToken newIdToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
|
|
||||||
// Assert that authTime wasn't updated
|
// Assert that authTime wasn't updated
|
||||||
Assert.assertEquals(oldIdToken.getAuthTime(), newIdToken.getAuthTime());
|
Assert.assertEquals(oldIdToken.getAuth_time(), newIdToken.getAuth_time());
|
||||||
|
|
||||||
// Set time offset
|
// Set time offset
|
||||||
setTimeOffset(20);
|
setTimeOffset(20);
|
||||||
|
@ -399,8 +399,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
|
||||||
newIdToken = sendTokenRequestAndGetIDToken(loginEvent);
|
newIdToken = sendTokenRequestAndGetIDToken(loginEvent);
|
||||||
|
|
||||||
// Assert that authTime was updated
|
// Assert that authTime was updated
|
||||||
Assert.assertTrue("Expected auth time to change. old auth time: " + oldIdToken.getAuthTime() + " , new auth time: " + newIdToken.getAuthTime(),
|
Assert.assertTrue("Expected auth time to change. old auth time: " + oldIdToken.getAuth_time() + " , new auth time: " + newIdToken.getAuth_time(),
|
||||||
oldIdToken.getAuthTime() + 20 <= newIdToken.getAuthTime());
|
oldIdToken.getAuth_time() + 20 <= newIdToken.getAuth_time());
|
||||||
|
|
||||||
// Assert userSession didn't change
|
// Assert userSession didn't change
|
||||||
Assert.assertEquals(oldIdToken.getSessionState(), newIdToken.getSessionState());
|
Assert.assertEquals(oldIdToken.getSessionState(), newIdToken.getSessionState());
|
||||||
|
|
Loading…
Reference in a new issue