use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class ClientPoliciesTest method testSecureSigningAlgorithmForSignedJwtEnforceExecutorWithSecureAlg.
@Test
public void testSecureSigningAlgorithmForSignedJwtEnforceExecutorWithSecureAlg() throws Exception {
// register profiles
String json = (new ClientProfilesBuilder()).addProfile((new ClientProfileBuilder()).createProfile(PROFILE_NAME, "Ensimmainen Profiili").addExecutor(SecureSigningAlgorithmForSignedJwtExecutorFactory.PROVIDER_ID, createSecureSigningAlgorithmForSignedJwtEnforceExecutorConfig(Boolean.TRUE)).toRepresentation()).toString();
updateProfiles(json);
// register policies
String roleAlphaName = "sample-client-role-alpha";
String roleZetaName = "sample-client-role-zeta";
String roleCommonName = "sample-client-role-common";
json = (new ClientPoliciesBuilder()).addPolicy((new ClientPolicyBuilder()).createPolicy(POLICY_NAME, "Den Forste Politikken", Boolean.TRUE).addCondition(ClientRolesConditionFactory.PROVIDER_ID, createClientRolesConditionConfig(Arrays.asList(roleAlphaName, roleZetaName))).addProfile(PROFILE_NAME).toRepresentation()).toString();
updatePolicies(json);
// create a client with client role
String clientId = generateSuffixedName(CLIENT_NAME);
String cid = createClientByAdmin(clientId, (ClientRepresentation clientRep) -> {
clientRep.setSecret("secret");
clientRep.setClientAuthenticatorType(JWTClientAuthenticator.PROVIDER_ID);
clientRep.setAttributes(new HashMap<>());
clientRep.getAttributes().put(OIDCConfigAttributes.TOKEN_ENDPOINT_AUTH_SIGNING_ALG, org.keycloak.crypto.Algorithm.ES256);
});
adminClient.realm(REALM_NAME).clients().get(cid).roles().create(RoleBuilder.create().name(roleAlphaName).build());
adminClient.realm(REALM_NAME).clients().get(cid).roles().create(RoleBuilder.create().name(roleCommonName).build());
ClientResource clientResource = ApiUtil.findClientByClientId(adminClient.realm(REALM_NAME), clientId);
ClientRepresentation clientRep = clientResource.toRepresentation();
KeyPair keyPair = setupJwksUrl(org.keycloak.crypto.Algorithm.ES256, clientRep, clientResource);
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String signedJwt = createSignedRequestToken(clientId, privateKey, publicKey, org.keycloak.crypto.Algorithm.ES256);
oauth.clientId(clientId);
oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD);
EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent();
String sessionId = loginEvent.getSessionId();
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
// obtain access token
OAuthClient.AccessTokenResponse response = doAccessTokenRequestWithSignedJWT(code, signedJwt);
assertEquals(200, response.getStatusCode());
oauth.verifyToken(response.getAccessToken());
RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken());
assertEquals(sessionId, refreshToken.getSessionState());
assertEquals(sessionId, refreshToken.getSessionState());
events.expectCodeToToken(loginEvent.getDetails().get(Details.CODE_ID), loginEvent.getSessionId()).client(clientId).detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID).assertEvent();
// refresh token
signedJwt = createSignedRequestToken(clientId, privateKey, publicKey, org.keycloak.crypto.Algorithm.ES256);
OAuthClient.AccessTokenResponse refreshedResponse = doRefreshTokenRequestWithSignedJWT(response.getRefreshToken(), signedJwt);
assertEquals(200, refreshedResponse.getStatusCode());
// introspect token
signedJwt = createSignedRequestToken(clientId, privateKey, publicKey, org.keycloak.crypto.Algorithm.ES256);
HttpResponse tokenIntrospectionResponse = doTokenIntrospectionWithSignedJWT("access_token", refreshedResponse.getAccessToken(), signedJwt);
assertEquals(200, tokenIntrospectionResponse.getStatusLine().getStatusCode());
// revoke token
signedJwt = createSignedRequestToken(clientId, privateKey, publicKey, org.keycloak.crypto.Algorithm.ES256);
HttpResponse revokeTokenResponse = doTokenRevokeWithSignedJWT("refresh_toke", refreshedResponse.getRefreshToken(), signedJwt);
assertEquals(200, revokeTokenResponse.getStatusLine().getStatusCode());
signedJwt = createSignedRequestToken(clientId, privateKey, publicKey, org.keycloak.crypto.Algorithm.ES256);
OAuthClient.AccessTokenResponse tokenRes = doRefreshTokenRequestWithSignedJWT(refreshedResponse.getRefreshToken(), signedJwt);
assertEquals(400, tokenRes.getStatusCode());
assertEquals(OAuthErrorException.INVALID_GRANT, tokenRes.getError());
// logout
signedJwt = createSignedRequestToken(clientId, privateKey, publicKey, org.keycloak.crypto.Algorithm.ES256);
HttpResponse logoutResponse = doLogoutWithSignedJWT(refreshedResponse.getRefreshToken(), signedJwt);
assertEquals(204, logoutResponse.getStatusLine().getStatusCode());
}
use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class OIDCScopeTest method testRefreshTokenWithConsentRequired.
@Test
// TODO remove this (KEYCLOAK-16228)
@DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true)
public void testRefreshTokenWithConsentRequired() {
// Login with consentRequired
oauth.clientId("third-party");
oauth.doLoginGrant("john", "password");
grantPage.assertCurrent();
grantPage.assertGrants(OAuthGrantPage.PROFILE_CONSENT_TEXT, OAuthGrantPage.EMAIL_CONSENT_TEXT, OAuthGrantPage.ROLES_CONSENT_TEXT);
grantPage.accept();
EventRepresentation loginEvent = events.expectLogin().user(userId).client("third-party").detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED).assertEvent();
Tokens tokens = sendTokenRequest(loginEvent, userId, "openid email profile", "third-party");
IDToken idToken = tokens.idToken;
RefreshToken refreshToken1 = oauth.parseRefreshToken(tokens.refreshToken);
assertProfile(idToken, true);
assertEmail(idToken, true);
assertAddress(idToken, false);
assertPhone(idToken, false);
// Ensure that I can refresh token
OAuthClient.AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(tokens.refreshToken, "password");
Assert.assertEquals(200, refreshResponse.getStatusCode());
idToken = oauth.verifyIDToken(refreshResponse.getIdToken());
assertProfile(idToken, true);
assertEmail(idToken, true);
assertAddress(idToken, false);
assertPhone(idToken, false);
events.expectRefresh(refreshToken1.getId(), idToken.getSessionState()).user(userId).client("third-party").assertEvent();
// Go to applications in account mgmt and revoke consent
accountAppsPage.open();
events.clear();
accountAppsPage.revokeGrant("third-party");
events.expect(EventType.REVOKE_GRANT).client("account").user(userId).detail(Details.REVOKED_CLIENT, "third-party").assertEvent();
// Ensure I can't refresh anymore
refreshResponse = oauth.doRefreshTokenRequest(refreshResponse.getRefreshToken(), "password");
assertEquals(400, refreshResponse.getStatusCode());
events.expectRefresh(refreshToken1.getId(), idToken.getSessionState()).client("third-party").user(userId).removeDetail(Details.TOKEN_ID).removeDetail(Details.REFRESH_TOKEN_ID).removeDetail(Details.UPDATED_REFRESH_TOKEN_ID).error("invalid_token").assertEvent();
}
use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class OfflineTokenTest method offlineTokenRequest.
private void offlineTokenRequest(String expectedRefreshAlg, String expectedAccessAlg, String expectedIdTokenAlg) throws Exception {
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.clientId("offline-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
JWSHeader header = null;
String idToken = tokenResponse.getIdToken();
String accessToken = tokenResponse.getAccessToken();
String refreshToken = tokenResponse.getRefreshToken();
if (idToken != null) {
header = new JWSInput(idToken).getHeader();
assertEquals(expectedIdTokenAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
if (accessToken != null) {
header = new JWSInput(accessToken).getHeader();
assertEquals(expectedAccessAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
if (refreshToken != null) {
header = new JWSInput(refreshToken).getHeader();
assertEquals(expectedRefreshAlg, header.getAlgorithm().name());
assertEquals("JWT", header.getType());
assertNull(header.getContentType());
}
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 decode 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 offlineTokenRemoveClientWithTokens.
// KEYCLOAK-4525
@Test
// TODO remove this (KEYCLOAK-16228)
@DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true)
public void offlineTokenRemoveClientWithTokens() throws Exception {
// Create new client
RealmResource appRealm = adminClient.realm("test");
ClientRepresentation clientRep = ClientBuilder.create().clientId("offline-client-2").id(KeycloakModelUtils.generateId()).directAccessGrants().secret("secret1").build();
appRealm.clients().create(clientRep);
// Direct grant login requesting offline token
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.clientId("offline-client-2");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "test-user@localhost", "password");
Assert.assertNull(tokenResponse.getErrorDescription());
AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken());
String offlineTokenString = tokenResponse.getRefreshToken();
RefreshToken offlineToken = oauth.parseRefreshToken(offlineTokenString);
events.expectLogin().client("offline-client-2").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();
// Go to account mgmt applications page
applicationsPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=applications").assertEvent();
assertTrue(applicationsPage.isCurrent());
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
assertTrue(apps.containsKey("offline-client-2"));
Assert.assertEquals("Offline Token", apps.get("offline-client-2").getAdditionalGrants().get(0));
// Now remove the client
ClientResource offlineTokenClient2 = ApiUtil.findClientByClientId(appRealm, "offline-client-2");
offlineTokenClient2.remove();
// Go to applications page and see offline-client not anymore
applicationsPage.open();
apps = applicationsPage.getApplications();
assertFalse(apps.containsKey("offline-client-2"));
// Login as admin and see consents of user
UserResource user = ApiUtil.findUserByUsernameId(appRealm, "test-user@localhost");
List<Map<String, Object>> consents = user.getConsents();
for (Map<String, Object> consent : consents) {
assertNotEquals(consent.get("clientId"), "offline-client-2");
}
}
use of org.keycloak.representations.RefreshToken in project keycloak by keycloak.
the class OfflineTokenTest method offlineTokenDirectGrantFlow.
@Test
public void offlineTokenDirectGrantFlow() throws Exception {
oauth.scope(OAuth2Constants.OFFLINE_ACCESS);
oauth.clientId("offline-client");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "test-user@localhost", "password");
Assert.assertNull(tokenResponse.getErrorDescription());
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());
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
// Assert same token can be refreshed again
testRefreshWithOfflineToken(token, offlineToken, offlineTokenString, token.getSessionState(), userId);
}
Aggregations