Search in sources :

Example 26 with AccessToken

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

the class AccessTokenTest method accessTokenRequest.

@Test
public void accessTokenRequest() 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");
    assertEquals(200, response.getStatusCode());
    Assert.assertThat(response.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
    Assert.assertThat(response.getRefreshExpiresIn(), allOf(greaterThanOrEqualTo(1750), lessThanOrEqualTo(1800)));
    assertEquals("Bearer", response.getTokenType());
    String expectedKid = oauth.doCertsRequest("test").getKeys()[0].getKeyId();
    JWSHeader header = new JWSInput(response.getAccessToken()).getHeader();
    assertEquals("RS256", header.getAlgorithm().name());
    assertEquals("JWT", header.getType());
    assertEquals(expectedKid, header.getKeyId());
    assertNull(header.getContentType());
    header = new JWSInput(response.getIdToken()).getHeader();
    assertEquals("RS256", header.getAlgorithm().name());
    assertEquals("JWT", header.getType());
    assertEquals(expectedKid, header.getKeyId());
    assertNull(header.getContentType());
    header = new JWSInput(response.getRefreshToken()).getHeader();
    assertEquals("HS256", header.getAlgorithm().name());
    assertEquals("JWT", header.getType());
    assertNull(header.getContentType());
    AccessToken token = oauth.verifyToken(response.getAccessToken());
    assertEquals(findUserByUsername(adminClient.realm("test"), "test-user@localhost").getId(), token.getSubject());
    assertNotEquals("test-user@localhost", token.getSubject());
    assertEquals(sessionId, token.getSessionState());
    JWSInput idToken = new JWSInput(response.getIdToken());
    ObjectMapper mapper = JsonSerialization.mapper;
    JsonParser parser = mapper.getFactory().createParser(idToken.readContentAsString());
    TreeNode treeNode = mapper.readTree(parser);
    String sid = ((TextNode) treeNode.get("sid")).asText();
    assertEquals(sessionId, sid);
    assertNull(token.getNbf());
    assertEquals(0, token.getNotBefore());
    assertNotNull(token.getIat());
    assertEquals(token.getIat().intValue(), token.getIssuedAt());
    assertNotNull(token.getExp());
    assertEquals(token.getExp().intValue(), token.getExpiration());
    assertEquals(1, token.getRealmAccess().getRoles().size());
    assertTrue(token.getRealmAccess().isUserInRole("user"));
    assertEquals(1, token.getResourceAccess(oauth.getClientId()).getRoles().size());
    assertTrue(token.getResourceAccess(oauth.getClientId()).isUserInRole("customer-user"));
    EventRepresentation event = events.expectCodeToToken(codeId, sessionId).assertEvent();
    assertEquals(token.getId(), event.getDetails().get(Details.TOKEN_ID));
    assertEquals(oauth.parseRefreshToken(response.getRefreshToken()).getId(), event.getDetails().get(Details.REFRESH_TOKEN_ID));
    assertEquals(sessionId, token.getSessionState());
}
Also used : OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) TreeNode(com.fasterxml.jackson.core.TreeNode) EventRepresentation(org.keycloak.representations.idm.EventRepresentation) TextNode(com.fasterxml.jackson.databind.node.TextNode) JWSInput(org.keycloak.jose.jws.JWSInput) JWSHeader(org.keycloak.jose.jws.JWSHeader) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) JsonParser(com.fasterxml.jackson.core.JsonParser) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 27 with AccessToken

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

the class OIDCProtocolMappersTest method testUserRolesMovedFromAccessTokenProperties.

// Test to update protocolMappers to not have roles on the default position (realm_access and resource_access properties)
@Test
@AuthServerContainerExclude(AuthServer.REMOTE)
public void testUserRolesMovedFromAccessTokenProperties() throws Exception {
    RealmResource realm = adminClient.realm("test");
    ClientScopeResource rolesScope = ApiUtil.findClientScopeByName(realm, OIDCLoginProtocolFactory.ROLES_SCOPE);
    // Update builtin protocolMappers to put roles to different position (claim "custom.roles") for both realm and client roles
    ProtocolMapperRepresentation realmRolesMapper = null;
    ProtocolMapperRepresentation clientRolesMapper = null;
    for (ProtocolMapperRepresentation rep : rolesScope.getProtocolMappers().getMappers()) {
        if (OIDCLoginProtocolFactory.REALM_ROLES.equals(rep.getName())) {
            realmRolesMapper = rep;
        } else if (OIDCLoginProtocolFactory.CLIENT_ROLES.equals(rep.getName())) {
            clientRolesMapper = rep;
        }
    }
    String realmRolesTokenClaimOrig = realmRolesMapper.getConfig().get(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
    String clientRolesTokenClaimOrig = clientRolesMapper.getConfig().get(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME);
    realmRolesMapper.getConfig().put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, "custom.roles");
    rolesScope.getProtocolMappers().update(realmRolesMapper.getId(), realmRolesMapper);
    clientRolesMapper.getConfig().put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, "custom.roles");
    rolesScope.getProtocolMappers().update(clientRolesMapper.getId(), clientRolesMapper);
    // Create some hardcoded role mapper
    Response resp = rolesScope.getProtocolMappers().createMapper(createHardcodedRole("hard-realm", "hardcoded"));
    String hardcodedMapperId = ApiUtil.getCreatedId(resp);
    resp.close();
    try {
        OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password");
        AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
        // Assert roles are not on their original positions
        Assert.assertNull(accessToken.getRealmAccess());
        Assert.assertTrue(accessToken.getResourceAccess().isEmpty());
        // KEYCLOAK-8481 Assert that accessToken JSON doesn't have "realm_access" or "resource_access" fields in it
        String accessTokenJson = new String(new JWSInput(response.getAccessToken()).getContent(), StandardCharsets.UTF_8);
        Assert.assertFalse(accessTokenJson.contains("realm_access"));
        Assert.assertFalse(accessTokenJson.contains("resource_access"));
        // Assert both realm and client roles on the new position. Hardcoded role should be here as well
        Map<String, Object> cst1 = (Map<String, Object>) accessToken.getOtherClaims().get("custom");
        List<String> roles = (List<String>) cst1.get("roles");
        Assert.assertNames(roles, "offline_access", "user", "customer-user", "hardcoded", AccountRoles.VIEW_PROFILE, AccountRoles.MANAGE_ACCOUNT, AccountRoles.MANAGE_ACCOUNT_LINKS);
        // Assert audience
        Assert.assertNames(Arrays.asList(accessToken.getAudience()), "account");
    } finally {
        // Revert
        rolesScope.getProtocolMappers().delete(hardcodedMapperId);
        realmRolesMapper.getConfig().put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, realmRolesTokenClaimOrig);
        rolesScope.getProtocolMappers().update(realmRolesMapper.getId(), realmRolesMapper);
        clientRolesMapper.getConfig().put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, clientRolesTokenClaimOrig);
        rolesScope.getProtocolMappers().update(clientRolesMapper.getId(), clientRolesMapper);
    }
}
Also used : OAuthClient(org.keycloak.testsuite.util.OAuthClient) RealmResource(org.keycloak.admin.client.resource.RealmResource) Matchers.isEmptyOrNullString(org.hamcrest.Matchers.isEmptyOrNullString) JWSInput(org.keycloak.jose.jws.JWSInput) Response(javax.ws.rs.core.Response) ClientScopeResource(org.keycloak.admin.client.resource.ClientScopeResource) AccessToken(org.keycloak.representations.AccessToken) ProtocolMapperRepresentation(org.keycloak.representations.idm.ProtocolMapperRepresentation) List(java.util.List) Map(java.util.Map) HashMap(java.util.HashMap) AuthServerContainerExclude(org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test)

Example 28 with AccessToken

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

the class OIDCProtocolMappersTest method executeTokenMappersOnDynamicScopes.

@Test
@EnableFeature(value = Profile.Feature.DYNAMIC_SCOPES, skipRestart = true)
public void executeTokenMappersOnDynamicScopes() {
    ClientResource clientResource = findClientResourceByClientId(adminClient.realm("test"), "test-app");
    ClientScopeRepresentation scopeRep = new ClientScopeRepresentation();
    scopeRep.setName("dyn-scope-with-mapper");
    scopeRep.setProtocol("openid-connect");
    scopeRep.setAttributes(new HashMap<String, String>() {

        {
            put(ClientScopeModel.IS_DYNAMIC_SCOPE, "true");
            put(ClientScopeModel.DYNAMIC_SCOPE_REGEXP, "dyn-scope-with-mapper:*");
        }
    });
    // create the attribute mapper
    ProtocolMapperRepresentation protocolMapperRepresentation = createHardcodedClaim("dynamic-scope-hardcoded-mapper", "hardcoded-foo", "hardcoded-bar", "String", true, true);
    scopeRep.setProtocolMappers(Collections.singletonList(protocolMapperRepresentation));
    try (Response resp = adminClient.realm("test").clientScopes().create(scopeRep)) {
        assertEquals(201, resp.getStatus());
        String clientScopeId = ApiUtil.getCreatedId(resp);
        getCleanup().addClientScopeId(clientScopeId);
        clientResource.addOptionalClientScope(clientScopeId);
    }
    oauth.scope("openid dyn-scope-with-mapper:value");
    OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password");
    IDToken idToken = oauth.verifyIDToken(response.getIdToken());
    AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
    assertNotNull(idToken.getOtherClaims());
    assertNotNull(idToken.getOtherClaims().get("hardcoded-foo"));
    assertTrue(idToken.getOtherClaims().get("hardcoded-foo") instanceof String);
    assertEquals("hardcoded-bar", idToken.getOtherClaims().get("hardcoded-foo"));
    assertNotNull(accessToken.getOtherClaims());
    assertNotNull(accessToken.getOtherClaims().get("hardcoded-foo"));
    assertTrue(accessToken.getOtherClaims().get("hardcoded-foo") instanceof String);
    assertEquals("hardcoded-bar", accessToken.getOtherClaims().get("hardcoded-foo"));
}
Also used : Response(javax.ws.rs.core.Response) OAuthClient(org.keycloak.testsuite.util.OAuthClient) AccessToken(org.keycloak.representations.AccessToken) ProtocolMapperRepresentation(org.keycloak.representations.idm.ProtocolMapperRepresentation) ClientScopeRepresentation(org.keycloak.representations.idm.ClientScopeRepresentation) ClientResource(org.keycloak.admin.client.resource.ClientResource) IDToken(org.keycloak.representations.IDToken) Matchers.isEmptyOrNullString(org.hamcrest.Matchers.isEmptyOrNullString) AbstractKeycloakTest(org.keycloak.testsuite.AbstractKeycloakTest) Test(org.junit.Test) EnableFeature(org.keycloak.testsuite.arquillian.annotation.EnableFeature)

Example 29 with AccessToken

use of org.keycloak.representations.AccessToken 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 30 with AccessToken

use of org.keycloak.representations.AccessToken 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)

Aggregations

AccessToken (org.keycloak.representations.AccessToken)230 Test (org.junit.Test)129 OAuthClient (org.keycloak.testsuite.util.OAuthClient)104 AbstractKeycloakTest (org.keycloak.testsuite.AbstractKeycloakTest)54 RefreshToken (org.keycloak.representations.RefreshToken)45 AuthorizationResponse (org.keycloak.representations.idm.authorization.AuthorizationResponse)37 JWSInput (org.keycloak.jose.jws.JWSInput)29 Permission (org.keycloak.representations.idm.authorization.Permission)28 EventRepresentation (org.keycloak.representations.idm.EventRepresentation)27 Response (javax.ws.rs.core.Response)26 ClientResource (org.keycloak.admin.client.resource.ClientResource)22 VerificationException (org.keycloak.common.VerificationException)19 ClientRepresentation (org.keycloak.representations.idm.ClientRepresentation)19 AccessTokenResponse (org.keycloak.representations.AccessTokenResponse)18 IDToken (org.keycloak.representations.IDToken)18 AuthorizationRequest (org.keycloak.representations.idm.authorization.AuthorizationRequest)17 IOException (java.io.IOException)15 AuthzClient (org.keycloak.authorization.client.AuthzClient)15 ResourceRepresentation (org.keycloak.representations.idm.authorization.ResourceRepresentation)14 ArrayList (java.util.ArrayList)13