use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class OfflineTokenTest method offlineTokenServiceAccountFlow.
@Test
public void offlineTokenServiceAccountFlow() throws Exception {
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.clientId("offline-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
String offlineTokenString = tokenResponse.getRefreshToken();
RefreshToken offlineToken = oauth.parseRefreshToken(offlineTokenString);
events.expectClientLogin().client("offline-client").user(serviceAccountUserId).session(token.getSessionState()).detail(Details.TOKEN_ID, token.getId()).detail(Details.REFRESH_TOKEN_ID, offlineToken.getId()).detail(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_OFFLINE).detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "offline-client").assertEvent();
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
Assert.assertEquals(0, offlineToken.getExpiration());
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
// Now retrieve another offline token and verify that previous offline token is still valid
tokenResponse = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
AccessToken token2 = oauth.verifyToken(tokenResponse.getAccessToken());
String offlineTokenString2 = tokenResponse.getRefreshToken();
RefreshToken offlineToken2 = oauth.parseRefreshToken(offlineTokenString2);
events.expectClientLogin().client("offline-client").user(serviceAccountUserId).session(token2.getSessionState()).detail(Details.TOKEN_ID, token2.getId()).detail(Details.REFRESH_TOKEN_ID, offlineToken2.getId()).detail(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_OFFLINE).detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "offline-client").assertEvent();
// Refresh with both offline tokens is fine
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), serviceAccountUserId);
testRefreshWithOfflineToken(token2, offlineToken2, offlineTokenString2, token2.getSessionState(), serviceAccountUserId);
}
use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class OfflineTokenTest method offlineTokenDirectGrantFlowWithRefreshTokensRevoked.
@Test
public void offlineTokenDirectGrantFlowWithRefreshTokensRevoked() throws Exception {
RealmManager.realm(adminClient.realm("test")).revokeRefreshToken(true);
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.clientId("offline-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "test-user@localhost", "password");
AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
String offlineTokenString = tokenResponse.getRefreshToken();
RefreshToken offlineToken = oauth.parseRefreshToken(offlineTokenString);
events.expectLogin().client("offline-client").user(userId).session(token.getSessionState()).detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD).detail(Details.TOKEN_ID, token.getId()).detail(Details.REFRESH_TOKEN_ID, offlineToken.getId()).detail(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_OFFLINE).detail(Details.USERNAME, "test-user@localhost").removeDetail(Details.CODE_ID).removeDetail(Details.REDIRECT_URI).removeDetail(Details.CONSENT).assertEvent();
Assert.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType());
Assert.assertEquals(0, offlineToken.getExpiration());
String offlineTokenString2 = testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
RefreshToken offlineToken2 = oauth.parseRefreshToken(offlineTokenString2);
// Assert second refresh with same refresh token will fail
OAuthClient.AccessTokenResponse response = oauth.doRefreshTokenRequest(offlineTokenString, "secret1");
Assert.assertEquals(400, response.getStatusCode());
events.expectRefresh(offlineToken.getId(), token.getSessionState()).client("offline-client").error(Errors.INVALID_TOKEN).user(userId).clearDetails().assertEvent();
// Refresh with new refreshToken fails as well (client session was invalidated because of attempt to refresh with revoked refresh token)
OAuthClient.AccessTokenResponse response2 = oauth.doRefreshTokenRequest(offlineTokenString2, "secret1");
Assert.assertEquals(400, response2.getStatusCode());
events.expectRefresh(offlineToken2.getId(), offlineToken2.getSessionState()).client("offline-client").error(Errors.INVALID_TOKEN).user(userId).clearDetails().assertEvent();
RealmManager.realm(adminClient.realm("test")).revokeRefreshToken(false);
}
use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class RefreshTokenTest method loginAndForceNewLoginPage.
private String loginAndForceNewLoginPage() {
oauth.doLogin("test-user@localhost", "password");
EventRepresentation loginEvent = events.expectLogin().assertEvent();
String sessionId = loginEvent.getSessionId();
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
OAuthClient.AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code, "password");
events.poll();
// Assert refresh successful
String refreshToken = tokenResponse.getRefreshToken();
RefreshToken refreshTokenParsed1 = oauth.parseRefreshToken(tokenResponse.getRefreshToken());
processExpectedValidRefresh(sessionId, refreshTokenParsed1, refreshToken);
// Set time offset to 1 (Just to simulate to be more close to real situation)
setTimeOffset(1);
// Open the tab with prompt=login. AuthenticationSession will be created with same ID like userSession
String loginFormUri = UriBuilder.fromUri(oauth.getLoginFormUrl()).queryParam(OIDCLoginProtocol.PROMPT_PARAM, OIDCLoginProtocol.PROMPT_VALUE_LOGIN).build().toString();
driver.navigate().to(loginFormUri);
loginPage.assertCurrent();
Assert.assertEquals("test-user@localhost", loginPage.getAttemptedUsername());
return refreshToken;
}
use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class RefreshTokenTest method refreshTokenReuseOfExistingTokenAfterDisablingReuseRevokation.
@Test
public void refreshTokenReuseOfExistingTokenAfterDisablingReuseRevokation() throws Exception {
try {
RealmManager.realm(adminClient.realm("test")).revokeRefreshToken(true).refreshTokenMaxReuse(1);
oauth.doLogin("test-user@localhost", "password");
EventRepresentation loginEvent = events.expectLogin().assertEvent();
String sessionId = loginEvent.getSessionId();
String codeId = loginEvent.getDetails().get(Details.CODE_ID);
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
OAuthClient.AccessTokenResponse initialResponse = oauth.doAccessTokenRequest(code, "password");
RefreshToken initialRefreshToken = oauth.parseRefreshToken(initialResponse.getRefreshToken());
events.expectCodeToToken(codeId, sessionId).assertEvent();
setTimeOffset(2);
// Single reuse authorized.
processExpectedValidRefresh(sessionId, initialRefreshToken, initialResponse.getRefreshToken());
processExpectedValidRefresh(sessionId, initialRefreshToken, initialResponse.getRefreshToken());
OAuthClient.AccessTokenResponse responseReuseExceeded = oauth.doRefreshTokenRequest(initialResponse.getRefreshToken(), "password");
assertEquals(400, responseReuseExceeded.getStatusCode());
events.expectRefresh(initialRefreshToken.getId(), sessionId).removeDetail(Details.TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error("invalid_token").assertEvent();
RealmManager.realm(adminClient.realm("test")).revokeRefreshToken(false);
// Config changed, token cannot be used again at this point due the client session invalidated
OAuthClient.AccessTokenResponse responseReuseExceeded2 = oauth.doRefreshTokenRequest(initialResponse.getRefreshToken(), "password");
assertEquals(400, responseReuseExceeded2.getStatusCode());
events.expectRefresh(initialRefreshToken.getId(), sessionId).removeDetail(Details.TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error("invalid_token").assertEvent();
} finally {
setTimeOffset(0);
RealmManager.realm(adminClient.realm("test")).refreshTokenMaxReuse(0).revokeRefreshToken(false);
}
}
use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class ServiceAccountTest method clientCredentialsLogout.
// This is for the backwards compatibility only. By default, there won't be refresh token and hence there won't be availability for the logout
@Test
public void clientCredentialsLogout() throws Exception {
oauth.clientId("service-account-cl-refresh-on");
events.clear();
OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
assertEquals(200, response.getStatusCode());
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
events.expectClientLogin().client("service-account-cl-refresh-on").user(userId).session(accessToken.getSessionState()).detail(Details.TOKEN_ID, accessToken.getId()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()).detail(Details.USERNAME, userName).detail(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID).assertEvent();
HttpResponse logoutResponse = oauth.doLogout(response.getRefreshToken(), "secret1");
assertEquals(204, logoutResponse.getStatusLine().getStatusCode());
events.expectLogout(accessToken.getSessionState()).client("service-account-cl-refresh-on").user(userId).removeDetail(Details.REDIRECT_URI).assertEvent();
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1");
assertEquals(400, response.getStatusCode());
assertEquals("invalid_grant", response.getError());
events.expectRefresh(refreshToken.getId(), refreshToken.getSessionState()).client("service-account-cl-refresh-on").user(userId).removeDetail(Details.TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error(Errors.INVALID_TOKEN).assertEvent();
}
Aggregations