diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java index f81f28dc68..b0cb3fab33 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenRevocationEndpoint.java @@ -266,7 +266,7 @@ public class TokenRevocationEndpoint { private void revokeAccessToken() { SingleUseObjectProvider singleUseStore = session.singleUseObjects(); int currentTime = Time.currentTime(); - long lifespanInSecs = Math.max(token.getExp() - currentTime, 10); + long lifespanInSecs = Math.max(token.getExp() - currentTime + 1, 10); singleUseStore.put(token.getId() + SingleUseObjectProvider.REVOKED_KEY, lifespanInSecs, Collections.emptyMap()); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java index cad12776e7..6d7e465ebe 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java @@ -69,6 +69,7 @@ import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.UserInfoClientUtil; +import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.util.JsonSerialization; /** @@ -84,6 +85,9 @@ public class TokenRevocationTest extends AbstractKeycloakTest { @Rule public AssertEvents events = new AssertEvents(this); + @Rule + public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); + @Override public void beforeAbstractKeycloakTest() throws Exception { super.beforeAbstractKeycloakTest(); @@ -171,6 +175,23 @@ public class TokenRevocationTest extends AbstractKeycloakTest { isAccessTokenDisabled(tokenResponse.getAccessToken(), "test-app"); } + @Test + public void testRevokedAccessTokenCacheLifespan() throws Exception { + oauth.clientId("test-app"); + OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password"); + + isTokenEnabled(tokenResponse, "test-app"); + + CloseableHttpResponse response = oauth.doTokenRevoke(tokenResponse.getAccessToken(), "access_token", "password"); + assertThat(response, Matchers.statusCodeIsHC(Status.OK)); + + setTimeOffset(adminClient.realm(oauth.getRealm()).toRepresentation().getAccessTokenLifespan()); + + isAccessTokenDisabled(tokenResponse.getAccessToken(), "test-app"); + + setTimeOffset(0); + } + @Test public void testRevokeOfflineToken() throws Exception { oauth.scope(OAuth2Constants.OFFLINE_ACCESS);