Search in sources :

Example 51 with RefreshToken

use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.

the class RefreshTokenTest method refreshTokenUserDeleted.

@Test
public void refreshTokenUserDeleted() throws Exception {
    String userId = createUser("test", "temp-user@localhost", "password");
    oauth.doLogin("temp-user@localhost", "password");
    EventRepresentation loginEvent = events.expectLogin().user(userId).assertEvent();
    String sessionId = loginEvent.getSessionId();
    String codeId = loginEvent.getDetails().get(Details.CODE_ID);
    String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
    OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
    String refreshTokenString = response.getRefreshToken();
    RefreshToken refreshToken = oauth.parseRefreshToken(refreshTokenString);
    events.expectCodeToToken(codeId, sessionId).user(userId).assertEvent();
    adminClient.realm("test").users().delete(userId);
    setTimeOffset(2);
    response = oauth.doRefreshTokenRequest(refreshTokenString, "password");
    assertEquals(400, response.getStatusCode());
    assertEquals("invalid_grant", response.getError());
    events.expectRefresh(refreshToken.getId(), sessionId).user(userId).clearDetails().error(Errors.INVALID_TOKEN).assertEvent();
}
Also used : RefreshToken(org.keycloak.representations.RefreshToken) OAuthClient(org.keycloak.testsuite.util.OAuthClient) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 52 with RefreshToken

use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.

the class RefreshTokenTest method refreshTokenReuseTokenWithRefreshTokensRevokedAndSSOReauthentication.

// Doublecheck that with "revokeRefreshToken" and revoked tokens, the SSO re-authentication won't cause old tokens to be valid again
@Test
public void refreshTokenReuseTokenWithRefreshTokensRevokedAndSSOReauthentication() throws Exception {
    try {
        // Initial login
        RealmManager.realm(adminClient.realm("test")).revokeRefreshToken(true);
        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 response1 = oauth.doAccessTokenRequest(code, "password");
        RefreshToken refreshToken1 = oauth.parseRefreshToken(response1.getRefreshToken());
        events.expectCodeToToken(codeId, sessionId).assertEvent();
        // Refresh token for the first time - should pass
        setTimeOffset(2);
        OAuthClient.AccessTokenResponse response2 = oauth.doRefreshTokenRequest(response1.getRefreshToken(), "password");
        RefreshToken refreshToken2 = oauth.parseRefreshToken(response2.getRefreshToken());
        assertEquals(200, response2.getStatusCode());
        events.expectRefresh(refreshToken1.getId(), sessionId).assertEvent();
        // Client sessions is available now
        Assert.assertTrue(hasClientSessionForTestApp());
        // Refresh token for the second time - should fail and invalidate client session
        setTimeOffset(4);
        OAuthClient.AccessTokenResponse response3 = oauth.doRefreshTokenRequest(response1.getRefreshToken(), "password");
        assertEquals(400, response3.getStatusCode());
        events.expectRefresh(refreshToken1.getId(), sessionId).removeDetail(Details.TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error("invalid_token").assertEvent();
        // No client sessions available after revoke
        Assert.assertFalse(hasClientSessionForTestApp());
        // Introspection with the accessToken from the first authentication. This should fail
        String introspectionResponse = oauth.introspectAccessTokenWithClientCredential("test-app", "password", response1.getAccessToken());
        JsonNode jsonNode = JsonSerialization.mapper.readTree(introspectionResponse);
        Assert.assertFalse(jsonNode.get("active").asBoolean());
        events.clear();
        // SSO re-authentication
        setTimeOffset(6);
        oauth.openLoginForm();
        loginEvent = events.expectLogin().assertEvent();
        sessionId = loginEvent.getSessionId();
        codeId = loginEvent.getDetails().get(Details.CODE_ID);
        code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
        OAuthClient.AccessTokenResponse response4 = oauth.doAccessTokenRequest(code, "password");
        RefreshToken refreshToken4 = oauth.parseRefreshToken(response4.getRefreshToken());
        events.expectCodeToToken(codeId, sessionId).assertEvent();
        // Client sessions should be available again now after re-authentication
        Assert.assertTrue(hasClientSessionForTestApp());
        // Introspection again with the accessToken from the very first authentication. This should fail as the access token was obtained for the old client session before SSO re-authentication
        introspectionResponse = oauth.introspectAccessTokenWithClientCredential("test-app", "password", response1.getAccessToken());
        jsonNode = JsonSerialization.mapper.readTree(introspectionResponse);
        Assert.assertFalse(jsonNode.get("active").asBoolean());
        // Try userInfo with the same old access token. Should fail as well
        UserInfo userInfo = oauth.doUserInfoRequest(response1.getAccessToken());
        Assert.assertNull(userInfo.getSubject());
        Assert.assertEquals(userInfo.getOtherClaims().get(OAuth2Constants.ERROR), OAuthErrorException.INVALID_TOKEN);
        events.clear();
        // Try to refresh with one of the old refresh tokens before SSO re-authentication - should fail
        setTimeOffset(8);
        OAuthClient.AccessTokenResponse response5 = oauth.doRefreshTokenRequest(response2.getRefreshToken(), "password");
        assertEquals(400, response5.getStatusCode());
        events.expectRefresh(refreshToken2.getId(), sessionId).removeDetail(Details.TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error("invalid_token").assertEvent();
    } finally {
        setTimeOffset(0);
        RealmManager.realm(adminClient.realm("test")).revokeRefreshToken(false);
    }
}
Also used : RefreshToken(org.keycloak.representations.RefreshToken) OAuthClient(org.keycloak.testsuite.util.OAuthClient) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) JsonNode(com.fasterxml.jackson.databind.JsonNode) UserInfo(org.keycloak.representations.UserInfo) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 53 with RefreshToken

use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.

the class RefreshTokenTest method refreshTokenUserDisabled.

@Test
public void refreshTokenUserDisabled() throws Exception {
    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 response = oauth.doAccessTokenRequest(code, "password");
    String refreshTokenString = response.getRefreshToken();
    RefreshToken refreshToken = oauth.parseRefreshToken(refreshTokenString);
    events.expectCodeToToken(codeId, sessionId).assertEvent();
    try {
        UserManager.realm(adminClient.realm("test")).username("test-user@localhost").enabled(false);
        setTimeOffset(2);
        response = oauth.doRefreshTokenRequest(refreshTokenString, "password");
        assertEquals(400, response.getStatusCode());
        assertEquals("invalid_grant", response.getError());
        events.expectRefresh(refreshToken.getId(), sessionId).clearDetails().error(Errors.INVALID_TOKEN).assertEvent();
    } finally {
        UserManager.realm(adminClient.realm("test")).username("test-user@localhost").enabled(true);
    }
}
Also used : RefreshToken(org.keycloak.representations.RefreshToken) OAuthClient(org.keycloak.testsuite.util.OAuthClient) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 54 with RefreshToken

use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.

the class ServiceAccountTest method clientCredentialsAuthSuccess.

@Test
public void clientCredentialsAuthSuccess() throws Exception {
    oauth.clientId("service-account-cl-refresh-on");
    OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
    assertEquals(200, response.getStatusCode());
    // older clients which use client-credentials grant may create a refresh-token and session, see KEYCLOAK-9551.
    List<Map<String, String>> clientSessionStats = getAdminClient().realm(oauth.getRealm()).getClientSessionStats();
    assertThat(clientSessionStats, hasSize(1));
    Map<String, String> sessionStats = clientSessionStats.get(0);
    assertEquals(sessionStats.get("clientId"), oauth.getClientId());
    // Refresh token is for backwards compatibility only. It won't be in client credentials by default
    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).assertEvent();
    assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
    System.out.println("Access token other claims: " + accessToken.getOtherClaims());
    Assert.assertEquals("service-account-cl-refresh-on", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID));
    Assert.assertTrue(accessToken.getOtherClaims().containsKey(ServiceAccountConstants.CLIENT_ADDRESS));
    Assert.assertTrue(accessToken.getOtherClaims().containsKey(ServiceAccountConstants.CLIENT_HOST));
    OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1");
    AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken());
    RefreshToken refreshedRefreshToken = oauth.parseRefreshToken(refreshedResponse.getRefreshToken());
    assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState());
    assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState());
    events.expectRefresh(refreshToken.getId(), refreshToken.getSessionState()).user(userId).client("service-account-cl-refresh-on").assertEvent();
}
Also used : RefreshToken(org.keycloak.representations.RefreshToken) OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) Map(java.util.Map) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 55 with RefreshToken

use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.

the class AuthorizationTokenService method createAuthorizationResponse.

private AuthorizationResponse createAuthorizationResponse(KeycloakIdentity identity, Collection<Permission> entitlements, KeycloakAuthorizationRequest request, ClientModel targetClient) {
    KeycloakSession keycloakSession = request.getKeycloakSession();
    AccessToken accessToken = identity.getAccessToken();
    RealmModel realm = request.getRealm();
    UserSessionProvider sessions = keycloakSession.sessions();
    UserSessionModel userSessionModel;
    if (accessToken.getSessionState() == null) {
        // Create temporary (request-scoped) transient session
        UserModel user = TokenManager.lookupUserFromStatelessToken(keycloakSession, realm, accessToken);
        userSessionModel = sessions.createUserSession(KeycloakModelUtils.generateId(), realm, user, user.getUsername(), request.getClientConnection().getRemoteAddr(), ServiceAccountConstants.CLIENT_AUTH, false, null, null, UserSessionModel.SessionPersistenceState.TRANSIENT);
    } else {
        userSessionModel = sessions.getUserSession(realm, accessToken.getSessionState());
        if (userSessionModel == null) {
            userSessionModel = sessions.getOfflineUserSession(realm, accessToken.getSessionState());
        }
    }
    ClientModel client = realm.getClientByClientId(accessToken.getIssuedFor());
    AuthenticatedClientSessionModel clientSession = userSessionModel.getAuthenticatedClientSessionByClient(targetClient.getId());
    ClientSessionContext clientSessionCtx;
    if (clientSession == null) {
        RootAuthenticationSessionModel rootAuthSession = keycloakSession.authenticationSessions().getRootAuthenticationSession(realm, userSessionModel.getId());
        if (rootAuthSession == null) {
            if (userSessionModel.getUser().getServiceAccountClientLink() == null) {
                rootAuthSession = keycloakSession.authenticationSessions().createRootAuthenticationSession(realm, userSessionModel.getId());
            } else {
                // if the user session is associated with a service account
                rootAuthSession = new AuthenticationSessionManager(keycloakSession).createAuthenticationSession(realm, false);
            }
        }
        AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(targetClient);
        authSession.setAuthenticatedUser(userSessionModel.getUser());
        authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
        authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(keycloakSession.getContext().getUri().getBaseUri(), realm.getName()));
        AuthenticationManager.setClientScopesInSession(authSession);
        clientSessionCtx = TokenManager.attachAuthenticationSession(keycloakSession, userSessionModel, authSession);
    } else {
        clientSessionCtx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession, keycloakSession);
    }
    TokenManager tokenManager = request.getTokenManager();
    EventBuilder event = request.getEvent();
    AccessTokenResponseBuilder responseBuilder = tokenManager.responseBuilder(realm, client, event, keycloakSession, userSessionModel, clientSessionCtx).generateAccessToken();
    AccessToken rpt = responseBuilder.getAccessToken();
    Authorization authorization = new Authorization();
    authorization.setPermissions(entitlements);
    rpt.setAuthorization(authorization);
    if (accessToken.getSessionState() == null) {
        // Skip generating refresh token for accessToken without sessionState claim. This is "stateless" accessToken not pointing to any real persistent userSession
        rpt.setSessionState(null);
    } else {
        if (OIDCAdvancedConfigWrapper.fromClientModel(client).isUseRefreshToken()) {
            responseBuilder.generateRefreshToken();
            RefreshToken refreshToken = responseBuilder.getRefreshToken();
            refreshToken.issuedFor(client.getClientId());
            refreshToken.setAuthorization(authorization);
        }
    }
    if (!rpt.hasAudience(targetClient.getClientId())) {
        rpt.audience(targetClient.getClientId());
    }
    return new AuthorizationResponse(responseBuilder.build(), isUpgraded(request, authorization));
}
Also used : UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) AuthorizationResponse(org.keycloak.representations.idm.authorization.AuthorizationResponse) RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Authorization(org.keycloak.representations.AccessToken.Authorization) UserSessionProvider(org.keycloak.models.UserSessionProvider) ClientModel(org.keycloak.models.ClientModel) EventBuilder(org.keycloak.events.EventBuilder) RefreshToken(org.keycloak.representations.RefreshToken) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) ClientSessionContext(org.keycloak.models.ClientSessionContext) AccessToken(org.keycloak.representations.AccessToken) KeycloakSession(org.keycloak.models.KeycloakSession) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) AccessTokenResponseBuilder(org.keycloak.protocol.oidc.TokenManager.AccessTokenResponseBuilder) TokenManager(org.keycloak.protocol.oidc.TokenManager)

Aggregations

RefreshToken (org.keycloak.representations.RefreshToken)68 OAuthClient (org.keycloak.testsuite.util.OAuthClient)50 AccessToken (org.keycloak.representations.AccessToken)45 Test (org.junit.Test)34 AbstractKeycloakTest (org.keycloak.testsuite.AbstractKeycloakTest)29 EventRepresentation (org.keycloak.representations.idm.EventRepresentation)27 JWSInput (org.keycloak.jose.jws.JWSInput)10 ClientRepresentation (org.keycloak.representations.idm.ClientRepresentation)6 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)6 IOException (java.io.IOException)5 HttpResponse (org.apache.http.HttpResponse)5 JWSHeader (org.keycloak.jose.jws.JWSHeader)5 IDToken (org.keycloak.representations.IDToken)5 CloseableHttpResponse (org.apache.http.client.methods.CloseableHttpResponse)4 ClientResource (org.keycloak.admin.client.resource.ClientResource)4 OIDCClientRepresentation (org.keycloak.representations.oidc.OIDCClientRepresentation)4 ClientPolicyException (org.keycloak.services.clientpolicy.ClientPolicyException)4 AccessTokenResponse (org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse)4 KeyPair (java.security.KeyPair)3 PrivateKey (java.security.PrivateKey)3