Search in sources :

Example 21 with EventRepresentation

use of org.keycloak.representations.idm.EventRepresentation in project keycloak by keycloak.

the class RefreshTokenTest method refreshTokenReuseTokenWithRefreshTokensRevoked.

@Test
public void refreshTokenReuseTokenWithRefreshTokensRevoked() throws Exception {
    try {
        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();
        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();
        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();
        // Client session invalidated hence old refresh token not valid anymore
        setTimeOffset(6);
        OAuthClient.AccessTokenResponse response4 = oauth.doRefreshTokenRequest(response2.getRefreshToken(), "password");
        assertEquals(400, response4.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) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 22 with EventRepresentation

use of org.keycloak.representations.idm.EventRepresentation in project keycloak by keycloak.

the class RefreshTokenTest method refreshTokenRequest.

@Test
public void refreshTokenRequest() throws Exception {
    oauth.nonce("123456");
    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 tokenResponse = oauth.doAccessTokenRequest(code, "password");
    AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
    assertEquals("123456", token.getNonce());
    String refreshTokenString = tokenResponse.getRefreshToken();
    RefreshToken refreshToken = oauth.parseRefreshToken(refreshTokenString);
    EventRepresentation tokenEvent = events.expectCodeToToken(codeId, sessionId).assertEvent();
    assertNotNull(refreshTokenString);
    assertEquals("Bearer", tokenResponse.getTokenType());
    Assert.assertThat(token.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(200), lessThanOrEqualTo(350)));
    int actual = refreshToken.getExpiration() - getCurrentTime();
    Assert.assertThat(actual, allOf(greaterThanOrEqualTo(1799 - ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(1800 + ALLOWED_CLOCK_SKEW)));
    assertEquals(sessionId, refreshToken.getSessionState());
    setTimeOffset(2);
    OAuthClient.AccessTokenResponse response = oauth.doRefreshTokenRequest(refreshTokenString, "password");
    AccessToken refreshedToken = oauth.verifyToken(response.getAccessToken());
    RefreshToken refreshedRefreshToken = oauth.parseRefreshToken(response.getRefreshToken());
    assertEquals(200, response.getStatusCode());
    assertEquals(sessionId, refreshedToken.getSessionState());
    assertEquals(sessionId, refreshedRefreshToken.getSessionState());
    Assert.assertThat(response.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
    Assert.assertThat(refreshedToken.getExpiration() - getCurrentTime(), allOf(greaterThanOrEqualTo(250 - ALLOWED_CLOCK_SKEW), lessThanOrEqualTo(300 + ALLOWED_CLOCK_SKEW)));
    Assert.assertThat(refreshedToken.getExpiration() - token.getExpiration(), allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(10)));
    Assert.assertThat(refreshedRefreshToken.getExpiration() - refreshToken.getExpiration(), allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(10)));
    // "test-app" should not be an audience in the refresh token
    assertEquals("test-app", refreshedRefreshToken.getIssuedFor());
    Assert.assertFalse(refreshedRefreshToken.hasAudience("test-app"));
    Assert.assertNotEquals(token.getId(), refreshedToken.getId());
    Assert.assertNotEquals(refreshToken.getId(), refreshedRefreshToken.getId());
    assertEquals("Bearer", response.getTokenType());
    assertEquals(findUserByUsername(adminClient.realm("test"), "test-user@localhost").getId(), refreshedToken.getSubject());
    Assert.assertNotEquals("test-user@localhost", refreshedToken.getSubject());
    assertTrue(refreshedToken.getRealmAccess().isUserInRole("user"));
    assertEquals(1, refreshedToken.getResourceAccess(oauth.getClientId()).getRoles().size());
    assertTrue(refreshedToken.getResourceAccess(oauth.getClientId()).isUserInRole("customer-user"));
    EventRepresentation refreshEvent = events.expectRefresh(tokenEvent.getDetails().get(Details.REFRESH_TOKEN_ID), sessionId).assertEvent();
    Assert.assertNotEquals(tokenEvent.getDetails().get(Details.TOKEN_ID), refreshEvent.getDetails().get(Details.TOKEN_ID));
    Assert.assertNotEquals(tokenEvent.getDetails().get(Details.REFRESH_TOKEN_ID), refreshEvent.getDetails().get(Details.UPDATED_REFRESH_TOKEN_ID));
    assertEquals("123456", refreshedToken.getNonce());
    setTimeOffset(0);
}
Also used : RefreshToken(org.keycloak.representations.RefreshToken) OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 23 with EventRepresentation

use of org.keycloak.representations.idm.EventRepresentation in project keycloak by keycloak.

the class RefreshTokenTest method refreshTokenReuseOfExistingTokenAfterEnablingReuseRevokation.

@Test
public void refreshTokenReuseOfExistingTokenAfterEnablingReuseRevokation() throws Exception {
    try {
        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);
        // Infinite reuse allowed
        processExpectedValidRefresh(sessionId, initialRefreshToken, initialResponse.getRefreshToken());
        processExpectedValidRefresh(sessionId, initialRefreshToken, initialResponse.getRefreshToken());
        processExpectedValidRefresh(sessionId, initialRefreshToken, initialResponse.getRefreshToken());
        RealmManager.realm(adminClient.realm("test")).revokeRefreshToken(true).refreshTokenMaxReuse(1);
        // Config changed, we start tracking reuse.
        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();
    } finally {
        setTimeOffset(0);
        RealmManager.realm(adminClient.realm("test")).refreshTokenMaxReuse(0).revokeRefreshToken(false);
    }
}
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 24 with EventRepresentation

use of org.keycloak.representations.idm.EventRepresentation in project keycloak by keycloak.

the class RefreshTokenTest method testUserSessionRefreshAndIdle.

@Test
public void testUserSessionRefreshAndIdle() throws Exception {
    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();
    String refreshId = oauth.parseRefreshToken(tokenResponse.getRefreshToken()).getId();
    int last = testingClient.testing().getLastSessionRefresh("test", sessionId, false);
    setTimeOffset(2);
    tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken(), "password");
    AccessToken refreshedToken = oauth.verifyToken(tokenResponse.getAccessToken());
    RefreshToken refreshedRefreshToken = oauth.parseRefreshToken(tokenResponse.getRefreshToken());
    assertEquals(200, tokenResponse.getStatusCode());
    int next = testingClient.testing().getLastSessionRefresh("test", sessionId, false);
    Assert.assertNotEquals(last, next);
    RealmResource realmResource = adminClient.realm("test");
    int lastAccessTokenLifespan = realmResource.toRepresentation().getAccessTokenLifespan();
    int originalIdle = realmResource.toRepresentation().getSsoSessionIdleTimeout();
    try {
        RealmManager.realm(realmResource).accessTokenLifespan(100000);
        setTimeOffset(4);
        tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken(), "password");
        next = testingClient.testing().getLastSessionRefresh("test", sessionId, false);
        // lastSEssionRefresh should be updated because access code lifespan is higher than sso idle timeout
        Assert.assertThat(next, allOf(greaterThan(last), lessThan(last + 50)));
        RealmManager.realm(realmResource).ssoSessionIdleTimeout(1);
        events.clear();
        // Needs to add some additional time due the tollerance allowed by IDLE_TIMEOUT_WINDOW_SECONDS
        setTimeOffset(6 + SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS);
        tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken(), "password");
        // test idle timeout
        assertEquals(400, tokenResponse.getStatusCode());
        assertNull(tokenResponse.getAccessToken());
        assertNull(tokenResponse.getRefreshToken());
        events.expectRefresh(refreshId, sessionId).error(Errors.INVALID_TOKEN);
    } finally {
        RealmManager.realm(realmResource).ssoSessionIdleTimeout(originalIdle).accessTokenLifespan(lastAccessTokenLifespan);
        events.clear();
        setTimeOffset(0);
    }
}
Also used : RefreshToken(org.keycloak.representations.RefreshToken) OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) RealmResource(org.keycloak.admin.client.resource.RealmResource) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 25 with EventRepresentation

use of org.keycloak.representations.idm.EventRepresentation in project keycloak by keycloak.

the class RefreshTokenTest method refreshTokenReuseTokenWithRefreshTokensRevokedAfterSingleReuse.

@Test
public void refreshTokenReuseTokenWithRefreshTokensRevokedAfterSingleReuse() 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);
        // Initial refresh.
        OAuthClient.AccessTokenResponse responseFirstUse = oauth.doRefreshTokenRequest(initialResponse.getRefreshToken(), "password");
        RefreshToken newTokenFirstUse = oauth.parseRefreshToken(responseFirstUse.getRefreshToken());
        assertEquals(200, responseFirstUse.getStatusCode());
        events.expectRefresh(initialRefreshToken.getId(), sessionId).assertEvent();
        setTimeOffset(4);
        // Second refresh (allowed).
        OAuthClient.AccessTokenResponse responseFirstReuse = oauth.doRefreshTokenRequest(initialResponse.getRefreshToken(), "password");
        RefreshToken newTokenFirstReuse = oauth.parseRefreshToken(responseFirstReuse.getRefreshToken());
        assertEquals(200, responseFirstReuse.getStatusCode());
        events.expectRefresh(initialRefreshToken.getId(), sessionId).assertEvent();
        setTimeOffset(6);
        // Token reused twice, became invalid.
        OAuthClient.AccessTokenResponse responseSecondReuse = oauth.doRefreshTokenRequest(initialResponse.getRefreshToken(), "password");
        assertEquals(400, responseSecondReuse.getStatusCode());
        events.expectRefresh(initialRefreshToken.getId(), sessionId).removeDetail(Details.TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error("invalid_token").assertEvent();
        setTimeOffset(8);
        // Refresh token from first use became invalid.
        OAuthClient.AccessTokenResponse responseUseOfInvalidatedRefreshToken = oauth.doRefreshTokenRequest(responseFirstUse.getRefreshToken(), "password");
        assertEquals(400, responseUseOfInvalidatedRefreshToken.getStatusCode());
        events.expectRefresh(newTokenFirstUse.getId(), sessionId).removeDetail(Details.TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error("invalid_token").assertEvent();
        setTimeOffset(10);
        // Refresh token from reuse is not valid. Client session was invalidated
        OAuthClient.AccessTokenResponse responseUseOfValidRefreshToken = oauth.doRefreshTokenRequest(responseFirstReuse.getRefreshToken(), "password");
        assertEquals(400, responseUseOfValidRefreshToken.getStatusCode());
        events.expectRefresh(newTokenFirstReuse.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);
    }
}
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)

Aggregations

EventRepresentation (org.keycloak.representations.idm.EventRepresentation)164 Test (org.junit.Test)124 OAuthClient (org.keycloak.testsuite.util.OAuthClient)93 AbstractKeycloakTest (org.keycloak.testsuite.AbstractKeycloakTest)60 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)44 RefreshToken (org.keycloak.representations.RefreshToken)27 ClientResource (org.keycloak.admin.client.resource.ClientResource)26 AccessToken (org.keycloak.representations.AccessToken)26 ClientRepresentation (org.keycloak.representations.idm.ClientRepresentation)25 IDToken (org.keycloak.representations.IDToken)23 Matchers.containsString (org.hamcrest.Matchers.containsString)15 AbstractAdminTest (org.keycloak.testsuite.admin.AbstractAdminTest)15 Response (javax.ws.rs.core.Response)13 OIDCClientRepresentation (org.keycloak.representations.oidc.OIDCClientRepresentation)13 AccessTokenResponse (org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse)12 IOException (java.io.IOException)11 RealmResource (org.keycloak.admin.client.resource.RealmResource)11 AssertEvents (org.keycloak.testsuite.AssertEvents)10 JWSInput (org.keycloak.jose.jws.JWSInput)9 TestAuthenticationChannelRequest (org.keycloak.testsuite.rest.representation.TestAuthenticationChannelRequest)9