Revoked token cache expiration fix
Added 1 second to the duration of the cache for revoked tokens to prevent them from still being valid for 1 second after the expiration date of the access token. Closes #26113 Signed-off-by: graziang <g.graziano94@gmail.com>
This commit is contained in:
parent
6071d5b687
commit
54b40d31b6
2 changed files with 22 additions and 1 deletions
|
@ -266,7 +266,7 @@ public class TokenRevocationEndpoint {
|
||||||
private void revokeAccessToken() {
|
private void revokeAccessToken() {
|
||||||
SingleUseObjectProvider singleUseStore = session.singleUseObjects();
|
SingleUseObjectProvider singleUseStore = session.singleUseObjects();
|
||||||
int currentTime = Time.currentTime();
|
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());
|
singleUseStore.put(token.getId() + SingleUseObjectProvider.REVOKED_KEY, lifespanInSecs, Collections.emptyMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ import org.keycloak.testsuite.util.OAuthClient;
|
||||||
import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse;
|
import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse;
|
||||||
import org.keycloak.testsuite.util.RealmBuilder;
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
import org.keycloak.testsuite.util.UserInfoClientUtil;
|
import org.keycloak.testsuite.util.UserInfoClientUtil;
|
||||||
|
import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,6 +85,9 @@ public class TokenRevocationTest extends AbstractKeycloakTest {
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(this);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeAbstractKeycloakTest() throws Exception {
|
public void beforeAbstractKeycloakTest() throws Exception {
|
||||||
super.beforeAbstractKeycloakTest();
|
super.beforeAbstractKeycloakTest();
|
||||||
|
@ -171,6 +175,23 @@ public class TokenRevocationTest extends AbstractKeycloakTest {
|
||||||
isAccessTokenDisabled(tokenResponse.getAccessToken(), "test-app");
|
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
|
@Test
|
||||||
public void testRevokeOfflineToken() throws Exception {
|
public void testRevokeOfflineToken() throws Exception {
|
||||||
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
|
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
|
||||||
|
|
Loading…
Reference in a new issue