From 0d5be568f80430566672cda8aab78f66a824082f Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 3 Oct 2014 13:15:29 +0200 Subject: [PATCH] KEYCLOAK-722 Refreshing token throws RuntimeException if realm keys have changed --- .../keycloak/protocol/oidc/TokenManager.java | 2 +- .../testsuite/oauth/RefreshTokenTest.java | 53 ++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java index 761b69f889..33485b0ed1 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java @@ -99,7 +99,7 @@ public class TokenManager { RefreshToken refreshToken = null; try { if (!RSAProvider.verify(jws, realm.getPublicKey())) { - throw new RuntimeException("Invalid refresh token"); + throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Invalid refresh token"); } refreshToken = jws.readJsonContent(RefreshToken.class); } catch (IOException e) { diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java index 803133ea0e..fcd51b3225 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java @@ -33,9 +33,11 @@ import org.keycloak.events.Event; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserSessionModel; +import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.protocol.oidc.OpenIDConnectService; import org.keycloak.representations.AccessToken; import org.keycloak.representations.RefreshToken; +import org.keycloak.services.managers.RealmManager; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.OAuthClient; import org.keycloak.testsuite.OAuthClient.AccessTokenResponse; @@ -56,6 +58,8 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import java.net.URI; +import java.security.PrivateKey; +import java.security.PublicKey; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertEquals; @@ -175,6 +179,54 @@ public class RefreshTokenTest { Assert.assertNotEquals(tokenEvent.getDetails().get(Details.REFRESH_TOKEN_ID), refreshEvent.getDetails().get(Details.UPDATED_REFRESH_TOKEN_ID)); } + PrivateKey privateKey; + PublicKey publicKey; + + @Test + public void refreshTokenRealmKeysChanged() throws Exception { + oauth.doLogin("test-user@localhost", "password"); + + Event loginEvent = events.expectLogin().assertEvent(); + + String sessionId = loginEvent.getSessionId(); + String codeId = loginEvent.getDetails().get(Details.CODE_ID); + + String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); + + AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password"); + String refreshTokenString = response.getRefreshToken(); + RefreshToken refreshToken = oauth.verifyRefreshToken(refreshTokenString); + + events.expectCodeToToken(codeId, sessionId).assertEvent(); + + try { + keycloakRule.configure(new KeycloakRule.KeycloakSetup() { + @Override + public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { + privateKey = appRealm.getPrivateKey(); + publicKey = appRealm.getPublicKey(); + KeycloakModelUtils.generateRealmKeys(appRealm); + } + }); + + response = oauth.doRefreshTokenRequest(refreshTokenString, "password"); + + assertEquals(400, response.getStatusCode()); + assertEquals("invalid_grant", response.getError()); + + events.expectRefresh(refreshToken.getId(), sessionId).user((String) null).session((String) null).clearDetails().error(Errors.INVALID_TOKEN).assertEvent(); + } finally { + keycloakRule.configure(new KeycloakRule.KeycloakSetup() { + @Override + public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { + appRealm.setPrivateKey(privateKey); + appRealm.setPublicKey(publicKey); + } + }); + + } + } + @Test public void refreshTokenUserSessionExpired() { oauth.doLogin("test-user@localhost", "password"); @@ -417,5 +469,4 @@ public class RefreshTokenTest { } - }