diff --git a/adapters/oidc/adapter-core/pom.xml b/adapters/oidc/adapter-core/pom.xml index efcbf3a5d2..6d4e8a1921 100755 --- a/adapters/oidc/adapter-core/pom.xml +++ b/adapters/oidc/adapter-core/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java index 63ea79e65b..dd0d39ba78 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AdapterDeploymentContext.java @@ -342,6 +342,12 @@ public class AdapterDeploymentContext { return delegate.getNotBefore(); } + @Override + public void updateNotBefore(int notBefore) { + delegate.setNotBefore(notBefore); + getPublicKeyLocator().reset(this); + } + @Override public void setExposeToken(boolean exposeToken) { delegate.setExposeToken(exposeToken); @@ -446,6 +452,16 @@ public class AdapterDeploymentContext { public int getMinTimeBetweenJwksRequests() { return delegate.getMinTimeBetweenJwksRequests(); } + + @Override + public int getPublicKeyCacheTtl() { + return delegate.getPublicKeyCacheTtl(); + } + + @Override + public void setPublicKeyCacheTtl(int publicKeyCacheTtl) { + delegate.setPublicKeyCacheTtl(publicKeyCacheTtl); + } } protected KeycloakUriBuilder getBaseBuilder(HttpFacade facade, String base) { diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/HttpAdapterUtils.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/HttpAdapterUtils.java index 3e0f36dee7..b7877964a0 100644 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/HttpAdapterUtils.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/HttpAdapterUtils.java @@ -46,14 +46,7 @@ public class HttpAdapterUtils { } InputStream is = entity.getContent(); try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - int c; - while ((c = is.read()) != -1) { - os.write(c); - } - byte[] bytes = os.toByteArray(); - String json = new String(bytes); - return JsonSerialization.readValue(json, clazz); + return JsonSerialization.readValue(is, clazz); } finally { try { is.close(); diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java index 1071b710fc..b9ee4c6f05 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeployment.java @@ -81,6 +81,7 @@ public class KeycloakDeployment { protected volatile int notBefore; protected int tokenMinimumTimeToLive; protected int minTimeBetweenJwksRequests; + protected int publicKeyCacheTtl; private PolicyEnforcer policyEnforcer; public KeycloakDeployment() { @@ -328,6 +329,11 @@ public class KeycloakDeployment { this.notBefore = notBefore; } + public void updateNotBefore(int notBefore) { + this.notBefore = notBefore; + getPublicKeyLocator().reset(this); + } + public boolean isAlwaysRefreshToken() { return alwaysRefreshToken; } @@ -384,6 +390,14 @@ public class KeycloakDeployment { this.minTimeBetweenJwksRequests = minTimeBetweenJwksRequests; } + public int getPublicKeyCacheTtl() { + return publicKeyCacheTtl; + } + + public void setPublicKeyCacheTtl(int publicKeyCacheTtl) { + this.publicKeyCacheTtl = publicKeyCacheTtl; + } + public void setPolicyEnforcer(PolicyEnforcer policyEnforcer) { this.policyEnforcer = policyEnforcer; } diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java index f6c6f5ea12..85b19ca538 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java @@ -105,6 +105,7 @@ public class KeycloakDeploymentBuilder { deployment.setRegisterNodePeriod(adapterConfig.getRegisterNodePeriod()); deployment.setTokenMinimumTimeToLive(adapterConfig.getTokenMinimumTimeToLive()); deployment.setMinTimeBetweenJwksRequests(adapterConfig.getMinTimeBetweenJwksRequests()); + deployment.setPublicKeyCacheTtl(adapterConfig.getPublicKeyCacheTtl()); if (realmKeyPem == null && adapterConfig.isBearerOnly() && adapterConfig.getAuthServerUrl() == null) { throw new IllegalArgumentException("For bearer auth, you must set the realm-public-key or auth-server-url"); diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java index 109361f1df..e8f534492a 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java @@ -357,7 +357,7 @@ public class OAuthRequestAuthenticator { return challenge(403, OIDCAuthenticationError.Reason.INVALID_TOKEN, null); } if (tokenResponse.getNotBeforePolicy() > deployment.getNotBefore()) { - deployment.setNotBefore(tokenResponse.getNotBeforePolicy()); + deployment.updateNotBefore(tokenResponse.getNotBeforePolicy()); } if (token.getIssuedAt() < deployment.getNotBefore()) { log.error("Stale token"); diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java index 9a291c071b..b4d017bc57 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/PreAuthActionsHandler.java @@ -155,7 +155,7 @@ public class PreAuthActionsHandler { } else { log.debugf("logout of all sessions for application '%s'", action.getResource()); if (action.getNotBefore() > deployment.getNotBefore()) { - deployment.setNotBefore(action.getNotBefore()); + deployment.updateNotBefore(action.getNotBefore()); } userSessionManagement.logoutAll(); } @@ -177,7 +177,7 @@ public class PreAuthActionsHandler { } PushNotBeforeAction action = JsonSerialization.readValue(token.getContent(), PushNotBeforeAction.class); if (!validateAction(action)) return; - deployment.setNotBefore(action.getNotBefore()); + deployment.updateNotBefore(action.getNotBefore()); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java index 39a3f1e59f..c70bce1261 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java @@ -144,7 +144,7 @@ public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext } if (response.getNotBeforePolicy() > deployment.getNotBefore()) { - deployment.setNotBefore(response.getNotBeforePolicy()); + deployment.updateNotBefore(response.getNotBeforePolicy()); } this.token = token; diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/HardcodedPublicKeyLocator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/HardcodedPublicKeyLocator.java index 2aa51a44c3..9e285a2c8c 100644 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/HardcodedPublicKeyLocator.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/HardcodedPublicKeyLocator.java @@ -37,4 +37,9 @@ public class HardcodedPublicKeyLocator implements PublicKeyLocator { public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) { return publicKey; } + + @Override + public void reset(KeycloakDeployment deployment) { + + } } diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/JWKPublicKeyLocator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/JWKPublicKeyLocator.java index 9305f32a49..22c6d7dc21 100644 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/JWKPublicKeyLocator.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/JWKPublicKeyLocator.java @@ -25,7 +25,6 @@ import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.common.util.Time; import org.keycloak.jose.jwk.JSONWebKeySet; import org.keycloak.jose.jwk.JWK; -import org.keycloak.jose.jws.JWSInput; import org.keycloak.util.JWKSUtils; import java.security.PublicKey; @@ -48,30 +47,43 @@ public class JWKPublicKeyLocator implements PublicKeyLocator { @Override public PublicKey getPublicKey(String kid, KeycloakDeployment deployment) { int minTimeBetweenRequests = deployment.getMinTimeBetweenJwksRequests(); + int publicKeyCacheTtl = deployment.getPublicKeyCacheTtl(); + int currentTime = Time.currentTime(); // Check if key is in cache. - PublicKey publicKey = currentKeys.get(kid); + PublicKey publicKey = lookupCachedKey(publicKeyCacheTtl, currentTime, kid); if (publicKey != null) { return publicKey; } - int currentTime = Time.currentTime(); - // Check if we are allowed to send request - if (currentTime > lastRequestTime + minTimeBetweenRequests) { - synchronized (this) { - currentTime = Time.currentTime(); - if (currentTime > lastRequestTime + minTimeBetweenRequests) { - sendRequest(deployment); - lastRequestTime = currentTime; - } else { - log.debugf("Won't send request to realm jwks url. Last request time was %d", lastRequestTime); - } + synchronized (this) { + currentTime = Time.currentTime(); + if (currentTime > lastRequestTime + minTimeBetweenRequests) { + sendRequest(deployment); + lastRequestTime = currentTime; + } else { + log.debugf("Won't send request to realm jwks url. Last request time was %d", lastRequestTime); } + + return lookupCachedKey(publicKeyCacheTtl, currentTime, kid); } + } - return currentKeys.get(kid); + @Override + public void reset(KeycloakDeployment deployment) { + sendRequest(deployment); + lastRequestTime = Time.currentTime(); + } + + + private PublicKey lookupCachedKey(int publicKeyCacheTtl, int currentTime, String kid) { + if (lastRequestTime + publicKeyCacheTtl > currentTime) { + return currentKeys.get(kid); + } else { + return null; + } } diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/PublicKeyLocator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/PublicKeyLocator.java index 3efd90a3b7..096f75f042 100644 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/PublicKeyLocator.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/rotation/PublicKeyLocator.java @@ -34,4 +34,11 @@ public interface PublicKeyLocator { */ PublicKey getPublicKey(String kid, KeycloakDeployment deployment); + /** + * Reset the state of locator (eg. clear the cached keys) + * + * @param deployment + */ + void reset(KeycloakDeployment deployment); + } diff --git a/adapters/oidc/adapter-core/src/test/java/org/keycloak/adapters/KeycloakDeploymentBuilderTest.java b/adapters/oidc/adapter-core/src/test/java/org/keycloak/adapters/KeycloakDeploymentBuilderTest.java index 77eb475bf6..233c1ed2f0 100644 --- a/adapters/oidc/adapter-core/src/test/java/org/keycloak/adapters/KeycloakDeploymentBuilderTest.java +++ b/adapters/oidc/adapter-core/src/test/java/org/keycloak/adapters/KeycloakDeploymentBuilderTest.java @@ -69,6 +69,7 @@ public class KeycloakDeploymentBuilderTest { assertEquals("email", deployment.getPrincipalAttribute()); assertEquals(10, deployment.getTokenMinimumTimeToLive()); assertEquals(20, deployment.getMinTimeBetweenJwksRequests()); + assertEquals(120, deployment.getPublicKeyCacheTtl()); } @Test @@ -78,6 +79,7 @@ public class KeycloakDeploymentBuilderTest { assertTrue(deployment.getPublicKeyLocator() instanceof JWKPublicKeyLocator); assertEquals(10, deployment.getMinTimeBetweenJwksRequests()); + assertEquals(86400, deployment.getPublicKeyCacheTtl()); } @Test diff --git a/adapters/oidc/adapter-core/src/test/resources/keycloak.json b/adapters/oidc/adapter-core/src/test/resources/keycloak.json index a8afd22cf2..9f0a204826 100644 --- a/adapters/oidc/adapter-core/src/test/resources/keycloak.json +++ b/adapters/oidc/adapter-core/src/test/resources/keycloak.json @@ -30,5 +30,6 @@ "token-store": "cookie", "principal-attribute": "email", "token-minimum-time-to-live": 10, - "min-time-between-jwks-requests": 20 + "min-time-between-jwks-requests": 20, + "public-key-cache-ttl": 120 } \ No newline at end of file diff --git a/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml b/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml index 1f64c36fca..fa0c29bf41 100755 --- a/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml +++ b/adapters/oidc/as7-eap6/as7-adapter-spi/pom.xml @@ -21,7 +21,7 @@ keycloak-as7-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/oidc/as7-eap6/as7-adapter/pom.xml b/adapters/oidc/as7-eap6/as7-adapter/pom.xml index 5f21d6d427..67ad24b51b 100755 --- a/adapters/oidc/as7-eap6/as7-adapter/pom.xml +++ b/adapters/oidc/as7-eap6/as7-adapter/pom.xml @@ -21,7 +21,7 @@ keycloak-as7-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/oidc/as7-eap6/as7-subsystem/pom.xml b/adapters/oidc/as7-eap6/as7-subsystem/pom.xml index 972903fcde..4b3369d65b 100755 --- a/adapters/oidc/as7-eap6/as7-subsystem/pom.xml +++ b/adapters/oidc/as7-eap6/as7-subsystem/pom.xml @@ -21,7 +21,7 @@ org.keycloak keycloak-as7-integration-pom - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/adapters/oidc/as7-eap6/pom.xml b/adapters/oidc/as7-eap6/pom.xml index 626c1a10f3..e8c50f5320 100755 --- a/adapters/oidc/as7-eap6/pom.xml +++ b/adapters/oidc/as7-eap6/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak AS7 / JBoss EAP 6 Integration diff --git a/adapters/oidc/installed/pom.xml b/adapters/oidc/installed/pom.xml index 2cff21abc9..1e88bae934 100755 --- a/adapters/oidc/installed/pom.xml +++ b/adapters/oidc/installed/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/jaxrs-oauth-client/pom.xml b/adapters/oidc/jaxrs-oauth-client/pom.xml index feca253cab..d91119251b 100755 --- a/adapters/oidc/jaxrs-oauth-client/pom.xml +++ b/adapters/oidc/jaxrs-oauth-client/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/jetty/jetty-core/pom.xml b/adapters/oidc/jetty/jetty-core/pom.xml index d6de06173d..0a626191a7 100755 --- a/adapters/oidc/jetty/jetty-core/pom.xml +++ b/adapters/oidc/jetty/jetty-core/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/oidc/jetty/jetty8.1/pom.xml b/adapters/oidc/jetty/jetty8.1/pom.xml index 5d9bfc32c3..b966d60e55 100755 --- a/adapters/oidc/jetty/jetty8.1/pom.xml +++ b/adapters/oidc/jetty/jetty8.1/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/oidc/jetty/jetty9.1/pom.xml b/adapters/oidc/jetty/jetty9.1/pom.xml index dbe08dd775..d017e24dda 100755 --- a/adapters/oidc/jetty/jetty9.1/pom.xml +++ b/adapters/oidc/jetty/jetty9.1/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/oidc/jetty/jetty9.2/pom.xml b/adapters/oidc/jetty/jetty9.2/pom.xml index 430a02d0fa..20e7afaa48 100755 --- a/adapters/oidc/jetty/jetty9.2/pom.xml +++ b/adapters/oidc/jetty/jetty9.2/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/oidc/jetty/jetty9.3/pom.xml b/adapters/oidc/jetty/jetty9.3/pom.xml index 9596a00bf0..b1ec1ff804 100644 --- a/adapters/oidc/jetty/jetty9.3/pom.xml +++ b/adapters/oidc/jetty/jetty9.3/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/oidc/jetty/pom.xml b/adapters/oidc/jetty/pom.xml index 6933fe78ab..d4b2f4bfda 100755 --- a/adapters/oidc/jetty/pom.xml +++ b/adapters/oidc/jetty/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak Jetty Integration diff --git a/adapters/oidc/js/pom.xml b/adapters/oidc/js/pom.xml index 5d1f812101..026d8e4aa2 100755 --- a/adapters/oidc/js/pom.xml +++ b/adapters/oidc/js/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/js/src/main/resources/keycloak.js b/adapters/oidc/js/src/main/resources/keycloak.js index ba27ed0cfc..70b318ec4b 100755 --- a/adapters/oidc/js/src/main/resources/keycloak.js +++ b/adapters/oidc/js/src/main/resources/keycloak.js @@ -846,14 +846,15 @@ kc.clearToken(); } - for (var i = loginIframe.callbackList.length - 1; i >= 0; --i) { - var promise = loginIframe.callbackList[i]; + var callbacks = loginIframe.callbackList.splice(0, loginIframe.callbackList.length); + + for (var i = callbacks.length - 1; i >= 0; --i) { + var promise = callbacks[i]; if (event.data == "unchanged") { promise.setSuccess(); } else { promise.setError(); } - loginIframe.callbackList.splice(i, 1); } }; diff --git a/adapters/oidc/js/src/main/resources/login-status-iframe.html b/adapters/oidc/js/src/main/resources/login-status-iframe.html index 6bea92ade4..f941663e4f 100755 --- a/adapters/oidc/js/src/main/resources/login-status-iframe.html +++ b/adapters/oidc/js/src/main/resources/login-status-iframe.html @@ -35,14 +35,14 @@ req.open('GET', url, true); req.onreadystatechange = function () { - if (req.readyState == 4) { - if (req.status == 204) { + if (req.readyState === 4) { + if (req.status === 204) { init = { clientId: clientId, origin: origin } callback('unchanged'); - } else if (req.status = 404) { + } else if (req.status === 404) { callback('changed'); } else { callback('error'); @@ -52,8 +52,8 @@ req.send(); } else { - if (clientId == init.clientId && origin == init.origin) { - if (sessionState == cookie) { + if (clientId === init.clientId && origin === init.origin) { + if (sessionState === cookie) { callback('unchanged'); } else { callback('changed'); @@ -71,7 +71,7 @@ for(var i=0; i - \ No newline at end of file + diff --git a/adapters/oidc/osgi-adapter/pom.xml b/adapters/oidc/osgi-adapter/pom.xml index bfc078b577..a2f33f9110 100755 --- a/adapters/oidc/osgi-adapter/pom.xml +++ b/adapters/oidc/osgi-adapter/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/pom.xml b/adapters/oidc/pom.xml index cc51e5317d..4c7d60e116 100755 --- a/adapters/oidc/pom.xml +++ b/adapters/oidc/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml Keycloak OIDC Client Adapter Modules diff --git a/adapters/oidc/servlet-filter/pom.xml b/adapters/oidc/servlet-filter/pom.xml index 2371c34ccc..5e1f89851b 100755 --- a/adapters/oidc/servlet-filter/pom.xml +++ b/adapters/oidc/servlet-filter/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/servlet-oauth-client/pom.xml b/adapters/oidc/servlet-oauth-client/pom.xml index 46efa50d87..3928311da5 100755 --- a/adapters/oidc/servlet-oauth-client/pom.xml +++ b/adapters/oidc/servlet-oauth-client/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/spring-boot/pom.xml b/adapters/oidc/spring-boot/pom.xml index 0553fb2339..ed6e9c17c7 100755 --- a/adapters/oidc/spring-boot/pom.xml +++ b/adapters/oidc/spring-boot/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/spring-security/pom.xml b/adapters/oidc/spring-security/pom.xml index 89092e85bc..af2c52ec4b 100755 --- a/adapters/oidc/spring-security/pom.xml +++ b/adapters/oidc/spring-security/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticatedActionsFilter.java b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticatedActionsFilter.java new file mode 100644 index 0000000000..a30a784807 --- /dev/null +++ b/adapters/oidc/spring-security/src/main/java/org/keycloak/adapters/springsecurity/filter/KeycloakAuthenticatedActionsFilter.java @@ -0,0 +1,90 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.adapters.springsecurity.filter; + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.keycloak.adapters.AdapterDeploymentContext; +import org.keycloak.adapters.AuthenticatedActionsHandler; +import org.keycloak.adapters.NodesRegistrationManagement; +import org.keycloak.adapters.OIDCHttpFacade; +import org.keycloak.adapters.spi.HttpFacade; +import org.keycloak.adapters.springsecurity.facade.SimpleHttpFacade; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.web.filter.GenericFilterBean; + +/** + * Exposes a Keycloak adapter {@link AuthenticatedActionsHandler} as a Spring Security filter. + * + * @author Scott Rossillo + * @version $Revision: 1 $ + */ +public class KeycloakAuthenticatedActionsFilter extends GenericFilterBean implements ApplicationContextAware { + + private static final Logger log = LoggerFactory.getLogger(KeycloakAuthenticatedActionsFilter.class); + + private final NodesRegistrationManagement management = new NodesRegistrationManagement(); + private ApplicationContext applicationContext; + private AdapterDeploymentContext deploymentContext; + + + public KeycloakAuthenticatedActionsFilter() { + super(); + } + + @Override + protected void initFilterBean() throws ServletException { + deploymentContext = applicationContext.getBean(AdapterDeploymentContext.class); + } + + @Override + public void destroy() { + log.debug("Unregistering deployment"); + management.stop(); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + HttpFacade facade = new SimpleHttpFacade((HttpServletRequest)request, (HttpServletResponse)response); + AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deploymentContext.resolveDeployment(facade), (OIDCHttpFacade)facade); + boolean handled = handler.handledRequest(); + if (handled) { + log.debug("Authenticated filter handled request: {}", ((HttpServletRequest) request).getRequestURI()); + } else { + chain.doFilter(request, response); + } + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } +} diff --git a/adapters/oidc/tomcat/pom.xml b/adapters/oidc/tomcat/pom.xml index e8495d4a78..99844f93ce 100755 --- a/adapters/oidc/tomcat/pom.xml +++ b/adapters/oidc/tomcat/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak Tomcat Integration diff --git a/adapters/oidc/tomcat/tomcat-core/pom.xml b/adapters/oidc/tomcat/tomcat-core/pom.xml index e048adac90..bce1604afa 100755 --- a/adapters/oidc/tomcat/tomcat-core/pom.xml +++ b/adapters/oidc/tomcat/tomcat-core/pom.xml @@ -21,7 +21,7 @@ keycloak-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/oidc/tomcat/tomcat6/pom.xml b/adapters/oidc/tomcat/tomcat6/pom.xml index cd0d6d9992..7976af6276 100755 --- a/adapters/oidc/tomcat/tomcat6/pom.xml +++ b/adapters/oidc/tomcat/tomcat6/pom.xml @@ -21,7 +21,7 @@ keycloak-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/oidc/tomcat/tomcat7/pom.xml b/adapters/oidc/tomcat/tomcat7/pom.xml index 8d36d61702..5f6435a977 100755 --- a/adapters/oidc/tomcat/tomcat7/pom.xml +++ b/adapters/oidc/tomcat/tomcat7/pom.xml @@ -21,7 +21,7 @@ keycloak-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/oidc/tomcat/tomcat8/pom.xml b/adapters/oidc/tomcat/tomcat8/pom.xml index edaf4dabc0..620ca5ce90 100755 --- a/adapters/oidc/tomcat/tomcat8/pom.xml +++ b/adapters/oidc/tomcat/tomcat8/pom.xml @@ -21,7 +21,7 @@ keycloak-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/oidc/undertow/pom.xml b/adapters/oidc/undertow/pom.xml index be1d44e9e1..8c84d416f0 100755 --- a/adapters/oidc/undertow/pom.xml +++ b/adapters/oidc/undertow/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/oidc/wildfly/pom.xml b/adapters/oidc/wildfly/pom.xml index 641dcc0e21..c762574209 100755 --- a/adapters/oidc/wildfly/pom.xml +++ b/adapters/oidc/wildfly/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak WildFly Integration diff --git a/adapters/oidc/wildfly/wf8-subsystem/pom.xml b/adapters/oidc/wildfly/wf8-subsystem/pom.xml index d8058180d9..cf5fe6886d 100755 --- a/adapters/oidc/wildfly/wf8-subsystem/pom.xml +++ b/adapters/oidc/wildfly/wf8-subsystem/pom.xml @@ -21,7 +21,7 @@ org.keycloak keycloak-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/adapters/oidc/wildfly/wildfly-adapter/pom.xml b/adapters/oidc/wildfly/wildfly-adapter/pom.xml index f20335b50f..1db02a3812 100755 --- a/adapters/oidc/wildfly/wildfly-adapter/pom.xml +++ b/adapters/oidc/wildfly/wildfly-adapter/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/oidc/wildfly/wildfly-subsystem/pom.xml b/adapters/oidc/wildfly/wildfly-subsystem/pom.xml index 76a7ee2ee2..16734b3f20 100755 --- a/adapters/oidc/wildfly/wildfly-subsystem/pom.xml +++ b/adapters/oidc/wildfly/wildfly-subsystem/pom.xml @@ -21,7 +21,7 @@ org.keycloak keycloak-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/adapters/pom.xml b/adapters/pom.xml index bb45f11809..a9179ed3da 100755 --- a/adapters/pom.xml +++ b/adapters/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml Keycloak Integration diff --git a/adapters/saml/as7-eap6/adapter/pom.xml b/adapters/saml/as7-eap6/adapter/pom.xml index c6098593e9..1fdec2a81e 100755 --- a/adapters/saml/as7-eap6/adapter/pom.xml +++ b/adapters/saml/as7-eap6/adapter/pom.xml @@ -21,7 +21,7 @@ keycloak-saml-eap-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/saml/as7-eap6/pom.xml b/adapters/saml/as7-eap6/pom.xml index f265e43714..f9c226cd94 100755 --- a/adapters/saml/as7-eap6/pom.xml +++ b/adapters/saml/as7-eap6/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak SAML EAP Integration diff --git a/adapters/saml/as7-eap6/subsystem/pom.xml b/adapters/saml/as7-eap6/subsystem/pom.xml index 1f97819360..1c0dd022b9 100755 --- a/adapters/saml/as7-eap6/subsystem/pom.xml +++ b/adapters/saml/as7-eap6/subsystem/pom.xml @@ -21,7 +21,7 @@ org.keycloak keycloak-saml-eap-integration-pom - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/adapters/saml/core-public/pom.xml b/adapters/saml/core-public/pom.xml index 00e5a3b1d7..821365209a 100755 --- a/adapters/saml/core-public/pom.xml +++ b/adapters/saml/core-public/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/saml/core/pom.xml b/adapters/saml/core/pom.xml index 98ad6040ac..66fbed7910 100755 --- a/adapters/saml/core/pom.xml +++ b/adapters/saml/core/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/saml/jetty/jetty-core/pom.xml b/adapters/saml/jetty/jetty-core/pom.xml index d735fa5e78..6a97fcec66 100755 --- a/adapters/saml/jetty/jetty-core/pom.xml +++ b/adapters/saml/jetty/jetty-core/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/saml/jetty/jetty8.1/pom.xml b/adapters/saml/jetty/jetty8.1/pom.xml index adb70cc36c..2f58cab189 100755 --- a/adapters/saml/jetty/jetty8.1/pom.xml +++ b/adapters/saml/jetty/jetty8.1/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/saml/jetty/jetty9.1/pom.xml b/adapters/saml/jetty/jetty9.1/pom.xml index 9c8e9e3b71..36e2c79fbb 100755 --- a/adapters/saml/jetty/jetty9.1/pom.xml +++ b/adapters/saml/jetty/jetty9.1/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/saml/jetty/jetty9.2/pom.xml b/adapters/saml/jetty/jetty9.2/pom.xml index 43833e8aa6..48f8ec93d1 100755 --- a/adapters/saml/jetty/jetty9.2/pom.xml +++ b/adapters/saml/jetty/jetty9.2/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/saml/jetty/jetty9.3/pom.xml b/adapters/saml/jetty/jetty9.3/pom.xml index 894f3291c4..27e146fb94 100644 --- a/adapters/saml/jetty/jetty9.3/pom.xml +++ b/adapters/saml/jetty/jetty9.3/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/saml/jetty/pom.xml b/adapters/saml/jetty/pom.xml index 7a06bb9832..5c195b7691 100755 --- a/adapters/saml/jetty/pom.xml +++ b/adapters/saml/jetty/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak SAML Jetty Integration diff --git a/adapters/saml/pom.xml b/adapters/saml/pom.xml index 6ce9bab825..71e4768142 100755 --- a/adapters/saml/pom.xml +++ b/adapters/saml/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml Keycloak SAML Client Adapter Modules diff --git a/adapters/saml/servlet-filter/pom.xml b/adapters/saml/servlet-filter/pom.xml index 0065ad0e3c..222238c6e5 100755 --- a/adapters/saml/servlet-filter/pom.xml +++ b/adapters/saml/servlet-filter/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/saml/tomcat/pom.xml b/adapters/saml/tomcat/pom.xml index 7d699d5f3e..d244ce4247 100755 --- a/adapters/saml/tomcat/pom.xml +++ b/adapters/saml/tomcat/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak SAML Tomcat Integration diff --git a/adapters/saml/tomcat/tomcat-core/pom.xml b/adapters/saml/tomcat/tomcat-core/pom.xml index 4654bdfe83..a195726bbc 100755 --- a/adapters/saml/tomcat/tomcat-core/pom.xml +++ b/adapters/saml/tomcat/tomcat-core/pom.xml @@ -21,7 +21,7 @@ keycloak-saml-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/saml/tomcat/tomcat6/pom.xml b/adapters/saml/tomcat/tomcat6/pom.xml index 218151daf7..1a75eb9327 100755 --- a/adapters/saml/tomcat/tomcat6/pom.xml +++ b/adapters/saml/tomcat/tomcat6/pom.xml @@ -21,7 +21,7 @@ keycloak-saml-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/saml/tomcat/tomcat7/pom.xml b/adapters/saml/tomcat/tomcat7/pom.xml index c2c0006937..f2e25862a9 100755 --- a/adapters/saml/tomcat/tomcat7/pom.xml +++ b/adapters/saml/tomcat/tomcat7/pom.xml @@ -21,7 +21,7 @@ keycloak-saml-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/saml/tomcat/tomcat8/pom.xml b/adapters/saml/tomcat/tomcat8/pom.xml index e292c36d4b..5d4e8b883e 100755 --- a/adapters/saml/tomcat/tomcat8/pom.xml +++ b/adapters/saml/tomcat/tomcat8/pom.xml @@ -21,7 +21,7 @@ keycloak-saml-tomcat-integration-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/adapters/saml/undertow/pom.xml b/adapters/saml/undertow/pom.xml index e81f6677e7..5c51f9f534 100755 --- a/adapters/saml/undertow/pom.xml +++ b/adapters/saml/undertow/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/saml/wildfly/pom.xml b/adapters/saml/wildfly/pom.xml index 441d734b54..65e9ecb16c 100755 --- a/adapters/saml/wildfly/pom.xml +++ b/adapters/saml/wildfly/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak SAML Wildfly Integration diff --git a/adapters/saml/wildfly/wildfly-adapter/pom.xml b/adapters/saml/wildfly/wildfly-adapter/pom.xml index e849beedaa..d18013a5df 100755 --- a/adapters/saml/wildfly/wildfly-adapter/pom.xml +++ b/adapters/saml/wildfly/wildfly-adapter/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml 4.0.0 diff --git a/adapters/saml/wildfly/wildfly-subsystem/pom.xml b/adapters/saml/wildfly/wildfly-subsystem/pom.xml index 8c628c8f6e..d297bd06db 100755 --- a/adapters/saml/wildfly/wildfly-subsystem/pom.xml +++ b/adapters/saml/wildfly/wildfly-subsystem/pom.xml @@ -21,7 +21,7 @@ org.keycloak keycloak-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/adapters/spi/adapter-spi/pom.xml b/adapters/spi/adapter-spi/pom.xml index c4ceb9fd0c..216fc6bf52 100755 --- a/adapters/spi/adapter-spi/pom.xml +++ b/adapters/spi/adapter-spi/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/spi/jboss-adapter-core/pom.xml b/adapters/spi/jboss-adapter-core/pom.xml index 11b61c3e3f..7a4623cec4 100755 --- a/adapters/spi/jboss-adapter-core/pom.xml +++ b/adapters/spi/jboss-adapter-core/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/spi/jetty-adapter-spi/pom.xml b/adapters/spi/jetty-adapter-spi/pom.xml index e2134163ec..edf189c24d 100755 --- a/adapters/spi/jetty-adapter-spi/pom.xml +++ b/adapters/spi/jetty-adapter-spi/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/spi/pom.xml b/adapters/spi/pom.xml index d662207ed4..f14009fab4 100755 --- a/adapters/spi/pom.xml +++ b/adapters/spi/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml Keycloak Client Adapter SPI Modules diff --git a/adapters/spi/servlet-adapter-spi/pom.xml b/adapters/spi/servlet-adapter-spi/pom.xml index ecae51f155..7a61a0bc60 100755 --- a/adapters/spi/servlet-adapter-spi/pom.xml +++ b/adapters/spi/servlet-adapter-spi/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/spi/tomcat-adapter-spi/pom.xml b/adapters/spi/tomcat-adapter-spi/pom.xml index 23378d7c58..3ee0fda744 100755 --- a/adapters/spi/tomcat-adapter-spi/pom.xml +++ b/adapters/spi/tomcat-adapter-spi/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/adapters/spi/undertow-adapter-spi/pom.xml b/adapters/spi/undertow-adapter-spi/pom.xml index 9ebbed5ce2..d3b0e7fc0d 100755 --- a/adapters/spi/undertow-adapter-spi/pom.xml +++ b/adapters/spi/undertow-adapter-spi/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml 4.0.0 diff --git a/authz/client/pom.xml b/authz/client/pom.xml index 3dbf10c183..fda3267955 100644 --- a/authz/client/pom.xml +++ b/authz/client/pom.xml @@ -7,7 +7,7 @@ org.keycloak keycloak-authz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/authz/policy/common/pom.xml b/authz/policy/common/pom.xml index a27dba1a98..6cf86b6a36 100644 --- a/authz/policy/common/pom.xml +++ b/authz/policy/common/pom.xml @@ -25,7 +25,7 @@ org.keycloak keycloak-authz-provider-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/authz/policy/drools/pom.xml b/authz/policy/drools/pom.xml index dd4adff2a3..0dcd10713c 100644 --- a/authz/policy/drools/pom.xml +++ b/authz/policy/drools/pom.xml @@ -7,7 +7,7 @@ org.keycloak keycloak-authz-provider-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/authz/policy/pom.xml b/authz/policy/pom.xml index 6a8816d51f..3f24bf51db 100644 --- a/authz/policy/pom.xml +++ b/authz/policy/pom.xml @@ -7,7 +7,7 @@ org.keycloak keycloak-authz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/authz/pom.xml b/authz/pom.xml index 9e9898bcb0..7be9e34644 100644 --- a/authz/pom.xml +++ b/authz/pom.xml @@ -7,7 +7,7 @@ org.keycloak keycloak-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/common/pom.xml b/common/pom.xml index e741c092b6..f94aa831ed 100755 --- a/common/pom.xml +++ b/common/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/core/pom.xml b/core/pom.xml index 3e69bdc1c7..ab080f8f44 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java b/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java index 0ba327d733..e4065bcd05 100755 --- a/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java +++ b/core/src/main/java/org/keycloak/representations/adapters/config/AdapterConfig.java @@ -36,7 +36,8 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; "client-keystore", "client-keystore-password", "client-key-password", "always-refresh-token", "register-node-at-startup", "register-node-period", "token-store", "principal-attribute", - "proxy-url", "turn-off-change-session-id-on-login", "token-minimum-time-to-live", "min-time-between-jwks-requests", + "proxy-url", "turn-off-change-session-id-on-login", "token-minimum-time-to-live", + "min-time-between-jwks-requests", "public-key-cache-ttl", "policy-enforcer" }) public class AdapterConfig extends BaseAdapterConfig implements AdapterHttpClientConfig { @@ -73,6 +74,8 @@ public class AdapterConfig extends BaseAdapterConfig implements AdapterHttpClien protected int tokenMinimumTimeToLive = 0; @JsonProperty("min-time-between-jwks-requests") protected int minTimeBetweenJwksRequests = 10; + @JsonProperty("public-key-cache-ttl") + protected int publicKeyCacheTtl = 86400; // 1 day @JsonProperty("policy-enforcer") protected PolicyEnforcerConfig policyEnforcerConfig; @@ -233,4 +236,12 @@ public class AdapterConfig extends BaseAdapterConfig implements AdapterHttpClien public void setMinTimeBetweenJwksRequests(int minTimeBetweenJwksRequests) { this.minTimeBetweenJwksRequests = minTimeBetweenJwksRequests; } + + public int getPublicKeyCacheTtl() { + return publicKeyCacheTtl; + } + + public void setPublicKeyCacheTtl(int publicKeyCacheTtl) { + this.publicKeyCacheTtl = publicKeyCacheTtl; + } } diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 17883aba05..6d72740361 100755 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml index 4d66d38139..f4489d4a45 100755 --- a/dependencies/server-all/pom.xml +++ b/dependencies/server-all/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/dependencies/server-min/pom.xml b/dependencies/server-min/pom.xml index 6cbf21b22b..1da3a70014 100755 --- a/dependencies/server-min/pom.xml +++ b/dependencies/server-min/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml b/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml index 4315912996..589927f9e4 100755 --- a/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml +++ b/distribution/adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml index ec486aa30e..ca587580d5 100755 --- a/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml +++ b/distribution/adapters/as7-eap6-adapter/as7-modules/pom.xml @@ -25,7 +25,7 @@ keycloak-as7-eap6-adapter-dist-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml index 2a9767de3d..991ac2d5ed 100755 --- a/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml +++ b/distribution/adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-as7-eap6-adapter-dist-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/distribution/adapters/as7-eap6-adapter/pom.xml b/distribution/adapters/as7-eap6-adapter/pom.xml index a00b050064..fe2df2ecde 100644 --- a/distribution/adapters/as7-eap6-adapter/pom.xml +++ b/distribution/adapters/as7-eap6-adapter/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak AS7 / JBoss EAP 6 Adapter Distros diff --git a/distribution/adapters/fuse-adapter-zip/pom.xml b/distribution/adapters/fuse-adapter-zip/pom.xml index 7c036d9407..abda11dc96 100644 --- a/distribution/adapters/fuse-adapter-zip/pom.xml +++ b/distribution/adapters/fuse-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/jetty81-adapter-zip/pom.xml b/distribution/adapters/jetty81-adapter-zip/pom.xml index 074315f9c1..72fa56733d 100755 --- a/distribution/adapters/jetty81-adapter-zip/pom.xml +++ b/distribution/adapters/jetty81-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/jetty91-adapter-zip/pom.xml b/distribution/adapters/jetty91-adapter-zip/pom.xml index 6ad37cdf18..09ee966fa2 100755 --- a/distribution/adapters/jetty91-adapter-zip/pom.xml +++ b/distribution/adapters/jetty91-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/jetty92-adapter-zip/pom.xml b/distribution/adapters/jetty92-adapter-zip/pom.xml index e1acb94989..10dfe4e3e1 100755 --- a/distribution/adapters/jetty92-adapter-zip/pom.xml +++ b/distribution/adapters/jetty92-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/jetty93-adapter-zip/pom.xml b/distribution/adapters/jetty93-adapter-zip/pom.xml index a65b62de57..ddb743f729 100644 --- a/distribution/adapters/jetty93-adapter-zip/pom.xml +++ b/distribution/adapters/jetty93-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/js-adapter-zip/pom.xml b/distribution/adapters/js-adapter-zip/pom.xml index 1e3074bed1..57dcae4038 100755 --- a/distribution/adapters/js-adapter-zip/pom.xml +++ b/distribution/adapters/js-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/osgi/features/pom.xml b/distribution/adapters/osgi/features/pom.xml index 56a1253f73..7448ff6000 100755 --- a/distribution/adapters/osgi/features/pom.xml +++ b/distribution/adapters/osgi/features/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml Keycloak OSGI Features diff --git a/distribution/adapters/osgi/jaas/pom.xml b/distribution/adapters/osgi/jaas/pom.xml index b9868930df..fcd302962d 100755 --- a/distribution/adapters/osgi/jaas/pom.xml +++ b/distribution/adapters/osgi/jaas/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml Keycloak OSGI JAAS Realm Configuration diff --git a/distribution/adapters/osgi/pom.xml b/distribution/adapters/osgi/pom.xml index 8a4f6037fa..093e2ece6e 100755 --- a/distribution/adapters/osgi/pom.xml +++ b/distribution/adapters/osgi/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak OSGI Integration diff --git a/distribution/adapters/osgi/thirdparty/pom.xml b/distribution/adapters/osgi/thirdparty/pom.xml index 470469addb..1974d0f038 100755 --- a/distribution/adapters/osgi/thirdparty/pom.xml +++ b/distribution/adapters/osgi/thirdparty/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/adapters/pom.xml b/distribution/adapters/pom.xml index 5c9bcc8480..b8ca39ae6d 100755 --- a/distribution/adapters/pom.xml +++ b/distribution/adapters/pom.xml @@ -20,7 +20,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Adapters Distribution Parent diff --git a/distribution/adapters/tomcat6-adapter-zip/pom.xml b/distribution/adapters/tomcat6-adapter-zip/pom.xml index bc650acb01..67de7c3565 100755 --- a/distribution/adapters/tomcat6-adapter-zip/pom.xml +++ b/distribution/adapters/tomcat6-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/tomcat7-adapter-zip/pom.xml b/distribution/adapters/tomcat7-adapter-zip/pom.xml index b524945ca0..6d2d8875cd 100755 --- a/distribution/adapters/tomcat7-adapter-zip/pom.xml +++ b/distribution/adapters/tomcat7-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/tomcat8-adapter-zip/pom.xml b/distribution/adapters/tomcat8-adapter-zip/pom.xml index d1dac8d306..ba29d33322 100755 --- a/distribution/adapters/tomcat8-adapter-zip/pom.xml +++ b/distribution/adapters/tomcat8-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/adapters/wf8-adapter/pom.xml b/distribution/adapters/wf8-adapter/pom.xml index 922e754fef..7bd34a0b96 100644 --- a/distribution/adapters/wf8-adapter/pom.xml +++ b/distribution/adapters/wf8-adapter/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak Wildfly 8 Adapter diff --git a/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml b/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml index 4d0a06ba6e..9bb314b2c0 100755 --- a/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml +++ b/distribution/adapters/wf8-adapter/wf8-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/adapters/wf8-adapter/wf8-modules/pom.xml b/distribution/adapters/wf8-adapter/wf8-modules/pom.xml index ef7c3310be..2e151c724f 100755 --- a/distribution/adapters/wf8-adapter/wf8-modules/pom.xml +++ b/distribution/adapters/wf8-adapter/wf8-modules/pom.xml @@ -25,7 +25,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/adapters/wildfly-adapter/pom.xml b/distribution/adapters/wildfly-adapter/pom.xml index 0f814d47e7..af991b8169 100644 --- a/distribution/adapters/wildfly-adapter/pom.xml +++ b/distribution/adapters/wildfly-adapter/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak Wildfly Adapter diff --git a/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml index 4251876589..f691030ed3 100755 --- a/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml +++ b/distribution/adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml b/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml index bf500db1ba..b528fefce3 100755 --- a/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml +++ b/distribution/adapters/wildfly-adapter/wildfly-modules/pom.xml @@ -25,7 +25,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/api-docs-dist/pom.xml b/distribution/api-docs-dist/pom.xml index 2267578090..8536bb96f8 100755 --- a/distribution/api-docs-dist/pom.xml +++ b/distribution/api-docs-dist/pom.xml @@ -21,7 +21,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-api-docs-dist diff --git a/distribution/demo-dist/pom.xml b/distribution/demo-dist/pom.xml index 2d0130ff32..ddb6e04838 100755 --- a/distribution/demo-dist/pom.xml +++ b/distribution/demo-dist/pom.xml @@ -21,7 +21,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-demo-dist diff --git a/distribution/downloads/pom.xml b/distribution/downloads/pom.xml index 1fc22ff938..bba0b912a4 100755 --- a/distribution/downloads/pom.xml +++ b/distribution/downloads/pom.xml @@ -21,7 +21,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-dist-downloads diff --git a/distribution/examples-dist/pom.xml b/distribution/examples-dist/pom.xml index cb25859405..c7eea912cb 100755 --- a/distribution/examples-dist/pom.xml +++ b/distribution/examples-dist/pom.xml @@ -21,7 +21,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-examples-dist diff --git a/distribution/feature-packs/adapter-feature-pack/pom.xml b/distribution/feature-packs/adapter-feature-pack/pom.xml index ca868b3e94..9dbfe27990 100755 --- a/distribution/feature-packs/adapter-feature-pack/pom.xml +++ b/distribution/feature-packs/adapter-feature-pack/pom.xml @@ -19,7 +19,7 @@ org.keycloak feature-packs-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/distribution/feature-packs/pom.xml b/distribution/feature-packs/pom.xml index 4198508487..e767d8cd3f 100644 --- a/distribution/feature-packs/pom.xml +++ b/distribution/feature-packs/pom.xml @@ -20,7 +20,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Feature Pack Builds diff --git a/distribution/feature-packs/server-feature-pack/pom.xml b/distribution/feature-packs/server-feature-pack/pom.xml index f001634bb9..2a5ee4c903 100644 --- a/distribution/feature-packs/server-feature-pack/pom.xml +++ b/distribution/feature-packs/server-feature-pack/pom.xml @@ -19,7 +19,7 @@ org.keycloak feature-packs-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/distribution/pom.xml b/distribution/pom.xml index 6004cc0ca7..dfb8e7c0da 100755 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/distribution/proxy-dist/pom.xml b/distribution/proxy-dist/pom.xml index 279314d46a..40e5d265ac 100755 --- a/distribution/proxy-dist/pom.xml +++ b/distribution/proxy-dist/pom.xml @@ -21,7 +21,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-proxy-dist diff --git a/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml index bc99ccb233..d3ad498eb0 100755 --- a/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml +++ b/distribution/saml-adapters/as7-eap6-adapter/as7-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml index bef3baf647..545e0337f4 100755 --- a/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml +++ b/distribution/saml-adapters/as7-eap6-adapter/as7-modules/pom.xml @@ -25,7 +25,7 @@ keycloak-saml-as7-eap6-adapter-dist-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml index cc487792eb..d6433a4aa6 100755 --- a/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml +++ b/distribution/saml-adapters/as7-eap6-adapter/eap6-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-saml-as7-eap6-adapter-dist-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/distribution/saml-adapters/as7-eap6-adapter/pom.xml b/distribution/saml-adapters/as7-eap6-adapter/pom.xml index 0ceef5a14a..1a705c1a5f 100755 --- a/distribution/saml-adapters/as7-eap6-adapter/pom.xml +++ b/distribution/saml-adapters/as7-eap6-adapter/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak SAML AS7 / JBoss EAP 6 Adapter Distros diff --git a/distribution/saml-adapters/jetty81-adapter-zip/pom.xml b/distribution/saml-adapters/jetty81-adapter-zip/pom.xml index 1d8ddd34b7..aeb4407092 100755 --- a/distribution/saml-adapters/jetty81-adapter-zip/pom.xml +++ b/distribution/saml-adapters/jetty81-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/saml-adapters/jetty92-adapter-zip/pom.xml b/distribution/saml-adapters/jetty92-adapter-zip/pom.xml index 589fdde4ba..9ba4478bdd 100755 --- a/distribution/saml-adapters/jetty92-adapter-zip/pom.xml +++ b/distribution/saml-adapters/jetty92-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/saml-adapters/jetty93-adapter-zip/pom.xml b/distribution/saml-adapters/jetty93-adapter-zip/pom.xml index 9f06f28bc5..42e4d75178 100644 --- a/distribution/saml-adapters/jetty93-adapter-zip/pom.xml +++ b/distribution/saml-adapters/jetty93-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/saml-adapters/pom.xml b/distribution/saml-adapters/pom.xml index e273793463..e45813038e 100755 --- a/distribution/saml-adapters/pom.xml +++ b/distribution/saml-adapters/pom.xml @@ -20,7 +20,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT SAML Adapters Distribution Parent diff --git a/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml b/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml index 8282701319..bee45754e3 100755 --- a/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml +++ b/distribution/saml-adapters/tomcat6-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml b/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml index 59112359d6..14b987528a 100755 --- a/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml +++ b/distribution/saml-adapters/tomcat7-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml b/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml index e0036d68f3..339b05459c 100755 --- a/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml +++ b/distribution/saml-adapters/tomcat8-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml diff --git a/distribution/saml-adapters/wildfly-adapter/pom.xml b/distribution/saml-adapters/wildfly-adapter/pom.xml index 91f6402080..da5d1f12bd 100755 --- a/distribution/saml-adapters/wildfly-adapter/pom.xml +++ b/distribution/saml-adapters/wildfly-adapter/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../pom.xml Keycloak Wildfly SAML Adapter diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml index 655a99f274..34823e9767 100755 --- a/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml +++ b/distribution/saml-adapters/wildfly-adapter/wildfly-adapter-zip/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml index 6e8a4c3dbb..9fe62c9dd5 100755 --- a/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml +++ b/distribution/saml-adapters/wildfly-adapter/wildfly-modules/pom.xml @@ -25,7 +25,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../../../pom.xml diff --git a/distribution/server-dist/pom.xml b/distribution/server-dist/pom.xml index 6ce5eaad72..85bd552023 100755 --- a/distribution/server-dist/pom.xml +++ b/distribution/server-dist/pom.xml @@ -21,7 +21,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-server-dist diff --git a/distribution/server-overlay/pom.xml b/distribution/server-overlay/pom.xml index 485dd4693c..ddf8cb56e7 100755 --- a/distribution/server-overlay/pom.xml +++ b/distribution/server-overlay/pom.xml @@ -21,7 +21,7 @@ keycloak-distribution-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-server-overlay diff --git a/examples/admin-client/pom.xml b/examples/admin-client/pom.xml index 70b4e062a1..a37811e395 100755 --- a/examples/admin-client/pom.xml +++ b/examples/admin-client/pom.xml @@ -22,7 +22,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Examples - Admin Client diff --git a/examples/authz/hello-world-authz-service/pom.xml b/examples/authz/hello-world-authz-service/pom.xml index 11ec950480..d68e59912f 100755 --- a/examples/authz/hello-world-authz-service/pom.xml +++ b/examples/authz/hello-world-authz-service/pom.xml @@ -24,7 +24,7 @@ org.keycloak keycloak-authz-example-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/authz/hello-world/pom.xml b/examples/authz/hello-world/pom.xml index 7863206386..c48651c49e 100755 --- a/examples/authz/hello-world/pom.xml +++ b/examples/authz/hello-world/pom.xml @@ -24,7 +24,7 @@ org.keycloak keycloak-authz-example-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/authz/photoz/photoz-authz-policy/pom.xml b/examples/authz/photoz/photoz-authz-policy/pom.xml index 5f594cc328..36415dcb5d 100755 --- a/examples/authz/photoz/photoz-authz-policy/pom.xml +++ b/examples/authz/photoz/photoz-authz-policy/pom.xml @@ -6,7 +6,7 @@ org.keycloak keycloak-authz-photoz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/authz/photoz/photoz-html5-client/pom.xml b/examples/authz/photoz/photoz-html5-client/pom.xml index 94a586d8c4..337a8a9a64 100755 --- a/examples/authz/photoz/photoz-html5-client/pom.xml +++ b/examples/authz/photoz/photoz-html5-client/pom.xml @@ -5,7 +5,7 @@ org.keycloak keycloak-authz-photoz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/authz/photoz/photoz-restful-api/pom.xml b/examples/authz/photoz/photoz-restful-api/pom.xml index 46dd910ffb..c4016f09e6 100755 --- a/examples/authz/photoz/photoz-restful-api/pom.xml +++ b/examples/authz/photoz/photoz-restful-api/pom.xml @@ -6,7 +6,7 @@ org.keycloak keycloak-authz-photoz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/authz/photoz/pom.xml b/examples/authz/photoz/pom.xml index 35222d844c..813c680beb 100755 --- a/examples/authz/photoz/pom.xml +++ b/examples/authz/photoz/pom.xml @@ -6,7 +6,7 @@ org.keycloak keycloak-authz-example-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/authz/pom.xml b/examples/authz/pom.xml index c15d7baf04..a05ae7ab3b 100755 --- a/examples/authz/pom.xml +++ b/examples/authz/pom.xml @@ -6,7 +6,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/authz/servlet-authz/pom.xml b/examples/authz/servlet-authz/pom.xml index 0ad402227a..502c20a90f 100755 --- a/examples/authz/servlet-authz/pom.xml +++ b/examples/authz/servlet-authz/pom.xml @@ -6,7 +6,7 @@ org.keycloak keycloak-authz-example-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/examples/basic-auth/pom.xml b/examples/basic-auth/pom.xml index dbe695e541..26f5d89587 100755 --- a/examples/basic-auth/pom.xml +++ b/examples/basic-auth/pom.xml @@ -23,7 +23,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Examples - Basic Auth diff --git a/examples/broker/facebook-authentication/pom.xml b/examples/broker/facebook-authentication/pom.xml index ac389599d8..c385021b5a 100755 --- a/examples/broker/facebook-authentication/pom.xml +++ b/examples/broker/facebook-authentication/pom.xml @@ -23,7 +23,7 @@ keycloak-examples-broker-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Broker Examples - Facebook Authentication diff --git a/examples/broker/google-authentication/pom.xml b/examples/broker/google-authentication/pom.xml index 6daddda5f9..2915b37d72 100755 --- a/examples/broker/google-authentication/pom.xml +++ b/examples/broker/google-authentication/pom.xml @@ -23,7 +23,7 @@ keycloak-examples-broker-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Broker Examples - Google Authentication diff --git a/examples/broker/pom.xml b/examples/broker/pom.xml index 7574ff6d96..ea4e4b9b10 100755 --- a/examples/broker/pom.xml +++ b/examples/broker/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Broker Examples diff --git a/examples/broker/saml-broker-authentication/pom.xml b/examples/broker/saml-broker-authentication/pom.xml index a926b41712..44ee35cf45 100755 --- a/examples/broker/saml-broker-authentication/pom.xml +++ b/examples/broker/saml-broker-authentication/pom.xml @@ -23,7 +23,7 @@ keycloak-examples-broker-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Broker Examples - SAML Identity Provider Brokering diff --git a/examples/broker/twitter-authentication/pom.xml b/examples/broker/twitter-authentication/pom.xml index 5d7faccaab..af32c5e7a6 100755 --- a/examples/broker/twitter-authentication/pom.xml +++ b/examples/broker/twitter-authentication/pom.xml @@ -23,7 +23,7 @@ keycloak-examples-broker-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Broker Examples - Twitter Authentication diff --git a/examples/cors/angular-product-app/pom.xml b/examples/cors/angular-product-app/pom.xml index 3412f64834..ec4f7696a5 100755 --- a/examples/cors/angular-product-app/pom.xml +++ b/examples/cors/angular-product-app/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-cors-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/cors/database-service/pom.xml b/examples/cors/database-service/pom.xml index 14f71ecfc0..e59fca3b59 100755 --- a/examples/cors/database-service/pom.xml +++ b/examples/cors/database-service/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-cors-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/cors/pom.xml b/examples/cors/pom.xml index 69aa10f71f..a38f8d8d57 100755 --- a/examples/cors/pom.xml +++ b/examples/cors/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Examples - CORS diff --git a/examples/demo-template/admin-access-app/pom.xml b/examples/demo-template/admin-access-app/pom.xml index 2d93fb4968..49ba4f8c04 100755 --- a/examples/demo-template/admin-access-app/pom.xml +++ b/examples/demo-template/admin-access-app/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/angular-product-app/pom.xml b/examples/demo-template/angular-product-app/pom.xml index 9d81a98818..c540f364e8 100755 --- a/examples/demo-template/angular-product-app/pom.xml +++ b/examples/demo-template/angular-product-app/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/angular2-product-app/pom.xml b/examples/demo-template/angular2-product-app/pom.xml index ee63fd6eb9..3ac174ab21 100644 --- a/examples/demo-template/angular2-product-app/pom.xml +++ b/examples/demo-template/angular2-product-app/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/customer-app-cli/pom.xml b/examples/demo-template/customer-app-cli/pom.xml index 0f8a08f46c..c4aef580f0 100755 --- a/examples/demo-template/customer-app-cli/pom.xml +++ b/examples/demo-template/customer-app-cli/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/customer-app-filter/pom.xml b/examples/demo-template/customer-app-filter/pom.xml index 7d3bd7614c..5e49975687 100755 --- a/examples/demo-template/customer-app-filter/pom.xml +++ b/examples/demo-template/customer-app-filter/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/customer-app-js/pom.xml b/examples/demo-template/customer-app-js/pom.xml index a0f6317ef4..efd296182d 100755 --- a/examples/demo-template/customer-app-js/pom.xml +++ b/examples/demo-template/customer-app-js/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/customer-app/pom.xml b/examples/demo-template/customer-app/pom.xml index 1adc37f1d9..96697dbe5b 100755 --- a/examples/demo-template/customer-app/pom.xml +++ b/examples/demo-template/customer-app/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/database-service/pom.xml b/examples/demo-template/database-service/pom.xml index e46ebf4f3b..1fbdec472b 100755 --- a/examples/demo-template/database-service/pom.xml +++ b/examples/demo-template/database-service/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/example-ear/pom.xml b/examples/demo-template/example-ear/pom.xml index a81d5e9930..57fb93b5c2 100755 --- a/examples/demo-template/example-ear/pom.xml +++ b/examples/demo-template/example-ear/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/offline-access-app/pom.xml b/examples/demo-template/offline-access-app/pom.xml index d5dc95daf2..103f13de36 100755 --- a/examples/demo-template/offline-access-app/pom.xml +++ b/examples/demo-template/offline-access-app/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/pom.xml b/examples/demo-template/pom.xml index f2d38ad12b..d08aedbc1d 100755 --- a/examples/demo-template/pom.xml +++ b/examples/demo-template/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Examples diff --git a/examples/demo-template/product-app/pom.xml b/examples/demo-template/product-app/pom.xml index 8b123e8499..71ae41f22b 100755 --- a/examples/demo-template/product-app/pom.xml +++ b/examples/demo-template/product-app/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/service-account/pom.xml b/examples/demo-template/service-account/pom.xml index 517cd39487..2d5c45da70 100755 --- a/examples/demo-template/service-account/pom.xml +++ b/examples/demo-template/service-account/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/third-party-cdi/pom.xml b/examples/demo-template/third-party-cdi/pom.xml index 8ceaf946a1..b0b0212ee6 100755 --- a/examples/demo-template/third-party-cdi/pom.xml +++ b/examples/demo-template/third-party-cdi/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/demo-template/third-party/pom.xml b/examples/demo-template/third-party/pom.xml index 664b2e6885..fcd67c5159 100755 --- a/examples/demo-template/third-party/pom.xml +++ b/examples/demo-template/third-party/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-demo-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/fuse/camel/pom.xml b/examples/fuse/camel/pom.xml index 984e98785c..be15f3d740 100755 --- a/examples/fuse/camel/pom.xml +++ b/examples/fuse/camel/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-fuse-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/fuse/customer-app-fuse/pom.xml b/examples/fuse/customer-app-fuse/pom.xml index 603a2cc47f..7d9f990f5d 100755 --- a/examples/fuse/customer-app-fuse/pom.xml +++ b/examples/fuse/customer-app-fuse/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-fuse-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/fuse/cxf-jaxrs/pom.xml b/examples/fuse/cxf-jaxrs/pom.xml index ac4832ec96..60238fb627 100755 --- a/examples/fuse/cxf-jaxrs/pom.xml +++ b/examples/fuse/cxf-jaxrs/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-fuse-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/fuse/cxf-jaxws/pom.xml b/examples/fuse/cxf-jaxws/pom.xml index 2a37cfbc3f..b3705c7ab2 100755 --- a/examples/fuse/cxf-jaxws/pom.xml +++ b/examples/fuse/cxf-jaxws/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-fuse-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/fuse/external-config/pom.xml b/examples/fuse/external-config/pom.xml index 178904bcb1..daadfefca6 100755 --- a/examples/fuse/external-config/pom.xml +++ b/examples/fuse/external-config/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-fuse-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Examples - External Config diff --git a/examples/fuse/features/pom.xml b/examples/fuse/features/pom.xml index 58183e6174..7d59641074 100755 --- a/examples/fuse/features/pom.xml +++ b/examples/fuse/features/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-fuse-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/fuse/pom.xml b/examples/fuse/pom.xml index d589b8d1c6..cc09f877a8 100755 --- a/examples/fuse/pom.xml +++ b/examples/fuse/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Fuse examples diff --git a/examples/fuse/product-app-fuse/pom.xml b/examples/fuse/product-app-fuse/pom.xml index 1b5dc91d2d..418f327cce 100755 --- a/examples/fuse/product-app-fuse/pom.xml +++ b/examples/fuse/product-app-fuse/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-fuse-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/js-console/pom.xml b/examples/js-console/pom.xml index 3d5f651357..eade8ca31e 100755 --- a/examples/js-console/pom.xml +++ b/examples/js-console/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/kerberos/pom.xml b/examples/kerberos/pom.xml index 129575ba30..8e2bcca436 100755 --- a/examples/kerberos/pom.xml +++ b/examples/kerberos/pom.xml @@ -22,7 +22,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Examples - Kerberos Credential Delegation diff --git a/examples/ldap/pom.xml b/examples/ldap/pom.xml index 4b65b78173..d70425b6cb 100644 --- a/examples/ldap/pom.xml +++ b/examples/ldap/pom.xml @@ -22,7 +22,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/examples/multi-tenant/pom.xml b/examples/multi-tenant/pom.xml index ac303311ab..e0c276c9a8 100755 --- a/examples/multi-tenant/pom.xml +++ b/examples/multi-tenant/pom.xml @@ -21,7 +21,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Examples - Multi Tenant diff --git a/examples/pom.xml b/examples/pom.xml index 1a985e2ad5..f2507b1696 100755 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Examples diff --git a/examples/providers/authenticator/pom.xml b/examples/providers/authenticator/pom.xml index 100b03a41b..5b70723eb3 100755 --- a/examples/providers/authenticator/pom.xml +++ b/examples/providers/authenticator/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-providers-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Authenticator Example diff --git a/examples/providers/domain-extension/pom.xml b/examples/providers/domain-extension/pom.xml index e0d75ca6e4..7cae0351bc 100755 --- a/examples/providers/domain-extension/pom.xml +++ b/examples/providers/domain-extension/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-providers-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Domain Extension Example diff --git a/examples/providers/event-listener-sysout/pom.xml b/examples/providers/event-listener-sysout/pom.xml index e5dcf77bc6..d17e48ae95 100755 --- a/examples/providers/event-listener-sysout/pom.xml +++ b/examples/providers/event-listener-sysout/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-providers-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Event Listener System.out Example diff --git a/examples/providers/event-store-mem/pom.xml b/examples/providers/event-store-mem/pom.xml index d1e068c0f6..88ac583cd2 100755 --- a/examples/providers/event-store-mem/pom.xml +++ b/examples/providers/event-store-mem/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-providers-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Event Store In-Mem Example diff --git a/examples/providers/pom.xml b/examples/providers/pom.xml index c9be81d3bb..dd59811509 100755 --- a/examples/providers/pom.xml +++ b/examples/providers/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Provider Examples diff --git a/examples/providers/rest/pom.xml b/examples/providers/rest/pom.xml index b17a42e9d3..1f785500d5 100755 --- a/examples/providers/rest/pom.xml +++ b/examples/providers/rest/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-providers-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Authenticator Example diff --git a/examples/providers/user-storage-jpa/pom.xml b/examples/providers/user-storage-jpa/pom.xml index d22ecc8015..0eb846feb9 100755 --- a/examples/providers/user-storage-jpa/pom.xml +++ b/examples/providers/user-storage-jpa/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-providers-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT User Storage JPA Provider Exapmle diff --git a/examples/providers/user-storage-simple/pom.xml b/examples/providers/user-storage-simple/pom.xml index 099510323d..03faeec62a 100755 --- a/examples/providers/user-storage-simple/pom.xml +++ b/examples/providers/user-storage-simple/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-providers-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT UserStorageProvider Simple Example diff --git a/examples/saml/pom.xml b/examples/saml/pom.xml index 429fe35dc1..c5ffee9cf4 100755 --- a/examples/saml/pom.xml +++ b/examples/saml/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Provider Examples diff --git a/examples/saml/post-with-encryption/pom.xml b/examples/saml/post-with-encryption/pom.xml index 41cde50ce2..40c690ae89 100755 --- a/examples/saml/post-with-encryption/pom.xml +++ b/examples/saml/post-with-encryption/pom.xml @@ -22,7 +22,7 @@ keycloak-examples-saml-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT saml-post-encryption diff --git a/examples/saml/post-with-signature/pom.xml b/examples/saml/post-with-signature/pom.xml index 06d1a8710f..fc74042de4 100755 --- a/examples/saml/post-with-signature/pom.xml +++ b/examples/saml/post-with-signature/pom.xml @@ -22,7 +22,7 @@ keycloak-examples-saml-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT sales-post-sig diff --git a/examples/saml/redirect-with-signature/pom.xml b/examples/saml/redirect-with-signature/pom.xml index c86a0f6ae5..0a8a6d93f7 100755 --- a/examples/saml/redirect-with-signature/pom.xml +++ b/examples/saml/redirect-with-signature/pom.xml @@ -22,7 +22,7 @@ keycloak-examples-saml-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT saml-redirect-signatures diff --git a/examples/saml/servlet-filter/pom.xml b/examples/saml/servlet-filter/pom.xml index fb01fa8748..3b1f94b12b 100755 --- a/examples/saml/servlet-filter/pom.xml +++ b/examples/saml/servlet-filter/pom.xml @@ -22,7 +22,7 @@ keycloak-examples-saml-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT saml-servlet-filter diff --git a/examples/themes/pom.xml b/examples/themes/pom.xml index ab4c7b618a..ff5fc6a2f9 100755 --- a/examples/themes/pom.xml +++ b/examples/themes/pom.xml @@ -20,7 +20,7 @@ keycloak-examples-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Themes Examples diff --git a/federation/kerberos/pom.xml b/federation/kerberos/pom.xml index a169fe2c5c..e8eddb18aa 100755 --- a/federation/kerberos/pom.xml +++ b/federation/kerberos/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/federation/ldap/pom.xml b/federation/ldap/pom.xml index 8e554a5846..9323814107 100755 --- a/federation/ldap/pom.xml +++ b/federation/ldap/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java index ec2e32c403..930837d037 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java @@ -127,6 +127,10 @@ public class LDAPConfig { return uuidAttrName; } + + public boolean isObjectGUID() { + return getUuidLDAPAttributeName().equalsIgnoreCase(LDAPConstants.OBJECT_GUID); + } public boolean isPagination() { String pagination = config.getFirst(LDAPConstants.PAGINATION); diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java index 4fe40020e3..cb58a1e174 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/idm/store/ldap/LDAPOperationManager.java @@ -242,7 +242,7 @@ public class LDAPOperationManager { public String getFilterById(String id) { String filter = null; - if (this.config.isActiveDirectory()) { + if (this.config.isObjectGUID()) { final String strObjectGUID = ""; try { @@ -458,8 +458,7 @@ public class LDAPOperationManager { public String decodeEntryUUID(final Object entryUUID) { String id; - - if (this.config.isActiveDirectory() && entryUUID instanceof byte[]) { + if (this.config.isObjectGUID() && entryUUID instanceof byte[]) { id = LDAPUtil.decodeObjectGUID((byte[]) entryUUID); } else { id = entryUUID.toString(); @@ -516,7 +515,7 @@ public class LDAPOperationManager { } } - if (config.isActiveDirectory()) { + if (this.config.isObjectGUID()) { env.put("java.naming.ldap.attributes.binary", LDAPConstants.OBJECT_GUID); } diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java new file mode 100644 index 0000000000..be07781321 --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapper.java @@ -0,0 +1,267 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.storage.ldap.mappers.msadlds; + +import org.jboss.logging.Logger; +import org.keycloak.component.ComponentModel; +import org.keycloak.credential.CredentialInput; +import org.keycloak.models.LDAPConstants; +import org.keycloak.models.ModelException; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.utils.UserModelDelegate; +import org.keycloak.storage.UserStorageProvider; +import org.keycloak.storage.ldap.LDAPStorageProvider; +import org.keycloak.storage.ldap.idm.model.LDAPObject; +import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery; +import org.keycloak.storage.ldap.mappers.AbstractLDAPStorageMapper; +import org.keycloak.storage.ldap.mappers.PasswordUpdated; + +import javax.naming.AuthenticationException; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Mapper specific to MSAD LDS. It's able to read the msDS-UserAccountDisabled, msDS-UserPasswordExpired and pwdLastSet attributes and set actions in Keycloak based on that. + * It's also able to handle exception code from LDAP user authentication (See http://www-01.ibm.com/support/docview.wss?uid=swg21290631 ) + * + * @author Marek Posolda + * @author Slawomir Dabek + */ +public class MSADLDSUserAccountControlStorageMapper extends AbstractLDAPStorageMapper implements PasswordUpdated { + + private static final Logger logger = Logger.getLogger(MSADLDSUserAccountControlStorageMapper.class); + + private static final Pattern AUTH_EXCEPTION_REGEX = Pattern.compile(".*AcceptSecurityContext error, data ([0-9a-f]*), v.*"); + private static final Pattern AUTH_INVALID_NEW_PASSWORD = Pattern.compile("(?s).*problem 1005 \\(CONSTRAINT_ATT_TYPE\\), data [0-9a-f]*, Att 23 \\(userPassword\\).*"); + + public MSADLDSUserAccountControlStorageMapper(ComponentModel mapperModel, LDAPStorageProvider ldapProvider, RealmModel realm) { + super(mapperModel, ldapProvider, realm); + ldapProvider.setUpdater(this); + } + + @Override + public void beforeLDAPQuery(LDAPQuery query) { + query.addReturningLdapAttribute(LDAPConstants.PWD_LAST_SET); + query.addReturningLdapAttribute(LDAPConstants.MSDS_USER_ACCOUNT_DISABLED); + + // This needs to be read-only and can be set to writable just on demand + query.addReturningReadOnlyLdapAttribute(LDAPConstants.PWD_LAST_SET); + + if (ldapProvider.getEditMode() != UserStorageProvider.EditMode.WRITABLE) { + query.addReturningReadOnlyLdapAttribute(LDAPConstants.MSDS_USER_ACCOUNT_DISABLED); + } + } + + @Override + public void passwordUpdated(UserModel user, LDAPObject ldapUser, CredentialInput input) { + logger.debugf("Going to update pwdLastSet for ldap user '%s' after successful password update", ldapUser.getDn().toString()); + + // Normally it's read-only + ldapUser.removeReadOnlyAttributeName(LDAPConstants.PWD_LAST_SET); + + ldapUser.setSingleAttribute(LDAPConstants.PWD_LAST_SET, "-1"); + + if (user.isEnabled()) { + // TODO: Use removeAttribute once available + ldapUser.setSingleAttribute(LDAPConstants.MSDS_USER_ACCOUNT_DISABLED, "FALSE"); + logger.debugf("Removing msDS-UserPasswordExpired of user '%s'", ldapUser.getDn().toString()); + } + + ldapProvider.getLdapIdentityStore().update(ldapUser); + } + + @Override + public UserModel proxy(LDAPObject ldapUser, UserModel delegate) { + return new MSADUserModelDelegate(delegate, ldapUser); + } + + @Override + public void onRegisterUserToLDAP(LDAPObject ldapUser, UserModel localUser) { + + } + + @Override + public void onImportUserFromLDAP(LDAPObject ldapUser, UserModel user, boolean isCreate) { + + } + + @Override + public boolean onAuthenticationFailure(LDAPObject ldapUser, UserModel user, AuthenticationException ldapException) { + String exceptionMessage = ldapException.getMessage(); + Matcher m = AUTH_EXCEPTION_REGEX.matcher(exceptionMessage); + if (m.matches()) { + String errorCode = m.group(1); + return processAuthErrorCode(errorCode, user); + } else { + return false; + } + } + + protected boolean processAuthErrorCode(String errorCode, UserModel user) { + logger.debugf("MSAD LDS Error code is '%s' after failed LDAP login of user '%s'", errorCode, user.getUsername()); + + if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) { + if (errorCode.equals("532") || errorCode.equals("773")) { + // User needs to change his MSAD password. Allow him to login, but add UPDATE_PASSWORD required action + user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD); + return true; + } else if (errorCode.equals("533")) { + // User is disabled in MSAD LDS. Set him to disabled in KC as well + user.setEnabled(false); + return true; + } else if (errorCode.equals("775")) { + logger.warnf("Locked user '%s' attempt to login", user.getUsername()); + } + } + + return false; + } + + + protected ModelException processFailedPasswordUpdateException(ModelException e) { + if (e.getCause() == null || e.getCause().getMessage() == null) { + return e; + } + + String exceptionMessage = e.getCause().getMessage(); + Matcher m = AUTH_INVALID_NEW_PASSWORD.matcher(exceptionMessage); + if (m.matches()) { + ModelException me = new ModelException("invalidPasswordRegexPatternMessage", e); + me.setParameters(new Object[]{"passwordConstraintViolation"}); + return me; + } + + return e; + } + + public class MSADUserModelDelegate extends UserModelDelegate { + + private final LDAPObject ldapUser; + + public MSADUserModelDelegate(UserModel delegate, LDAPObject ldapUser) { + super(delegate); + this.ldapUser = ldapUser; + } + + @Override + public boolean isEnabled() { + boolean kcEnabled = super.isEnabled(); + + if (getPwdLastSet() > 0) { + // Merge KC and MSAD LDS + return kcEnabled && !Boolean.parseBoolean(ldapUser.getAttributeAsString(LDAPConstants.MSDS_USER_ACCOUNT_DISABLED)); + } else { + // If new MSAD LDS user is created and pwdLastSet is still 0, MSAD account is in disabled state. So read just from Keycloak DB. User is not able to login via MSAD anyway + return kcEnabled; + } + } + + @Override + public void setEnabled(boolean enabled) { + // Always update DB + super.setEnabled(enabled); + + if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE && getPwdLastSet() > 0) { + if (enabled) { + logger.debugf("Removing msDS-UserAccountDisabled of user '%s'", ldapUser.getDn().toString()); + // TODO: Use removeAttribute once available + ldapUser.setSingleAttribute(LDAPConstants.MSDS_USER_ACCOUNT_DISABLED, "FALSE"); + } else { + logger.debugf("Setting msDS-UserAccountDisabled of user '%s' to value 'TRUE'", ldapUser.getDn().toString()); + ldapUser.setSingleAttribute(LDAPConstants.MSDS_USER_ACCOUNT_DISABLED, "TRUE"); + } + + ldapProvider.getLdapIdentityStore().update(ldapUser); + } + } + + @Override + public void addRequiredAction(RequiredAction action) { + String actionName = action.name(); + addRequiredAction(actionName); + } + + @Override + public void addRequiredAction(String action) { + // Always update DB + super.addRequiredAction(action); + + if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE && RequiredAction.UPDATE_PASSWORD.toString().equals(action)) { + logger.debugf("Going to propagate required action UPDATE_PASSWORD to MSAD for ldap user '%s' ", ldapUser.getDn().toString()); + + // Normally it's read-only + ldapUser.removeReadOnlyAttributeName(LDAPConstants.PWD_LAST_SET); + + ldapUser.setSingleAttribute(LDAPConstants.PWD_LAST_SET, "0"); + ldapProvider.getLdapIdentityStore().update(ldapUser); + } + } + + @Override + public void removeRequiredAction(RequiredAction action) { + String actionName = action.name(); + removeRequiredAction(actionName); + } + + @Override + public void removeRequiredAction(String action) { + // Always update DB + super.removeRequiredAction(action); + + if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE && RequiredAction.UPDATE_PASSWORD.toString().equals(action)) { + + // Don't set pwdLastSet in MSAD LDS when it is new user + if (!Boolean.parseBoolean(ldapUser.getAttributeAsString(LDAPConstants.MSDS_USER_PASSWORD_NOTREQD))) { + logger.debugf("Going to remove required action UPDATE_PASSWORD from MSAD LDS for ldap user '%s' ", ldapUser.getDn().toString()); + + // Normally it's read-only + ldapUser.removeReadOnlyAttributeName(LDAPConstants.PWD_LAST_SET); + + ldapUser.setSingleAttribute(LDAPConstants.PWD_LAST_SET, "-1"); + ldapProvider.getLdapIdentityStore().update(ldapUser); + } + } + } + + @Override + public Set getRequiredActions() { + Set requiredActions = super.getRequiredActions(); + + if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) { + if (getPwdLastSet() == 0 || Boolean.parseBoolean(ldapUser.getAttributeAsString(LDAPConstants.MSDS_USER_PASSWORD_EXPIRED))) { + requiredActions = new HashSet<>(requiredActions); + requiredActions.add(RequiredAction.UPDATE_PASSWORD.toString()); + return requiredActions; + } + } + + return requiredActions; + } + + protected long getPwdLastSet() { + String pwdLastSet = ldapUser.getAttributeAsString(LDAPConstants.PWD_LAST_SET); + return pwdLastSet == null ? 0 : Long.parseLong(pwdLastSet); + } + + + } + +} diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapperFactory.java new file mode 100644 index 0000000000..fc456cdddf --- /dev/null +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/msadlds/MSADLDSUserAccountControlStorageMapperFactory.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.storage.ldap.mappers.msadlds; + +import org.keycloak.component.ComponentModel; +import org.keycloak.models.LDAPConstants; +import org.keycloak.models.RealmModel; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.storage.ldap.LDAPStorageProvider; +import org.keycloak.storage.ldap.mappers.AbstractLDAPStorageMapper; +import org.keycloak.storage.ldap.mappers.AbstractLDAPStorageMapperFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Marek Posolda + * @author Slawomir Dabek + */ +public class MSADLDSUserAccountControlStorageMapperFactory extends AbstractLDAPStorageMapperFactory { + + public static final String PROVIDER_ID = LDAPConstants.MSADLDS_USER_ACCOUNT_CONTROL_MAPPER; + protected static final List configProperties = new ArrayList<>(); + + static { + } + + @Override + public String getHelpText() { + return "Mapper specific to MSAD LDS. It's able to integrate the MSAD LDS user account state into Keycloak account state (account enabled, password is expired etc). It's using msDS-UserAccountDisabled and pwdLastSet MSAD attributes for that. " + + "For example if pwdLastSet is 0, the Keycloak user is required to update password, if msDS-UserAccountDisabled is 'TRUE' the Keycloak user is disabled as well etc. Mapper is also able to handle exception code from LDAP user authentication."; + } + + @Override + public List getConfigProperties() { + return configProperties; + } + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + protected AbstractLDAPStorageMapper createMapper(ComponentModel mapperModel, LDAPStorageProvider federationProvider, RealmModel realm) { + return new MSADLDSUserAccountControlStorageMapper(mapperModel, federationProvider, realm); + } +} diff --git a/federation/ldap/src/main/resources/META-INF/services/org.keycloak.storage.ldap.mappers.LDAPStorageMapperFactory b/federation/ldap/src/main/resources/META-INF/services/org.keycloak.storage.ldap.mappers.LDAPStorageMapperFactory index 6f3f5ae3b0..3781e87bf3 100644 --- a/federation/ldap/src/main/resources/META-INF/services/org.keycloak.storage.ldap.mappers.LDAPStorageMapperFactory +++ b/federation/ldap/src/main/resources/META-INF/services/org.keycloak.storage.ldap.mappers.LDAPStorageMapperFactory @@ -20,4 +20,5 @@ org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapperFactory org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory org.keycloak.storage.ldap.mappers.msad.MSADUserAccountControlStorageMapperFactory +org.keycloak.storage.ldap.mappers.msadlds.MSADLDSUserAccountControlStorageMapperFactory org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapperFactory diff --git a/federation/pom.xml b/federation/pom.xml index 0d592a3b9f..b7766646fd 100755 --- a/federation/pom.xml +++ b/federation/pom.xml @@ -22,7 +22,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/federation/sssd/pom.xml b/federation/sssd/pom.xml index 789bbe2c2d..9e4d2c33d7 100644 --- a/federation/sssd/pom.xml +++ b/federation/sssd/pom.xml @@ -4,7 +4,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/integration/admin-client/pom.xml b/integration/admin-client/pom.xml index 3c3924656b..507619bc57 100755 --- a/integration/admin-client/pom.xml +++ b/integration/admin-client/pom.xml @@ -22,7 +22,7 @@ keycloak-integration-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/integration/client-cli/client-cli-dist/pom.xml b/integration/client-cli/client-cli-dist/pom.xml index b6fdbf39af..1b567cb529 100755 --- a/integration/client-cli/client-cli-dist/pom.xml +++ b/integration/client-cli/client-cli-dist/pom.xml @@ -21,7 +21,7 @@ keycloak-client-cli-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-client-cli-dist diff --git a/integration/client-cli/client-registration-cli/pom.xml b/integration/client-cli/client-registration-cli/pom.xml index f1f95d0944..dc5c210237 100755 --- a/integration/client-cli/client-registration-cli/pom.xml +++ b/integration/client-cli/client-registration-cli/pom.xml @@ -21,7 +21,7 @@ keycloak-client-cli-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/integration/client-cli/pom.xml b/integration/client-cli/pom.xml index 64a78e4305..4759514b25 100644 --- a/integration/client-cli/pom.xml +++ b/integration/client-cli/pom.xml @@ -20,7 +20,7 @@ keycloak-integration-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT Keycloak Client CLI diff --git a/integration/client-registration/pom.xml b/integration/client-registration/pom.xml index 7e101921ae..45e4690331 100755 --- a/integration/client-registration/pom.xml +++ b/integration/client-registration/pom.xml @@ -21,7 +21,7 @@ keycloak-integration-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/integration/pom.xml b/integration/pom.xml index 44422df0a9..863eadea56 100755 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml Keycloak Integration diff --git a/model/infinispan/pom.xml b/model/infinispan/pom.xml index 287dd99a37..ef3ceceae7 100755 --- a/model/infinispan/pom.xml +++ b/model/infinispan/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/model/infinispan/src/main/java/org/keycloak/keys/infinispan/InfinispanPublicKeyStorageProvider.java b/model/infinispan/src/main/java/org/keycloak/keys/infinispan/InfinispanPublicKeyStorageProvider.java index edfd392c6c..b5f48cd5bb 100644 --- a/model/infinispan/src/main/java/org/keycloak/keys/infinispan/InfinispanPublicKeyStorageProvider.java +++ b/model/infinispan/src/main/java/org/keycloak/keys/infinispan/InfinispanPublicKeyStorageProvider.java @@ -55,12 +55,13 @@ public class InfinispanPublicKeyStorageProvider implements PublicKeyStorageProvi private Set invalidations = new HashSet<>(); + private boolean transactionEnlisted = false; + public InfinispanPublicKeyStorageProvider(KeycloakSession session, Cache keys, Map> tasksInProgress, int minTimeBetweenRequests) { this.session = session; this.keys = keys; this.tasksInProgress = tasksInProgress; this.minTimeBetweenRequests = minTimeBetweenRequests; - session.getTransactionManager().enlistAfterCompletion(getAfterTransaction()); } @@ -73,6 +74,11 @@ public class InfinispanPublicKeyStorageProvider implements PublicKeyStorageProvi void addInvalidation(String cacheKey) { + if (!transactionEnlisted) { + session.getTransactionManager().enlistAfterCompletion(getAfterTransaction()); + transactionEnlisted = true; + } + this.invalidations.add(cacheKey); } diff --git a/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java b/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java index ffd355c8a8..77dd98952f 100644 --- a/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java +++ b/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java @@ -45,7 +45,6 @@ import org.keycloak.keys.PublicKeyLoader; /** * @author Marek Posolda */ -@Ignore public class InfinispanKeyStorageProviderTest { private Map counters = new ConcurrentHashMap<>(); diff --git a/model/jpa/pom.xml b/model/jpa/pom.xml index 8bca064c4b..ea50a668b9 100755 --- a/model/jpa/pom.xml +++ b/model/jpa/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/model/mongo/pom.xml b/model/mongo/pom.xml index 4f3a1c11ea..6bfb882bda 100755 --- a/model/mongo/pom.xml +++ b/model/mongo/pom.xml @@ -22,7 +22,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/model/pom.xml b/model/pom.xml index 7bbd07e1e6..a89dcb72d9 100755 --- a/model/pom.xml +++ b/model/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml Keycloak Model Parent diff --git a/pom.xml b/pom.xml index 277f016c60..55bb4f842e 100755 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ org.keycloak keycloak-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT pom diff --git a/proxy/launcher/pom.xml b/proxy/launcher/pom.xml index 5821286acb..7b33d0993a 100755 --- a/proxy/launcher/pom.xml +++ b/proxy/launcher/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/proxy/pom.xml b/proxy/pom.xml index b21e506d1e..2009021fd9 100755 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -20,7 +20,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml Model Parent diff --git a/proxy/proxy-server/pom.xml b/proxy/proxy-server/pom.xml index 37d91bd85c..9d19ccd518 100755 --- a/proxy/proxy-server/pom.xml +++ b/proxy/proxy-server/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/saml-core-api/pom.xml b/saml-core-api/pom.xml index 914e893f3f..7bdc5688a2 100755 --- a/saml-core-api/pom.xml +++ b/saml-core-api/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/saml-core/pom.xml b/saml-core/pom.xml index 7cb185199a..a93790a926 100755 --- a/saml-core/pom.xml +++ b/saml-core/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/server-spi-private/pom.xml b/server-spi-private/pom.xml index 60c73a3e56..5551600c9a 100755 --- a/server-spi-private/pom.xml +++ b/server-spi-private/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/server-spi-private/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java b/server-spi-private/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java index f7a26e9899..f2c8a7aad7 100755 --- a/server-spi-private/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java +++ b/server-spi-private/src/main/java/org/keycloak/broker/provider/BrokeredIdentityContext.java @@ -161,6 +161,10 @@ public class BrokeredIdentityContext { getContextData().put(Constants.USER_ATTRIBUTES_PREFIX + attributeName, list); } + public void setUserAttribute(String attributeName, List attributeValues) { + getContextData().put(Constants.USER_ATTRIBUTES_PREFIX + attributeName, attributeValues); + } + public String getUserAttribute(String attributeName) { List userAttribute = (List) getContextData().get(Constants.USER_ATTRIBUTES_PREFIX + attributeName); if (userAttribute == null || userAttribute.isEmpty()) { diff --git a/server-spi-private/src/main/java/org/keycloak/models/LDAPConstants.java b/server-spi-private/src/main/java/org/keycloak/models/LDAPConstants.java index b560e1844e..08be1c1bd2 100644 --- a/server-spi-private/src/main/java/org/keycloak/models/LDAPConstants.java +++ b/server-spi-private/src/main/java/org/keycloak/models/LDAPConstants.java @@ -26,6 +26,7 @@ public class LDAPConstants { public static final String LDAP_PROVIDER = "ldap"; public static final String MSAD_USER_ACCOUNT_CONTROL_MAPPER = "msad-user-account-control-mapper"; + public static final String MSADLDS_USER_ACCOUNT_CONTROL_MAPPER = "msad-lds-user-account-control-mapper"; public static final String VENDOR = "vendor"; public static final String VENDOR_RHDS = "rhds"; @@ -93,6 +94,9 @@ public class LDAPConstants { public static final String GROUP_OF_UNIQUE_NAMES = "groupOfUniqueNames"; public static final String USER_ACCOUNT_CONTROL = "userAccountControl"; public static final String PWD_LAST_SET = "pwdLastSet"; + public static final String MSDS_USER_ACCOUNT_DISABLED = "msDS-UserAccountDisabled"; + public static final String MSDS_USER_PASSWORD_NOTREQD = "msDS-UserPasswordNotRequired"; + public static final String MSDS_USER_PASSWORD_EXPIRED = "msDS-UserPasswordExpired"; // read-only public static final String COMMA = ","; public static final String EQUAL = "="; diff --git a/server-spi-private/src/main/java/org/keycloak/services/managers/ClientSessionCode.java b/server-spi-private/src/main/java/org/keycloak/services/managers/ClientSessionCode.java index 2710174088..1369e27014 100755 --- a/server-spi-private/src/main/java/org/keycloak/services/managers/ClientSessionCode.java +++ b/server-spi-private/src/main/java/org/keycloak/services/managers/ClientSessionCode.java @@ -18,22 +18,16 @@ package org.keycloak.services.managers; import org.jboss.logging.Logger; -import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.Time; -import org.keycloak.jose.jws.Algorithm; -import org.keycloak.jose.jws.crypto.RSAProvider; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientSessionModel; import org.keycloak.models.ClientTemplateModel; -import org.keycloak.models.KeyManager; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.utils.KeycloakModelUtils; -import java.security.PublicKey; -import java.security.Signature; import java.util.HashSet; import java.util.Set; @@ -43,6 +37,8 @@ import java.util.Set; */ public class ClientSessionCode { + private static final String ACTIVE_CODE = "active_code"; + private static final Logger logger = Logger.getLogger(ClientSessionCode.class); private static final String NEXT_CODE = ClientSessionCode.class.getName() + ".nextCode"; @@ -99,7 +95,7 @@ public class ClientSessionCode { return result; } - if (!verifyCode(code, session, realm, result.clientSession)) { + if (!verifyCode(code, result.clientSession)) { result.illegalHash = true; return result; } @@ -119,7 +115,7 @@ public class ClientSessionCode { return null; } - if (!verifyCode(code, session, realm, clientSession)) { + if (!verifyCode(code, clientSession)) { return null; } @@ -215,7 +211,7 @@ public class ClientSessionCode { public String getCode() { String nextCode = (String) session.getAttribute(NEXT_CODE + "." + clientSession.getId()); if (nextCode == null) { - nextCode = generateCode(session, realm, clientSession); + nextCode = generateCode(clientSession); session.setAttribute(NEXT_CODE + "." + clientSession.getId(), nextCode); } else { logger.debug("Code already generated for session, using code from session attributes"); @@ -223,30 +219,18 @@ public class ClientSessionCode { return nextCode; } - private static String generateCode(KeycloakSession session, RealmModel realm, ClientSessionModel clientSession) { + private static String generateCode(ClientSessionModel clientSession) { try { - KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); - - String secret = KeycloakModelUtils.generateSecret(); + String actionId = KeycloakModelUtils.generateSecret(); StringBuilder sb = new StringBuilder(); - sb.append(secret); + sb.append(actionId); sb.append('.'); sb.append(clientSession.getId()); String code = sb.toString(); - Signature signature = RSAProvider.getSignature(Algorithm.RS256); - signature.initSign(keys.getPrivateKey()); - signature.update(code.getBytes("utf-8")); - - sb = new StringBuilder(); - - sb.append(Base64Url.encode(signature.sign())); - sb.append('.'); - sb.append(keys.getKid()); - - clientSession.setNote(ClientSessionModel.ACTION_SIGNATURE, sb.toString()); + clientSession.setNote(ACTIVE_CODE, code); return code; } catch (Exception e) { @@ -254,24 +238,17 @@ public class ClientSessionCode { } } - private static boolean verifyCode(String code, KeycloakSession session, RealmModel realm, ClientSessionModel clientSession) { + private static boolean verifyCode(String code, ClientSessionModel clientSession) { try { - String note = clientSession.getNote(ClientSessionModel.ACTION_SIGNATURE); - if (note == null) { - logger.debug("Action signature not found in client session"); + String activeCode = clientSession.getNote(ACTIVE_CODE); + if (activeCode == null) { + logger.debug("Active code not found in client session"); return false; } - clientSession.removeNote(ClientSessionModel.ACTION_SIGNATURE); + clientSession.removeNote(ACTIVE_CODE); - String[] signed = note.split("\\."); - - PublicKey publicKey = session.keys().getPublicKey(realm, signed[1]); - - Signature verifier = RSAProvider.getSignature(Algorithm.RS256); - verifier.initVerify(publicKey); - verifier.update(code.getBytes("utf-8")); - return verifier.verify(Base64Url.decode(signed[0])); + return code.equals(activeCode); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/server-spi/pom.xml b/server-spi/pom.xml index 41a118272a..0e8c9400fa 100755 --- a/server-spi/pom.xml +++ b/server-spi/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/server-spi/src/main/java/org/keycloak/models/ClientSessionModel.java b/server-spi/src/main/java/org/keycloak/models/ClientSessionModel.java index 6b7e9d5715..84fa64e1c1 100755 --- a/server-spi/src/main/java/org/keycloak/models/ClientSessionModel.java +++ b/server-spi/src/main/java/org/keycloak/models/ClientSessionModel.java @@ -24,7 +24,6 @@ import java.util.Set; * @author Stian Thorgersen */ public interface ClientSessionModel { - public static final String ACTION_SIGNATURE = "action_signature"; public String getId(); public RealmModel getRealm(); diff --git a/services/pom.xml b/services/pom.xml index 5f89ececcc..ad25f69f01 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java index 3b409a04c5..2f23cb82a4 100755 --- a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java +++ b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java @@ -802,7 +802,7 @@ public class AuthenticationProcessor { * */ public void setActionSuccessful() { - oneActionWasSuccessful = true; +// oneActionWasSuccessful = true; } public Response checkWasSuccessfulBrowserAction() { diff --git a/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractClaimMapper.java b/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractClaimMapper.java index feb51b67c9..f2b52882fe 100755 --- a/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractClaimMapper.java +++ b/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractClaimMapper.java @@ -76,7 +76,7 @@ public abstract class AbstractClaimMapper extends AbstractIdentityProviderMapper { // Search the OIDC UserInfo claim set (if any) JsonNode profileJsonNode = (JsonNode) context.getContextData().get(OIDCIdentityProvider.USER_INFO); - String value = AbstractJsonUserAttributeMapper.getJsonValue(profileJsonNode, claim); + Object value = AbstractJsonUserAttributeMapper.getJsonValue(profileJsonNode, claim); if (value != null) return value; } return null; diff --git a/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java b/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java index e718a0d7f7..49e145cf0b 100755 --- a/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java +++ b/services/src/main/java/org/keycloak/broker/oidc/mappers/AbstractJsonUserAttributeMapper.java @@ -35,7 +35,7 @@ import java.util.List; * Abstract class for Social Provider mappers which allow mapping of JSON user profile field into Keycloak user * attribute. Concrete mapper classes with own ID and provider mapping must be implemented for each social provider who * uses {@link JsonNode} user profile. - * + * * @author Vlastimil Elias (velias at redhat dot com) */ public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityProviderMapper { @@ -81,8 +81,8 @@ public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityPr } /** - * Store used profile JsonNode into user context for later use by this mapper. Profile data are dumped into special logger if enabled also to allow investigation of the structure. - * + * Store used profile JsonNode into user context for later use by this mapper. Profile data are dumped into special logger if enabled also to allow investigation of the structure. + * * @param user context to store profile data into * @param profile to store into context * @param provider identification of social provider to be used in log dump @@ -125,9 +125,13 @@ public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityPr } attribute = attribute.trim(); - String value = getJsonValue(mapperModel, context); + Object value = getJsonValue(mapperModel, context); if (value != null) { - context.setUserAttribute(attribute, value); + if (value instanceof List) { + context.setUserAttribute(attribute, (List) value); + } else { + context.setUserAttribute(attribute, value.toString()); + } } } @@ -136,7 +140,7 @@ public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityPr // we do not update user profile from social provider } - protected static String getJsonValue(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { + protected static Object getJsonValue(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { String jsonField = mapperModel.getConfig().get(CONF_JSON_FIELD); if (jsonField == null || jsonField.trim().isEmpty()) { @@ -152,7 +156,7 @@ public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityPr JsonNode profileJsonNode = (JsonNode) context.getContextData().get(CONTEXT_JSON_NODE); - String value = getJsonValue(profileJsonNode, jsonField); + Object value = getJsonValue(profileJsonNode, jsonField); if (value == null) { logger.debugf("User profile JSON value '%s' is not available.", jsonField); @@ -161,7 +165,7 @@ public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityPr return value; } - public static String getJsonValue(JsonNode baseNode, String fieldPath) { + public static Object getJsonValue(JsonNode baseNode, String fieldPath) { logger.debug("Going to process JsonNode path " + fieldPath + " on data " + baseNode); if (baseNode != null) { @@ -206,6 +210,20 @@ public abstract class AbstractJsonUserAttributeMapper extends AbstractIdentityPr } if (idx < 0) { + if (currentNode.isArray()) { + List values = new ArrayList<>(); + for (JsonNode childNode : currentNode) { + if (childNode.isTextual()) { + values.add(childNode.textValue()); + } else { + logger.warn("JsonNode in array is not text value " + childNode); + } + } + if (values.isEmpty()) { + return null; + } + return arrayIndex == idx? values : null; + } if (!currentNode.isValueNode()) { logger.debug("JsonNode is not value node for name " + currentFieldName); return null; diff --git a/services/src/main/java/org/keycloak/broker/oidc/mappers/UserAttributeMapper.java b/services/src/main/java/org/keycloak/broker/oidc/mappers/UserAttributeMapper.java index 52ad5de33f..2e2abcae29 100755 --- a/services/src/main/java/org/keycloak/broker/oidc/mappers/UserAttributeMapper.java +++ b/services/src/main/java/org/keycloak/broker/oidc/mappers/UserAttributeMapper.java @@ -20,14 +20,20 @@ package org.keycloak.broker.oidc.mappers; import org.keycloak.broker.oidc.KeycloakOIDCIdentityProviderFactory; import org.keycloak.broker.oidc.OIDCIdentityProviderFactory; import org.keycloak.broker.provider.BrokeredIdentityContext; +import org.keycloak.common.util.CollectionUtil; import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.saml.common.util.StringUtil; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.stream.Collectors; /** * @author Bill Burke @@ -37,9 +43,12 @@ public class UserAttributeMapper extends AbstractClaimMapper { public static final String[] COMPATIBLE_PROVIDERS = {KeycloakOIDCIdentityProviderFactory.PROVIDER_ID, OIDCIdentityProviderFactory.PROVIDER_ID}; - private static final List configProperties = new ArrayList(); + private static final List configProperties = new ArrayList<>(); public static final String USER_ATTRIBUTE = "user.attribute"; + public static final String EMAIL = "email"; + public static final String FIRST_NAME = "firstName"; + public static final String LAST_NAME = "lastName"; static { ProviderConfigProperty property; @@ -88,37 +97,63 @@ public class UserAttributeMapper extends AbstractClaimMapper { @Override public void preprocessFederatedIdentity(KeycloakSession session, RealmModel realm, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { String attribute = mapperModel.getConfig().get(USER_ATTRIBUTE); - Object value = getClaimValue(mapperModel, context); - if (value != null) { - if (attribute.equalsIgnoreCase("email")) { - context.setEmail(value.toString()); - } else if (attribute.equalsIgnoreCase("firstName")) { - context.setFirstName(value.toString()); - } else if (attribute.equalsIgnoreCase("lastName")) { - context.setLastName(value.toString()); - } else { - context.setUserAttribute(attribute, value.toString()); - } + if(StringUtil.isNullOrEmpty(attribute)){ + return; } + Object value = getClaimValue(mapperModel, context); + List values = toList(value); + + if (EMAIL.equalsIgnoreCase(attribute)) { + setIfNotEmpty(context::setEmail, values); + } else if (FIRST_NAME.equalsIgnoreCase(attribute)) { + setIfNotEmpty(context::setFirstName, values); + } else if (LAST_NAME.equalsIgnoreCase(attribute)) { + setIfNotEmpty(context::setLastName, values); + } else { + List valuesToString = values.stream() + .filter(Objects::nonNull) + .map(Object::toString) + .collect(Collectors.toList()); + + context.setUserAttribute(attribute, valuesToString); + } + } + + private void setIfNotEmpty(Consumer consumer, List values) { + if (values != null && !values.isEmpty()) { + consumer.accept(values.get(0)); + } + } + + private List toList(Object value) { + List values = (value instanceof List) + ? (List) value + : Collections.singletonList(value); + return values.stream() + .filter(Objects::nonNull) + .map(Object::toString) + .collect(Collectors.toList()); } @Override public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { String attribute = mapperModel.getConfig().get(USER_ATTRIBUTE); + if(StringUtil.isNullOrEmpty(attribute)){ + return; + } Object value = getClaimValue(mapperModel, context); - String stringValue = null; - if (value != null) stringValue = value.toString(); - if (attribute.equalsIgnoreCase("email")) { - user.setEmail(stringValue); - } else if (attribute.equalsIgnoreCase("firstName")) { - user.setFirstName(stringValue); - } else if (attribute.equalsIgnoreCase("lastName")) { - user.setLastName(stringValue); + List values = toList(value); + if (EMAIL.equalsIgnoreCase(attribute)) { + setIfNotEmpty(user::setEmail, values); + } else if (FIRST_NAME.equalsIgnoreCase(attribute)) { + setIfNotEmpty(user::setFirstName, values); + } else if (LAST_NAME.equalsIgnoreCase(attribute)) { + setIfNotEmpty(user::setLastName, values); } else { - String current = user.getFirstAttribute(attribute); - if (stringValue != null && !stringValue.equals(current)) { - user.setSingleAttribute(attribute, stringValue); - } else if (value == null) { + List current = user.getAttribute(attribute); + if (!CollectionUtil.collectionEquals(values, current)) { + user.setAttribute(attribute, values); + } else if (values.isEmpty()) { user.removeAttribute(attribute); } } diff --git a/services/src/main/java/org/keycloak/broker/saml/mappers/UserAttributeMapper.java b/services/src/main/java/org/keycloak/broker/saml/mappers/UserAttributeMapper.java index 70cae078e5..8a71493fe5 100755 --- a/services/src/main/java/org/keycloak/broker/saml/mappers/UserAttributeMapper.java +++ b/services/src/main/java/org/keycloak/broker/saml/mappers/UserAttributeMapper.java @@ -21,17 +21,18 @@ import org.keycloak.broker.provider.AbstractIdentityProviderMapper; import org.keycloak.broker.provider.BrokeredIdentityContext; import org.keycloak.broker.saml.SAMLEndpoint; import org.keycloak.broker.saml.SAMLIdentityProviderFactory; +import org.keycloak.common.util.CollectionUtil; import org.keycloak.dom.saml.v2.assertion.AssertionType; import org.keycloak.dom.saml.v2.assertion.AttributeStatementType; import org.keycloak.dom.saml.v2.assertion.AttributeType; -import org.keycloak.models.IdentityProviderMapperModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; +import org.keycloak.models.*; import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.saml.common.util.StringUtil; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; /** * @author Bill Burke @@ -41,11 +42,14 @@ public class UserAttributeMapper extends AbstractIdentityProviderMapper { public static final String[] COMPATIBLE_PROVIDERS = {SAMLIdentityProviderFactory.PROVIDER_ID}; - private static final List configProperties = new ArrayList(); + private static final List configProperties = new ArrayList<>(); public static final String ATTRIBUTE_NAME = "attribute.name"; public static final String ATTRIBUTE_FRIENDLY_NAME = "attribute.friendly.name"; public static final String USER_ATTRIBUTE = "user.attribute"; + private static final String EMAIL = "email"; + private static final String FIRST_NAME = "firstName"; + private static final String LAST_NAME = "lastName"; static { ProviderConfigProperty property; @@ -99,61 +103,84 @@ public class UserAttributeMapper extends AbstractIdentityProviderMapper { @Override public void preprocessFederatedIdentity(KeycloakSession session, RealmModel realm, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { String attribute = mapperModel.getConfig().get(USER_ATTRIBUTE); - String value = getAttribute(mapperModel, context); - if (value != null) { - if (attribute.equalsIgnoreCase("email")) { - context.setEmail(value); - } else if (attribute.equalsIgnoreCase("firstName")) { - context.setFirstName(value); - } else if (attribute.equalsIgnoreCase("lastName")) { - context.setLastName(value); + if (StringUtil.isNullOrEmpty(attribute)) { + return; + } + String attributeName = getAttributeNameFromMapperModel(mapperModel); + + List attributeValuesInContext = findAttributeValuesInContext(attributeName, context); + if (!attributeValuesInContext.isEmpty()) { + if (attribute.equalsIgnoreCase(EMAIL)) { + setIfNotEmpty(context::setEmail, attributeValuesInContext); + } else if (attribute.equalsIgnoreCase(FIRST_NAME)) { + setIfNotEmpty(context::setFirstName, attributeValuesInContext); + } else if (attribute.equalsIgnoreCase(LAST_NAME)) { + setIfNotEmpty(context::setLastName, attributeValuesInContext); } else { - context.setUserAttribute(attribute, value); + context.setUserAttribute(attribute, attributeValuesInContext); } } } - protected String getAttribute(IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { - String name = mapperModel.getConfig().get(ATTRIBUTE_NAME); - if (name != null && name.trim().equals("")) name = null; - String friendly = mapperModel.getConfig().get(ATTRIBUTE_FRIENDLY_NAME); - if (friendly != null && friendly.trim().equals("")) friendly = null; - AssertionType assertion = (AssertionType)context.getContextData().get(SAMLEndpoint.SAML_ASSERTION); - for (AttributeStatementType statement : assertion.getAttributeStatements()) { - for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) { - AttributeType attr = choice.getAttribute(); - if (name != null && !name.equals(attr.getName())) continue; - if (friendly != null && !friendly.equals(attr.getFriendlyName())) continue; - - List attributeValue = attr.getAttributeValue(); - if (attributeValue == null || attributeValue.isEmpty()) return null; - return attributeValue.get(0).toString(); - } + private String getAttributeNameFromMapperModel(IdentityProviderMapperModel mapperModel) { + String attributeName = mapperModel.getConfig().get(ATTRIBUTE_NAME); + if (attributeName == null) { + attributeName = mapperModel.getConfig().get(ATTRIBUTE_FRIENDLY_NAME); } - return null; + return attributeName; + } + + private void setIfNotEmpty(Consumer consumer, List values) { + if (values != null && !values.isEmpty()) { + consumer.accept(values.get(0)); + } + } + + private Predicate elementWith(String attributeName) { + return attributeType -> { + AttributeType attribute = attributeType.getAttribute(); + return Objects.equals(attribute.getName(), attributeName) + || Objects.equals(attribute.getFriendlyName(), attributeName); + }; + } + + + private List findAttributeValuesInContext(String attributeName, BrokeredIdentityContext context) { + AssertionType assertion = (AssertionType) context.getContextData().get(SAMLEndpoint.SAML_ASSERTION); + + return assertion.getAttributeStatements().stream() + .flatMap(statement -> statement.getAttributes().stream()) + .filter(elementWith(attributeName)) + .flatMap(attributeType -> attributeType.getAttribute().getAttributeValue().stream()) + .filter(Objects::nonNull) + .map(Object::toString) + .collect(Collectors.toList()); } @Override public void updateBrokeredUser(KeycloakSession session, RealmModel realm, UserModel user, IdentityProviderMapperModel mapperModel, BrokeredIdentityContext context) { String attribute = mapperModel.getConfig().get(USER_ATTRIBUTE); - String value = getAttribute(mapperModel, context); - if (attribute.equalsIgnoreCase("email")) { - user.setEmail(value); - } else if (attribute.equalsIgnoreCase("firstName")) { - user.setFirstName(value); - } else if (attribute.equalsIgnoreCase("lastName")) { - user.setLastName(value); + if (StringUtil.isNullOrEmpty(attribute)) { + return; + } + String attributeName = getAttributeNameFromMapperModel(mapperModel); + List attributeValuesInContext = findAttributeValuesInContext(attributeName, context); + if (attribute.equalsIgnoreCase(EMAIL)) { + setIfNotEmpty(user::setEmail, attributeValuesInContext); + } else if (attribute.equalsIgnoreCase(FIRST_NAME)) { + setIfNotEmpty(user::setFirstName, attributeValuesInContext); + } else if (attribute.equalsIgnoreCase(LAST_NAME)) { + setIfNotEmpty(user::setLastName, attributeValuesInContext); } else { - String current = user.getFirstAttribute(attribute); - if (value != null && !value.equals(current)) { - user.setSingleAttribute(attribute, value.toString()); - } else if (value == null) { + List currentAttributeValues = user.getAttributes().get(attribute); + if (attributeValuesInContext != null + && currentAttributeValues != null + && !CollectionUtil.collectionEquals(attributeValuesInContext, currentAttributeValues)) { + user.setAttribute(attribute, attributeValuesInContext); + } else if (attributeValuesInContext == null) { user.removeAttribute(attribute); } } - - - } @Override diff --git a/services/src/main/java/org/keycloak/partialimport/ClientRolesPartialImport.java b/services/src/main/java/org/keycloak/partialimport/ClientRolesPartialImport.java index 008917da7c..95fa4a6645 100644 --- a/services/src/main/java/org/keycloak/partialimport/ClientRolesPartialImport.java +++ b/services/src/main/java/org/keycloak/partialimport/ClientRolesPartialImport.java @@ -103,6 +103,11 @@ public class ClientRolesPartialImport { return; } RoleModel role = client.getRole(getName(roleRep)); + if (role == null) { + // role might not exist if client was just created as part of the + // partial import + return; + } client.removeRole(role); } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java index c67160794b..5e48c7bc7d 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java @@ -38,6 +38,7 @@ import org.keycloak.models.GroupModel; import org.keycloak.models.KeyManager; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.models.ModelException; import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; @@ -130,15 +131,24 @@ public class TokenManager { if (TokenUtil.TOKEN_TYPE_OFFLINE.equals(oldToken.getType())) { UserSessionManager sessionManager = new UserSessionManager(session); - clientSession = sessionManager.findOfflineClientSession(realm, oldToken.getClientSession(), oldToken.getSessionState()); + clientSession = sessionManager.findOfflineClientSession(realm, oldToken.getClientSession()); if (clientSession != null) { userSession = clientSession.getUserSession(); + if (userSession == null) { + throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline user session not found", "Offline user session not found"); + } + + String userSessionId = oldToken.getSessionState(); + if (!userSessionId.equals(userSession.getId())) { + throw new ModelException("User session don't match. Offline client session " + clientSession.getId() + ", It's user session " + userSession.getId() + + " Wanted user session: " + userSessionId); + } + // Revoke timeouted offline userSession if (userSession.getLastSessionRefresh() < Time.currentTime() - realm.getOfflineSessionIdleTimeout()) { sessionManager.revokeOfflineUserSession(userSession); - userSession = null; - clientSession = null; + throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline user session not active", "Offline user session session not active"); } } } else { diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java index 674c9ff10c..2f40c21829 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java @@ -17,14 +17,11 @@ package org.keycloak.protocol.oidc.mappers; -import org.keycloak.models.ClientSessionModel; -import org.keycloak.models.KeycloakSession; import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.provider.ProviderConfigProperty; -import org.keycloak.representations.AccessToken; import org.keycloak.representations.AddressClaimSet; import org.keycloak.representations.IDToken; @@ -34,7 +31,6 @@ import java.util.List; import java.util.Map; /** - * Set the 'name' claim to be first + last name. * * @author Bill Burke * @version $Revision: 1 $ @@ -43,26 +39,39 @@ public class AddressMapper extends AbstractOIDCProtocolMapper implements OIDCAcc private static final List configProperties = new ArrayList(); + public static final String STREET = "street"; + static { OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, AddressMapper.class); + + configProperties.add(createConfigProperty(STREET)); + configProperties.add(createConfigProperty(AddressClaimSet.LOCALITY)); + configProperties.add(createConfigProperty(AddressClaimSet.REGION)); + configProperties.add(createConfigProperty(AddressClaimSet.POSTAL_CODE)); + configProperties.add(createConfigProperty(AddressClaimSet.COUNTRY)); + configProperties.add(createConfigProperty(AddressClaimSet.FORMATTED)); + } + + protected static ProviderConfigProperty createConfigProperty(String claimName) { + ProviderConfigProperty property = new ProviderConfigProperty(); + property.setName(getModelPropertyName(claimName)); + property.setLabel("addressClaim." + claimName + ".label"); + property.setHelpText("addressClaim." + claimName + ".tooltip"); + property.setType(ProviderConfigProperty.STRING_TYPE); + property.setDefaultValue(claimName); + return property; + } + + public static String getModelPropertyName(String claimName) { + return "user.attribute." + claimName; } public static final String PROVIDER_ID = "oidc-address-mapper"; public static ProtocolMapperModel createAddressMapper() { - Map config; - ProtocolMapperModel address = new ProtocolMapperModel(); - address.setName("address"); - address.setProtocolMapper(PROVIDER_ID); - address.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); - address.setConsentRequired(true); - address.setConsentText("${address}"); - config = new HashMap(); - config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); - config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); - address.setConfig(config); - return address; + return createAddressMapper(true, true); } + public static ProtocolMapperModel createAddressMapper(boolean idToken, boolean accessToken) { Map config; ProtocolMapperModel address = new ProtocolMapperModel(); @@ -74,6 +83,14 @@ public class AddressMapper extends AbstractOIDCProtocolMapper implements OIDCAcc config = new HashMap(); config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, Boolean.toString(idToken)); config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, Boolean.toString(accessToken)); + + config.put(getModelPropertyName(STREET), STREET); + config.put(getModelPropertyName(AddressClaimSet.LOCALITY), AddressClaimSet.LOCALITY); + config.put(getModelPropertyName(AddressClaimSet.REGION), AddressClaimSet.REGION); + config.put(getModelPropertyName(AddressClaimSet.POSTAL_CODE), AddressClaimSet.POSTAL_CODE); + config.put(getModelPropertyName(AddressClaimSet.COUNTRY), AddressClaimSet.COUNTRY); + config.put(getModelPropertyName(AddressClaimSet.FORMATTED), AddressClaimSet.FORMATTED); + address.setConfig(config); return address; } @@ -107,12 +124,24 @@ public class AddressMapper extends AbstractOIDCProtocolMapper implements OIDCAcc protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) { UserModel user = userSession.getUser(); AddressClaimSet addressSet = new AddressClaimSet(); - addressSet.setStreetAddress(user.getFirstAttribute("street")); - addressSet.setLocality(user.getFirstAttribute("locality")); - addressSet.setRegion(user.getFirstAttribute("region")); - addressSet.setPostalCode(user.getFirstAttribute("postal_code")); - addressSet.setCountry(user.getFirstAttribute("country")); + addressSet.setStreetAddress(getUserModelAttributeValue(user, mappingModel, STREET)); + addressSet.setLocality(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.LOCALITY)); + addressSet.setRegion(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.REGION)); + addressSet.setPostalCode(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.POSTAL_CODE)); + addressSet.setCountry(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.COUNTRY)); + addressSet.setFormattedAddress(getUserModelAttributeValue(user, mappingModel, AddressClaimSet.FORMATTED)); token.getOtherClaims().put("address", addressSet); } + private String getUserModelAttributeValue(UserModel user, ProtocolMapperModel mappingModel, String claim) { + String modelPropertyName = getModelPropertyName(claim); + String userAttrName = mappingModel.getConfig().get(modelPropertyName); + + if (userAttrName == null) { + userAttrName = claim; + } + + return user.getFirstAttribute(userAttrName); + } + } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java index 8b64aef891..7b8ba36716 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java @@ -25,10 +25,9 @@ import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.representations.IDToken; import org.keycloak.services.ServicesLogger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; /** * @author Bill Burke @@ -70,29 +69,78 @@ public class OIDCAttributeMapperHelper { ServicesLogger.LOGGER.multipleValuesForMapper(attributeValue.toString(), mappingModel.getName()); } - attributeValue = valueAsList.get(0); + attributeValue = valueAsList; } } String type = mappingModel.getConfig().get(JSON_TYPE); + Object converted = convertToType(type, attributeValue); + return converted != null ? converted : attributeValue; + } + + private static List transform(List attributeValue, Function mapper) { + return attributeValue.stream() + .filter(Objects::nonNull) + .map(mapper) + .collect(Collectors.toList()); + } + + private static Object convertToType(String type, Object attributeValue) { if (type == null) return attributeValue; - if (type.equals("boolean")) { - if (attributeValue instanceof Boolean) return attributeValue; - if (attributeValue instanceof String) return Boolean.valueOf((String)attributeValue); - throw new RuntimeException("cannot map type for token claim"); - } else if (type.equals("String")) { - if (attributeValue instanceof String) return attributeValue; - return attributeValue.toString(); - } else if (type.equals("long")) { - if (attributeValue instanceof Long) return attributeValue; - if (attributeValue instanceof String) return Long.valueOf((String)attributeValue); - throw new RuntimeException("cannot map type for token claim"); - } else if (type.equals("int")) { - if (attributeValue instanceof Integer) return attributeValue; - if (attributeValue instanceof String) return Integer.valueOf((String)attributeValue); - throw new RuntimeException("cannot map type for token claim"); + switch (type) { + case "boolean": + Boolean booleanObject = getBoolean(attributeValue); + if (booleanObject != null) return booleanObject; + if (attributeValue instanceof List) { + return transform((List) attributeValue, OIDCAttributeMapperHelper::getBoolean); + } + throw new RuntimeException("cannot map type for token claim"); + case "String": + if (attributeValue instanceof String) return attributeValue; + if (attributeValue instanceof List) { + return transform((List) attributeValue, OIDCAttributeMapperHelper::getString); + } + return attributeValue.toString(); + case "long": + Long longObject = getLong(attributeValue); + if (longObject != null) return longObject; + if (attributeValue instanceof List) { + return transform((List) attributeValue, OIDCAttributeMapperHelper::getLong); + } + throw new RuntimeException("cannot map type for token claim"); + case "int": + Integer intObject = getInteger(attributeValue); + if (intObject != null) return intObject; + if (attributeValue instanceof List) { + return transform((List) attributeValue, OIDCAttributeMapperHelper::getInteger); + } + throw new RuntimeException("cannot map type for token claim"); + default: + return null; } - return attributeValue; + } + + private static String getString(Object attributeValue) { + return attributeValue.toString(); + } + + + private static Long getLong(Object attributeValue) { + if (attributeValue instanceof Long) return (Long) attributeValue; + if (attributeValue instanceof String) return Long.valueOf((String) attributeValue); + return null; + } + + private static Integer getInteger(Object attributeValue) { + if (attributeValue instanceof Integer) return (Integer) attributeValue; + if (attributeValue instanceof String) return Integer.valueOf((String) attributeValue); + return null; + } + + private static Boolean getBoolean(Object attributeValue) { + if (attributeValue instanceof Boolean) return (Boolean) attributeValue; + if (attributeValue instanceof String) return Boolean.valueOf((String) attributeValue); + return null; } public static void mapClaim(IDToken token, ProtocolMapperModel mappingModel, Object attributeValue) { diff --git a/services/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java b/services/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java index c1cf9c4b73..423cab9b94 100755 --- a/services/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java +++ b/services/src/main/java/org/keycloak/protocol/saml/mappers/AttributeStatementHelper.java @@ -52,6 +52,15 @@ public class AttributeStatementHelper { attributeStatement.addAttribute(new AttributeStatementType.ASTChoiceType(attribute)); } + public static void addAttributes(AttributeStatementType attributeStatement, ProtocolMapperModel mappingModel, + List attributeValues) { + + AttributeType attribute = createAttributeType(mappingModel); + attributeValues.forEach(attribute::addAttributeValue); + + attributeStatement.addAttribute(new AttributeStatementType.ASTChoiceType(attribute)); + } + public static AttributeType createAttributeType(ProtocolMapperModel mappingModel) { String attributeName = mappingModel.getConfig().get(SAML_ATTRIBUTE_NAME); AttributeType attribute = new AttributeType(attributeName); diff --git a/services/src/main/java/org/keycloak/protocol/saml/mappers/UserAttributeStatementMapper.java b/services/src/main/java/org/keycloak/protocol/saml/mappers/UserAttributeStatementMapper.java index 2340191c51..f29d972234 100755 --- a/services/src/main/java/org/keycloak/protocol/saml/mappers/UserAttributeStatementMapper.java +++ b/services/src/main/java/org/keycloak/protocol/saml/mappers/UserAttributeStatementMapper.java @@ -80,10 +80,9 @@ public class UserAttributeStatementMapper extends AbstractSAMLProtocolMapper imp public void transformAttributeStatement(AttributeStatementType attributeStatement, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession) { UserModel user = userSession.getUser(); String attributeName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_ATTRIBUTE); - String attributeValue = KeycloakModelUtils.resolveFirstAttribute(user, attributeName); - if (attributeValue == null) return; - AttributeStatementHelper.addAttribute(attributeStatement, mappingModel, attributeValue); - + List attributeValues = KeycloakModelUtils.resolveAttribute(user, attributeName); + if (attributeValues.isEmpty()) return; + AttributeStatementHelper.addAttributes(attributeStatement, mappingModel, attributeValues); } public static ProtocolMapperModel createAttributeMapper(String name, String userAttribute, diff --git a/services/src/main/java/org/keycloak/services/managers/ClientManager.java b/services/src/main/java/org/keycloak/services/managers/ClientManager.java index 1aa9b7f0f3..fec49c92c5 100644 --- a/services/src/main/java/org/keycloak/services/managers/ClientManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ClientManager.java @@ -195,6 +195,17 @@ public class ClientManager { } } + public void clientIdChanged(ClientModel client, String newClientId) { + logger.debugf("Updating clientId from '%s' to '%s'", client.getClientId(), newClientId); + + UserModel serviceAccountUser = realmManager.getSession().users().getServiceAccount(client); + if (serviceAccountUser != null) { + String username = ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + newClientId; + serviceAccountUser.setUsername(username); + serviceAccountUser.setEmail(username + "@placeholder.org"); + } + } + @JsonPropertyOrder({"realm", "realm-public-key", "bearer-only", "auth-server-url", "ssl-required", "resource", "public-client", "credentials", "use-resource-role-mappings"}) diff --git a/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java b/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java index e3ee409e49..4c8c2fe89e 100644 --- a/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java +++ b/services/src/main/java/org/keycloak/services/managers/UserSessionManager.java @@ -72,18 +72,8 @@ public class UserSessionManager { } // userSessionId is provided from offline token. It's used just to verify if it match the ID from clientSession representation - public ClientSessionModel findOfflineClientSession(RealmModel realm, String clientSessionId, String userSessionId) { - ClientSessionModel clientSession = kcSession.sessions().getOfflineClientSession(realm, clientSessionId); - if (clientSession == null) { - return null; - } - - if (!userSessionId.equals(clientSession.getUserSession().getId())) { - throw new ModelException("User session don't match. Offline client session " + clientSession.getId() + ", It's user session " + clientSession.getUserSession().getId() + - " Wanted user session: " + userSessionId); - } - - return clientSession; + public ClientSessionModel findOfflineClientSession(RealmModel realm, String clientSessionId) { + return kcSession.sessions().getOfflineClientSession(realm, clientSessionId); } public Set findClientsWithOfflineToken(RealmModel realm, UserModel user) { diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java index 7e0e11274b..2bdb1297da 100755 --- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java +++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java @@ -96,6 +96,7 @@ public class LoginActionsService { public static final String REQUIRED_ACTION = "required-action"; public static final String FIRST_BROKER_LOGIN_PATH = "first-broker-login"; public static final String POST_BROKER_LOGIN_PATH = "post-broker-login"; + public static final String LAST_PROCESSED_CODE = "last_processed_code"; private RealmModel realm; @@ -323,14 +324,22 @@ public class LoginActionsService { public Response authenticate(@QueryParam("code") String code, @QueryParam("execution") String execution) { event.event(EventType.LOGIN); - Checks checks = new Checks(); - if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) { - return checks.response; - } - event.detail(Details.CODE_ID, code); - ClientSessionCode clientSessionCode = checks.clientCode; - ClientSessionModel clientSession = clientSessionCode.getClientSession(); + ClientSessionModel clientSession = ClientSessionCode.getClientSession(code, session, realm); + if (clientSession != null && code.equals(clientSession.getNote(LAST_PROCESSED_CODE))) { + // Allow refresh of previous page + } else { + Checks checks = new Checks(); + if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) { + return checks.response; + } + + ClientSessionCode clientSessionCode = checks.clientCode; + clientSession = clientSessionCode.getClientSession(); + } + + event.detail(Details.CODE_ID, code); + clientSession.setNote(LAST_PROCESSED_CODE, code); return processAuthentication(execution, clientSession, null); } @@ -373,12 +382,21 @@ public class LoginActionsService { public Response authenticateForm(@QueryParam("code") String code, @QueryParam("execution") String execution) { event.event(EventType.LOGIN); + + ClientSessionModel clientSession = ClientSessionCode.getClientSession(code, session, realm); + if (clientSession != null && code.equals(clientSession.getNote(LAST_PROCESSED_CODE))) { + // Post already processed (refresh) - ignore form post and return next form + request.getFormParameters().clear(); + return authenticate(code, null); + } + Checks checks = new Checks(); if (!checks.verifyCode(code, ClientSessionModel.Action.AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) { return checks.response; } final ClientSessionCode clientCode = checks.clientCode; - final ClientSessionModel clientSession = clientCode.getClientSession(); + clientSession = clientCode.getClientSession(); + clientSession.setNote(LAST_PROCESSED_CODE, code); return processAuthentication(execution, clientSession, null); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java index 8928568ac6..1275022646 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java @@ -158,6 +158,10 @@ public class ClientResource { new ClientManager(new RealmManager(session)).enableServiceAccount(client); } + if (!rep.getClientId().equals(client.getClientId())) { + new ClientManager(new RealmManager(session)).clientIdChanged(client, rep.getClientId()); + } + RepresentationToModel.updateClient(rep, client); if (Profile.isPreviewEnabled()) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java index 8017b04a08..6c1779471a 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java @@ -56,8 +56,10 @@ import org.keycloak.theme.Theme; import org.keycloak.theme.ThemeProvider; import javax.ws.rs.GET; +import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import java.io.IOException; import java.util.Collections; import java.util.Comparator; @@ -83,6 +85,7 @@ public class ServerInfoAdminResource { * @return */ @GET + @Produces(MediaType.APPLICATION_JSON) public ServerInfoRepresentation getInfo() { ServerInfoRepresentation info = new ServerInfoRepresentation(); info.setSystemInfo(SystemInfoRepresentation.create(session.getKeycloakSessionFactory().getServerStartupTimestamp())); diff --git a/services/src/test/java/org/keycloak/test/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java b/services/src/test/java/org/keycloak/test/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java index 24c4cebcd6..786a528c43 100755 --- a/services/src/test/java/org/keycloak/test/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java +++ b/services/src/test/java/org/keycloak/test/broker/oidc/mappers/AbstractJsonUserAttributeMapperTest.java @@ -24,10 +24,11 @@ import org.junit.Test; import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper; import java.io.IOException; +import java.util.Arrays; /** * Unit test for {@link org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper} - * + * * @author Vlastimil Elias (velias at redhat dot com) */ public class AbstractJsonUserAttributeMapperTest { @@ -58,7 +59,7 @@ public class AbstractJsonUserAttributeMapperTest { //unknown field returns null Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_unknown")); - + // we check value is trimmed also! Assert.assertEquals("v1", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value1")); Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_empty")); @@ -95,14 +96,14 @@ public class AbstractJsonUserAttributeMapperTest { public void getJsonValue_simpleArray() throws JsonProcessingException, IOException { // array field itself returns null if no index is provided - Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array")); + Assert.assertEquals(Arrays.asList("a1", "a2"), AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array")); // outside index returns null Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[2]")); //corect index Assert.assertEquals("a1", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[0]")); Assert.assertEquals("a2", AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[1]")); - + //incorrect array constructs Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array[]")); Assert.assertNull(AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "value_array]")); @@ -125,7 +126,7 @@ public class AbstractJsonUserAttributeMapperTest { Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a.av1")); Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a].av1")); Assert.assertEquals(null, AbstractJsonUserAttributeMapper.getJsonValue(getJsonNode(), "nesta.a[.av1")); - + } } diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml index ccd3e12d02..5f7fe929af 100644 --- a/testsuite/integration-arquillian/pom.xml +++ b/testsuite/integration-arquillian/pom.xml @@ -24,7 +24,7 @@ org.keycloak keycloak-testsuite-pom - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/as7/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/as7/pom.xml index 94af0b3ea4..39d567b552 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/as7/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/as7/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/eap/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/eap/pom.xml index 7eff562af9..61a085a431 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/eap/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/eap/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/eap6-fuse/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/eap6-fuse/pom.xml index e60fbc1627..60fc6a223f 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/eap6-fuse/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/eap6-fuse/pom.xml @@ -5,7 +5,7 @@ integration-arquillian-servers-app-server-jboss org.keycloak.testsuite - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/eap6/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/eap6/pom.xml index 853845c471..2a47b31d24 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/eap6/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/eap6/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml index 49f0162966..a2c6b4a397 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/relative/eap/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/relative/eap/pom.xml index b0a62e0db6..360b73f41e 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/relative/eap/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/relative/eap/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss-relative - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/relative/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/relative/pom.xml index 767b21b29d..131fb8d3ab 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/relative/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/relative/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/relative/wildfly/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/relative/wildfly/pom.xml index 2fe4ad2a24..04b75f954c 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/relative/wildfly/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/relative/wildfly/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss-relative - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/wildfly/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/wildfly/pom.xml index 9f2b285fdc..7c59b1025b 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/wildfly/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/wildfly/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/wildfly8/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/wildfly8/pom.xml index d59b465364..5ea9125112 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/wildfly8/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/wildfly8/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/wildfly9/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/wildfly9/pom.xml index e6612faa1a..d1b80e92d9 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/wildfly9/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/jboss/wildfly9/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse61/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/fuse61/pom.xml index 52b44ec6aa..e6fb8dd090 100644 --- a/testsuite/integration-arquillian/servers/app-server/karaf/fuse61/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse61/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse62/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/fuse62/pom.xml index 6379104a9a..126f03efb1 100644 --- a/testsuite/integration-arquillian/servers/app-server/karaf/fuse62/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse62/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml index 22a48d1733..ea1eadf8d1 100644 --- a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/karaf3/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/karaf3/pom.xml index aed028f378..c5a56a94f9 100644 --- a/testsuite/integration-arquillian/servers/app-server/karaf/karaf3/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/karaf/karaf3/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml index b9eb252ed7..e57d3c7840 100644 --- a/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/pom.xml b/testsuite/integration-arquillian/servers/app-server/pom.xml index 12b674bb77..b2c217bc43 100644 --- a/testsuite/integration-arquillian/servers/app-server/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml b/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml index 21d4477f9d..2e90fa67d2 100644 --- a/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat7/pom.xml b/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat7/pom.xml index 62cdea96c7..71982b6666 100644 --- a/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat7/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat7/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-tomcat - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat8/pom.xml b/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat8/pom.xml index 126041c9ae..79b6090cce 100644 --- a/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat8/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat8/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-tomcat - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat9/pom.xml b/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat9/pom.xml index e461d629e0..47ff0c9315 100644 --- a/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat9/pom.xml +++ b/testsuite/integration-arquillian/servers/app-server/tomcat/tomcat9/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-app-server-tomcat - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml index 2601da6358..b5bc27acab 100644 --- a/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-auth-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml index 926338956f..7e54e46d21 100644 --- a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-auth-server - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/wildfly/pom.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/wildfly/pom.xml index 3ecf670fdd..e2958f6f25 100644 --- a/testsuite/integration-arquillian/servers/auth-server/jboss/wildfly/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/jboss/wildfly/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-auth-server-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/auth-server/pom.xml b/testsuite/integration-arquillian/servers/auth-server/pom.xml index 232d6a6d27..56e9a0f37c 100644 --- a/testsuite/integration-arquillian/servers/auth-server/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/auth-server/services/pom.xml b/testsuite/integration-arquillian/servers/auth-server/services/pom.xml index 12fc60879d..afc7081043 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/services/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-auth-server - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/pom.xml b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/pom.xml index 97933583f3..e40a806b29 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-servers-auth-server-services - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-testsuite-providers diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml b/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml index ff476ed3bc..2793df4e4d 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers-auth-server - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java index 9d299734b0..bdbd4d92ce 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java @@ -50,8 +50,8 @@ import javax.servlet.ServletException; import java.lang.reflect.Field; import java.util.Collection; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; public class KeycloakOnUndertow implements DeployableContainer { @@ -61,7 +61,7 @@ public class KeycloakOnUndertow implements DeployableContainer deployedArchivesToContextPath = new HashMap<>(); + Map deployedArchivesToContextPath = new ConcurrentHashMap<>(); private DeploymentInfo createAuthServerDeploymentInfo() { ResteasyDeployment deployment = new ResteasyDeployment(); diff --git a/testsuite/integration-arquillian/servers/migration/pom.xml b/testsuite/integration-arquillian/servers/migration/pom.xml index 13fb3b486e..6b76f94504 100644 --- a/testsuite/integration-arquillian/servers/migration/pom.xml +++ b/testsuite/integration-arquillian/servers/migration/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/pom.xml b/testsuite/integration-arquillian/servers/pom.xml index 2bea37c100..7117c159f5 100644 --- a/testsuite/integration-arquillian/servers/pom.xml +++ b/testsuite/integration-arquillian/servers/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml b/testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml index f14cd09751..f3270e081d 100644 --- a/testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml +++ b/testsuite/integration-arquillian/servers/wildfly-balancer/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-servers - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/test-apps/app-profile-jee/pom.xml b/testsuite/integration-arquillian/test-apps/app-profile-jee/pom.xml index d9d031a0f8..e8ff1c40a9 100644 --- a/testsuite/integration-arquillian/test-apps/app-profile-jee/pom.xml +++ b/testsuite/integration-arquillian/test-apps/app-profile-jee/pom.xml @@ -5,7 +5,7 @@ org.keycloak.testsuite integration-arquillian-test-apps - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT keycloak-test-app-profile-jee diff --git a/testsuite/integration-arquillian/test-apps/hello-world-authz-service/pom.xml b/testsuite/integration-arquillian/test-apps/hello-world-authz-service/pom.xml index 1d41d2efed..5d575d9dc4 100755 --- a/testsuite/integration-arquillian/test-apps/hello-world-authz-service/pom.xml +++ b/testsuite/integration-arquillian/test-apps/hello-world-authz-service/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-test-apps - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT hello-world-authz-service diff --git a/testsuite/integration-arquillian/test-apps/js-console/pom.xml b/testsuite/integration-arquillian/test-apps/js-console/pom.xml index 6ba97ca49c..73093aa398 100755 --- a/testsuite/integration-arquillian/test-apps/js-console/pom.xml +++ b/testsuite/integration-arquillian/test-apps/js-console/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-test-apps - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/test-apps/js-database/pom.xml b/testsuite/integration-arquillian/test-apps/js-database/pom.xml index 513c057b59..3d746e472e 100644 --- a/testsuite/integration-arquillian/test-apps/js-database/pom.xml +++ b/testsuite/integration-arquillian/test-apps/js-database/pom.xml @@ -5,7 +5,7 @@ integration-arquillian-test-apps org.keycloak.testsuite - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-authz-policy/pom.xml b/testsuite/integration-arquillian/test-apps/photoz/photoz-authz-policy/pom.xml index 8439fc00e2..abdb7d699b 100755 --- a/testsuite/integration-arquillian/test-apps/photoz/photoz-authz-policy/pom.xml +++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-authz-policy/pom.xml @@ -6,7 +6,7 @@ org.keycloak.testsuite integration-arquillian-test-apps-photoz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/pom.xml b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/pom.xml index 82fd69fb5f..e17a37b98f 100755 --- a/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/pom.xml +++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-html5-client/pom.xml @@ -5,7 +5,7 @@ org.keycloak.testsuite integration-arquillian-test-apps-photoz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml index 1351553b5d..bd272b5d6c 100755 --- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml +++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml @@ -6,7 +6,7 @@ org.keycloak.testsuite integration-arquillian-test-apps-photoz-parent - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml diff --git a/testsuite/integration-arquillian/test-apps/photoz/pom.xml b/testsuite/integration-arquillian/test-apps/photoz/pom.xml index 71db385d3e..4a880b24e6 100755 --- a/testsuite/integration-arquillian/test-apps/photoz/pom.xml +++ b/testsuite/integration-arquillian/test-apps/photoz/pom.xml @@ -6,7 +6,7 @@ org.keycloak.testsuite integration-arquillian-test-apps - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-test-apps-photoz-parent diff --git a/testsuite/integration-arquillian/test-apps/pom.xml b/testsuite/integration-arquillian/test-apps/pom.xml index 4d74389265..cacb0ac9a5 100644 --- a/testsuite/integration-arquillian/test-apps/pom.xml +++ b/testsuite/integration-arquillian/test-apps/pom.xml @@ -5,7 +5,7 @@ integration-arquillian org.keycloak.testsuite - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/test-apps/servlet-authz/pom.xml b/testsuite/integration-arquillian/test-apps/servlet-authz/pom.xml index 249d47e3bd..724df70fbf 100755 --- a/testsuite/integration-arquillian/test-apps/servlet-authz/pom.xml +++ b/testsuite/integration-arquillian/test-apps/servlet-authz/pom.xml @@ -6,7 +6,7 @@ org.keycloak.testsuite integration-arquillian-test-apps - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT servlet-authz-app diff --git a/testsuite/integration-arquillian/test-apps/servlets/pom.xml b/testsuite/integration-arquillian/test-apps/servlets/pom.xml index cab0c285bf..9159c73959 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/pom.xml +++ b/testsuite/integration-arquillian/test-apps/servlets/pom.xml @@ -5,7 +5,7 @@ integration-arquillian-test-apps org.keycloak.testsuite - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java index 1bfbb3e0ce..3b3cc4997f 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/filter/AdapterActionsFilter.java @@ -23,12 +23,14 @@ import org.keycloak.adapters.AdapterDeploymentContext; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.rotation.JWKPublicKeyLocator; import org.keycloak.common.util.Time; +import org.keycloak.common.util.reflections.Reflections; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.Field; /** * Filter to handle "special" requests to perform actions on adapter side (for example setting time offset ) @@ -38,7 +40,7 @@ import java.io.PrintWriter; public class AdapterActionsFilter implements Filter { public static final String TIME_OFFSET_PARAM = "timeOffset"; - public static final String RESET_PUBLIC_KEY_PARAM = "resetPublicKey"; + public static final String RESET_DEPLOYMENT_PARAM = "resetDeployment"; private static final Logger log = Logger.getLogger(AdapterActionsFilter.class); @@ -54,19 +56,28 @@ public class AdapterActionsFilter implements Filter { //Accept timeOffset as argument to enforce timeouts String timeOffsetParam = request.getParameter(TIME_OFFSET_PARAM); - String resetPublicKey = request.getParameter(RESET_PUBLIC_KEY_PARAM); + String resetDeploymentParam = request.getParameter(RESET_DEPLOYMENT_PARAM); if (timeOffsetParam != null && !timeOffsetParam.isEmpty()) { int timeOffset = Integer.parseInt(timeOffsetParam); log.infof("Time offset updated to %d for application %s", timeOffset, servletReq.getRequestURI()); Time.setOffset(timeOffset); writeResponse(servletResp, "Offset set successfully"); - } else if (resetPublicKey != null && !resetPublicKey.isEmpty()) { + } else if (resetDeploymentParam != null && !resetDeploymentParam.isEmpty()) { AdapterDeploymentContext deploymentContext = (AdapterDeploymentContext) request.getServletContext().getAttribute(AdapterDeploymentContext.class.getName()); - KeycloakDeployment deployment = deploymentContext.resolveDeployment(null); - deployment.setPublicKeyLocator(new JWKPublicKeyLocator()); - log.infof("Restarted publicKey locator for application %s", servletReq.getRequestURI()); - writeResponse(servletResp, "PublicKeyLocator restarted successfully"); + + Field field = Reflections.findDeclaredField(AdapterDeploymentContext.class, "deployment"); + Reflections.setAccessible(field); + KeycloakDeployment deployment = (KeycloakDeployment) Reflections.getFieldValue(field, deploymentContext); + + Time.setOffset(0); + deployment.setNotBefore(0); + if (deployment.getPublicKeyLocator() instanceof JWKPublicKeyLocator) { + deployment.setPublicKeyLocator(new JWKPublicKeyLocator()); + } + + log.infof("Restarted PublicKeyLocator, notBefore and timeOffset for application %s", servletReq.getRequestURI()); + writeResponse(servletResp, "Restarted PublicKeyLocator, notBefore and timeOffset successfully"); } else { // Continue request chain.doFilter(request, response); diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/AbstractShowTokensServlet.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/AbstractShowTokensServlet.java index 370717210c..6db5922cc1 100644 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/AbstractShowTokensServlet.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/AbstractShowTokensServlet.java @@ -49,6 +49,7 @@ public abstract class AbstractShowTokensServlet extends HttpServlet { return new StringBuilder("" + accessTokenPretty + "") .append("" + refreshTokenPretty + "") + .append("" + ctx.getTokenString() + "") .toString(); } diff --git a/testsuite/integration-arquillian/test-apps/test-apps-dist/pom.xml b/testsuite/integration-arquillian/test-apps/test-apps-dist/pom.xml index f4790c1f61..0ce3451330 100644 --- a/testsuite/integration-arquillian/test-apps/test-apps-dist/pom.xml +++ b/testsuite/integration-arquillian/test-apps/test-apps-dist/pom.xml @@ -5,7 +5,7 @@ integration-arquillian-test-apps org.keycloak.testsuite - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/test-utils/pom.xml b/testsuite/integration-arquillian/test-utils/pom.xml index 5fb36070f1..5e179e18e5 100644 --- a/testsuite/integration-arquillian/test-utils/pom.xml +++ b/testsuite/integration-arquillian/test-utils/pom.xml @@ -5,7 +5,7 @@ integration-arquillian org.keycloak.testsuite - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml index a0eb15cba5..a945047e9b 100644 --- a/testsuite/integration-arquillian/tests/base/pom.xml +++ b/testsuite/integration-arquillian/tests/base/pom.xml @@ -21,7 +21,7 @@ org.keycloak.testsuite integration-arquillian-tests - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/AbstractShowTokensPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/AbstractShowTokensPage.java index ea7ef6fe48..64d0de2eb7 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/AbstractShowTokensPage.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/AbstractShowTokensPage.java @@ -38,6 +38,9 @@ public abstract class AbstractShowTokensPage extends AbstractPageWithInjectedUrl @FindBy(id = "refreshToken") private WebElement refreshToken; + @FindBy(id = "accessTokenString") + private WebElement accessTokenString; + public AccessToken getAccessToken() { try { @@ -51,13 +54,25 @@ public abstract class AbstractShowTokensPage extends AbstractPageWithInjectedUrl return null; } + public RefreshToken getRefreshToken() { try { return JsonSerialization.readValue(refreshToken.getText(), RefreshToken.class); } catch (IOException e) { e.printStackTrace(); } catch (NoSuchElementException nsee) { - log.warn("No idToken element found on the page"); + log.warn("No refreshToken element found on the page"); + } + + return null; + } + + + public String getAccessTokenString() { + try { + return accessTokenString.getText(); + } catch (NoSuchElementException nsee) { + log.warn("No accessTokenString element found on the page"); } return null; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java index a40275f727..cc018d2267 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractServletsAdapterTest.java @@ -111,14 +111,17 @@ public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest { testRealmPage.setAuthRealm(DEMO); } - protected void setAdapterAndServerTimeOffset(int timeOffset, String servletUri) { + protected void setAdapterAndServerTimeOffset(int timeOffset, String... servletUris) { setTimeOffset(timeOffset); - String timeOffsetUri = UriBuilder.fromUri(servletUri) - .queryParam(AdapterActionsFilter.TIME_OFFSET_PARAM, timeOffset) - .build().toString(); - driver.navigate().to(timeOffsetUri); - WaitUtils.waitUntilElement(By.tagName("body")).is().visible(); + for (String servletUri : servletUris) { + String timeOffsetUri = UriBuilder.fromUri(servletUri) + .queryParam(AdapterActionsFilter.TIME_OFFSET_PARAM, timeOffset) + .build().toString(); + + driver.navigate().to(timeOffsetUri); + WaitUtils.waitUntilElement(By.tagName("body")).is().visible(); + } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoFilterServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoFilterServletAdapterTest.java index 0ad81d501b..a9ce39a16d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoFilterServletAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoFilterServletAdapterTest.java @@ -27,10 +27,4 @@ public abstract class AbstractDemoFilterServletAdapterTest extends AbstractDemoS } - @Test - @Override - @Ignore - public void testClientWithJwksUri() { - - } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java index f57b858bdf..fde26a1514 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractDemoServletsAdapterTest.java @@ -27,17 +27,13 @@ import org.junit.Test; import org.keycloak.OAuth2Constants; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.common.Version; -import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.Time; import org.keycloak.constants.AdapterConstants; -import org.keycloak.keys.KeyProvider; -import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.OIDCLoginProtocolService; import org.keycloak.representations.AccessToken; import org.keycloak.representations.VersionRepresentation; import org.keycloak.representations.idm.ClientRepresentation; -import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; @@ -67,7 +63,6 @@ import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Form; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; import java.io.File; import java.io.IOException; import java.net.URI; @@ -86,7 +81,6 @@ import static org.junit.Assert.assertTrue; import org.keycloak.testsuite.adapter.page.CustomerPortalNoConf; import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf; import static org.keycloak.testsuite.util.WaitUtils.pause; import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; @@ -141,7 +135,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd @Deployment(name = CustomerDb.DEPLOYMENT_NAME) protected static WebArchive customerDb() { - return servletDeployment(CustomerDb.DEPLOYMENT_NAME, CustomerDatabaseServlet.class); + return servletDeployment(CustomerDb.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class); } @Deployment(name = CustomerDbErrorPage.DEPLOYMENT_NAME) @@ -217,97 +211,6 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd client.close(); } - @Test - public void testRealmKeyRotationWithNewKeyDownload() throws Exception { - // Login success first - tokenMinTTLPage.navigateTo(); - testRealmLoginPage.form().waitForUsernameInputPresent(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(tokenMinTTLPage); - - AccessToken token = tokenMinTTLPage.getAccessToken(); - Assert.assertEquals("bburke@redhat.com", token.getPreferredUsername()); - - // Logout - String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) - .queryParam(OAuth2Constants.REDIRECT_URI, tokenMinTTLPage.toString()) - .build("demo").toString(); - driver.navigate().to(logoutUri); - - // Generate new realm key - String realmId = adminClient.realm(DEMO).toRepresentation().getId(); - ComponentRepresentation keys = new ComponentRepresentation(); - keys.setName("generated"); - keys.setProviderType(KeyProvider.class.getName()); - keys.setProviderId("rsa-generated"); - keys.setParentId(realmId); - keys.setConfig(new MultivaluedHashMap<>()); - keys.getConfig().putSingle("priority", "100"); - Response response = adminClient.realm(DEMO).components().add(keys); - assertEquals(201, response.getStatus()); - response.close(); - - String adapterActionsUrl = tokenMinTTLPage.toString() + "/unsecured/foo"; - setAdapterAndServerTimeOffset(300, adapterActionsUrl); - - // Try to login. Should work now due to realm key change - tokenMinTTLPage.navigateTo(); - testRealmLoginPage.form().waitForUsernameInputPresent(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlEquals(tokenMinTTLPage); - token = tokenMinTTLPage.getAccessToken(); - Assert.assertEquals("bburke@redhat.com", token.getPreferredUsername()); - driver.navigate().to(logoutUri); - - // Revert public keys change - String timeOffsetUri = UriBuilder.fromUri(adapterActionsUrl) - .queryParam(AdapterActionsFilter.RESET_PUBLIC_KEY_PARAM, "true") - .build().toString(); - driver.navigate().to(timeOffsetUri); - waitUntilElement(By.tagName("body")).is().visible(); - - setAdapterAndServerTimeOffset(0, adapterActionsUrl); - } - - @Test - public void testClientWithJwksUri() throws Exception { - // Set client to bad JWKS URI - ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "secure-portal"); - ClientRepresentation client = clientResource.toRepresentation(); - OIDCAdvancedConfigWrapper wrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client); - wrapper.setUseJwksUrl(true); - wrapper.setJwksUrl(securePortal + "/bad-jwks-url"); - clientResource.update(client); - - // Login should fail at the code-to-token - securePortal.navigateTo(); - assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); - testRealmLoginPage.form().login("bburke@redhat.com", "password"); - String pageSource = driver.getPageSource(); - assertCurrentUrlStartsWith(securePortal); - assertFalse(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen")); - - // Set client to correct JWKS URI - client = clientResource.toRepresentation(); - wrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client); - wrapper.setUseJwksUrl(true); - wrapper.setJwksUrl(securePortal + "/" + AdapterConstants.K_JWKS); - clientResource.update(client); - - // Login to secure-portal should be fine now. Client keys downloaded from JWKS URI - securePortal.navigateTo(); - assertCurrentUrlEquals(securePortal); - pageSource = driver.getPageSource(); - assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen")); - - // Logout - String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) - .queryParam(OAuth2Constants.REDIRECT_URI, securePortal.toString()).build("demo").toString(); - driver.navigate().to(logoutUri); - } - @Test public void testLoginSSOAndLogout() { // test login to customer-portal which does a bearer request to customer-db diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractOIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractOIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..8c42b997aa --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/AbstractOIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,346 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter.servlet; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.graphene.page.Page; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.OAuth2Constants; +import org.keycloak.admin.client.resource.ClientResource; +import org.keycloak.common.util.MultivaluedHashMap; +import org.keycloak.common.util.StreamUtil; +import org.keycloak.common.util.Time; +import org.keycloak.constants.AdapterConstants; +import org.keycloak.keys.KeyProvider; +import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; +import org.keycloak.protocol.oidc.OIDCLoginProtocolService; +import org.keycloak.representations.AccessToken; +import org.keycloak.representations.adapters.action.GlobalRequestResult; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ComponentRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; +import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; +import org.keycloak.testsuite.adapter.page.CustomerDb; +import org.keycloak.testsuite.adapter.page.SecurePortal; +import org.keycloak.testsuite.adapter.page.TokenMinTTLPage; +import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.util.URLAssert; +import org.openqa.selenium.By; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf; +import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; + +/** + * Tests related to public key rotation for OIDC adapter + * + * @author Marek Posolda + */ +public class AbstractOIDCPublicKeyRotationAdapterTest extends AbstractServletsAdapterTest { + + @Page + private SecurePortal securePortal; + + @Page + private TokenMinTTLPage tokenMinTTLPage; + + @Page + private CustomerDb customerDb; + + @Deployment(name = SecurePortal.DEPLOYMENT_NAME) + protected static WebArchive securePortal() { + return servletDeployment(SecurePortal.DEPLOYMENT_NAME, CallAuthenticatedServlet.class); + } + + @Deployment(name = TokenMinTTLPage.DEPLOYMENT_NAME) + protected static WebArchive tokenMinTTLPage() { + return servletDeployment(TokenMinTTLPage.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, TokenMinTTLServlet.class, ErrorServlet.class); + } + + @Deployment(name = CustomerDb.DEPLOYMENT_NAME) + protected static WebArchive customerDb() { + return servletDeployment(CustomerDb.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class); + } + + + + + @Before + public void beforeRotationAdapterTest() { + // Delete all cookies from token-min-ttl page to be sure we are logged out + tokenMinTTLPage.navigateTo(); + driver.manage().deleteAllCookies(); + } + + + @Test + public void testRealmKeyRotationWithNewKeyDownload() throws Exception { + // Login success first + loginToTokenMinTtlApp(); + + // Logout + String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) + .queryParam(OAuth2Constants.REDIRECT_URI, tokenMinTTLPage.toString()) + .build("demo").toString(); + driver.navigate().to(logoutUri); + assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); + + // Generate new realm key + generateNewRealmKey(); + + // Try to login again. It should fail now because not yet allowed to download new keys + tokenMinTTLPage.navigateTo(); + testRealmLoginPage.form().waitForUsernameInputPresent(); + assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); + testRealmLoginPage.form().login("bburke@redhat.com", "password"); + URLAssert.assertCurrentUrlStartsWith(driver, tokenMinTTLPage.getInjectedUrl().toString()); + Assert.assertNull(tokenMinTTLPage.getAccessToken()); + + driver.navigate().to(logoutUri); + assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); + + setAdapterAndServerTimeOffset(300, tokenMinTTLPage.toString() + "/unsecured/foo"); + + // Try to login. Should work now due to realm key change + loginToTokenMinTtlApp(); + driver.navigate().to(logoutUri); + + // Revert public keys change + resetKeycloakDeploymentForAdapter(tokenMinTTLPage.toString() + "/unsecured/foo"); + } + + + @Test + public void testClientWithJwksUri() throws Exception { + // Set client to bad JWKS URI + ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "secure-portal"); + ClientRepresentation client = clientResource.toRepresentation(); + OIDCAdvancedConfigWrapper wrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client); + wrapper.setUseJwksUrl(true); + wrapper.setJwksUrl(securePortal + "/bad-jwks-url"); + clientResource.update(client); + + // Login should fail at the code-to-token + securePortal.navigateTo(); + assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); + testRealmLoginPage.form().login("bburke@redhat.com", "password"); + String pageSource = driver.getPageSource(); + assertCurrentUrlStartsWith(securePortal); + assertFalse(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen")); + + // Set client to correct JWKS URI + client = clientResource.toRepresentation(); + wrapper = OIDCAdvancedConfigWrapper.fromClientRepresentation(client); + wrapper.setUseJwksUrl(true); + wrapper.setJwksUrl(securePortal + "/" + AdapterConstants.K_JWKS); + clientResource.update(client); + + // Login to secure-portal should be fine now. Client keys downloaded from JWKS URI + securePortal.navigateTo(); + assertCurrentUrlEquals(securePortal); + pageSource = driver.getPageSource(); + assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen")); + + // Logout + String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder()) + .queryParam(OAuth2Constants.REDIRECT_URI, securePortal.toString()).build("demo").toString(); + driver.navigate().to(logoutUri); + } + + + // KEYCLOAK-3824: Test for public-key-cache-ttl + @Test + public void testPublicKeyCacheTtl() { + // increase accessTokenLifespan to 1200 + RealmRepresentation demoRealm = adminClient.realm(DEMO).toRepresentation(); + demoRealm.setAccessTokenLifespan(1200); + adminClient.realm(DEMO).update(demoRealm); + + // authenticate in tokenMinTTL app + loginToTokenMinTtlApp(); + String accessTokenString = tokenMinTTLPage.getAccessTokenString(); + + // Send REST request to customer-db app. I should be successfully authenticated + int status = invokeRESTEndpoint(accessTokenString); + Assert.assertEquals(200, status); + + // Re-generate realm public key and remove the old key + String oldKeyId = getActiveKeyId(); + generateNewRealmKey(); + adminClient.realm(DEMO).components().component(oldKeyId).remove(); + + // Send REST request to the customer-db app. Should be still succcessfully authenticated as the JWKPublicKeyLocator cache is still valid + status = invokeRESTEndpoint(accessTokenString); + Assert.assertEquals(200, status); + + // TimeOffset to 900 on the REST app side. Token is still valid (1200) but JWKPublicKeyLocator should try to download new key (public-key-cache-ttl=600) + setAdapterAndServerTimeOffset(900, customerDb.toString() + "/unsecured/foo"); + + // Send REST request. New request to the publicKey cache should be sent, and key is no longer returned as token contains the old kid + status = invokeRESTEndpoint(accessTokenString); + Assert.assertEquals(401, status); + + // Revert public keys change and time offset + resetKeycloakDeploymentForAdapter(customerDb.toString() + "/unsecured/foo"); + resetKeycloakDeploymentForAdapter(tokenMinTTLPage.toString() + "/unsecured/foo"); + } + + + // KEYCLOAK-3823: Test that sending notBefore policy invalidates JWKPublicKeyLocator cache + @Test + public void testPublicKeyCacheInvalidatedWhenPushedNotBefore() { + driver.manage().timeouts().pageLoadTimeout(1000, TimeUnit.SECONDS); + + // increase accessTokenLifespan to 1200 + RealmRepresentation demoRealm = adminClient.realm(DEMO).toRepresentation(); + demoRealm.setAccessTokenLifespan(1200); + adminClient.realm(DEMO).update(demoRealm); + + // authenticate in tokenMinTTL app + loginToTokenMinTtlApp(); + String accessTokenString = tokenMinTTLPage.getAccessTokenString(); + + // Generate new realm public key + String oldKeyId = getActiveKeyId(); + generateNewRealmKey(); + + // Send REST request to customer-db app. It should be successfully authenticated even that token is signed by the old key + int status = invokeRESTEndpoint(accessTokenString); + Assert.assertEquals(200, status); + + // Remove the old realm key now + adminClient.realm(DEMO).components().component(oldKeyId).remove(); + + // Set some offset to ensure pushing notBefore will pass + setAdapterAndServerTimeOffset(130, customerDb.toString() + "/unsecured/foo", tokenMinTTLPage.toString() + "/unsecured/foo"); + + // Send notBefore policy from the realm + demoRealm.setNotBefore(Time.currentTime() - 1); + adminClient.realm(DEMO).update(demoRealm); + GlobalRequestResult result = adminClient.realm(DEMO).pushRevocation(); + Assert.assertTrue(result.getSuccessRequests().contains(customerDb.toString())); + + // Send REST request. New request to the publicKey cache should be sent, and key is no longer returned as token contains the old kid + status = invokeRESTEndpoint(accessTokenString); + Assert.assertEquals(401, status); + + // Revert public keys change and time offset + resetKeycloakDeploymentForAdapter(customerDb.toString() + "/unsecured/foo"); + resetKeycloakDeploymentForAdapter(tokenMinTTLPage.toString() + "/unsecured/foo"); + } + + + // HELPER METHODS + + private void loginToTokenMinTtlApp() { + tokenMinTTLPage.navigateTo(); + testRealmLoginPage.form().waitForUsernameInputPresent(); + assertCurrentUrlStartsWithLoginUrlOf(testRealmPage); + testRealmLoginPage.form().login("bburke@redhat.com", "password"); + assertCurrentUrlEquals(tokenMinTTLPage); + + AccessToken token = tokenMinTTLPage.getAccessToken(); + Assert.assertEquals("bburke@redhat.com", token.getPreferredUsername()); + } + + + private void generateNewRealmKey() { + String realmId = adminClient.realm(DEMO).toRepresentation().getId(); + + ComponentRepresentation keys = new ComponentRepresentation(); + keys.setName("generated"); + keys.setProviderType(KeyProvider.class.getName()); + keys.setProviderId("rsa-generated"); + keys.setParentId(realmId); + keys.setConfig(new MultivaluedHashMap<>()); + keys.getConfig().putSingle("priority", "150"); + Response response = adminClient.realm(DEMO).components().add(keys); + assertEquals(201, response.getStatus()); + response.close(); + } + + private String getActiveKeyId() { + String realmId = adminClient.realm(DEMO).toRepresentation().getId(); + return adminClient.realm(DEMO).components().query(realmId, KeyProvider.class.getName()) + .get(0).getId(); + } + + + private int invokeRESTEndpoint(String accessTokenString) { + + HttpClient client = new DefaultHttpClient(); + try { + String restUrl = customerDb.toString(); + HttpGet get = new HttpGet(restUrl); + get.addHeader("Authorization", "Bearer " + accessTokenString); + try { + HttpResponse response = client.execute(get); + int status = response.getStatusLine().getStatusCode(); + if (status != 200) { + return status; + } + + HttpEntity entity = response.getEntity(); + InputStream is = entity.getContent(); + try { + String body = StreamUtil.readString(is); + Assert.assertTrue(body.contains("Stian Thorgersen") && body.contains("Bill Burke")); + return status; + } finally { + is.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } finally { + client.getConnectionManager().shutdown(); + } + } + + + private void resetKeycloakDeploymentForAdapter(String adapterActionsUrl) { + String timeOffsetUri = UriBuilder.fromUri(adapterActionsUrl) + .queryParam(AdapterActionsFilter.RESET_DEPLOYMENT_PARAM, "true") + .build().toString(); + driver.navigate().to(timeOffsetUri); + waitUntilElement(By.tagName("body")).is().visible(); + } + + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowOIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowOIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..0dfd99c996 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/undertow/servlet/UndertowOIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter.undertow.servlet; + +import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("auth-server-undertow") +public class UndertowOIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java index 545fbff0f1..5b4777b9cc 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTest.java @@ -28,6 +28,7 @@ import org.keycloak.admin.client.resource.IdentityProviderResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RoleMappingResource; import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.models.Constants; @@ -847,6 +848,19 @@ public class UserTest extends AbstractAdminTest { assertNames(roles.clientLevel(clientUuid).listAll(), "client-composite"); } + @Test + public void defaultMaxResults() { + UsersResource users = adminClient.realms().realm("test").users(); + + for (int i = 0; i < 110; i++) { + users.create(UserBuilder.create().username("test-" + i).build()).close(); + } + + assertEquals(100, users.search("test", null, null).size()); + assertEquals(105, users.search("test", 0, 105).size()); + assertEquals(111, users.search("test", 0, 1000).size()); + } + private void switchEditUsernameAllowedOn() { RealmRepresentation rep = realm.toRepresentation(); rep.setEditUsernameAllowed(true); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventTest.java index 2d48ccc3c8..3d33fdc436 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventTest.java @@ -19,11 +19,17 @@ package org.keycloak.testsuite.admin.event; import org.junit.Before; import org.junit.Test; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.admin.client.resource.UsersResource; +import org.keycloak.events.EventType; +import org.keycloak.events.admin.OperationType; import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.AuthDetailsRepresentation; +import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.util.UserBuilder; import java.util.Arrays; import java.util.Collections; @@ -127,4 +133,22 @@ public class AdminEventTest extends AbstractEventTest { List events = testRealmResource().getAdminEvents(Arrays.asList("CREATE"), realmName(), null, null, null, null, null, null, null, null); assertEquals(2, events.size()); } + + @Test + public void defaultMaxResults() { + RealmResource realm = adminClient.realms().realm("test"); + AdminEventRepresentation event = new AdminEventRepresentation(); + event.setOperationType(OperationType.CREATE.toString()); + event.setAuthDetails(new AuthDetailsRepresentation()); + event.setRealmId(realm.toRepresentation().getId()); + + for (int i = 0; i < 110; i++) { + testingClient.testing("test").onAdminEvent(event, false); + } + + assertEquals(100, realm.getAdminEvents(null, null, null, null, null, null, null, null, null, null).size()); + assertEquals(105, realm.getAdminEvents(null, null, null, null, null, null, null, null, 0, 105).size()); + assertTrue(realm.getAdminEvents(null, null, null, null, null, null, null, null, 0, 1000).size() >= 110); + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/LoginEventsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/LoginEventsTest.java index a4fa8be87e..dc0d787cd4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/LoginEventsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/LoginEventsTest.java @@ -20,8 +20,13 @@ package org.keycloak.testsuite.admin.event; import org.jboss.arquillian.graphene.page.Page; import org.junit.Before; import org.junit.Test; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.admin.client.resource.UsersResource; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.EventType; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.testsuite.console.page.events.LoginEvents; +import org.keycloak.testsuite.util.UserBuilder; import java.util.Arrays; import java.util.List; @@ -128,6 +133,22 @@ public class LoginEventsTest extends AbstractEventTest { assertEquals(2, filteredEvents.size()); } + @Test + public void defaultMaxResults() { + RealmResource realm = adminClient.realms().realm("test"); + EventRepresentation event = new EventRepresentation(); + event.setRealmId(realm.toRepresentation().getId()); + event.setType(EventType.LOGIN.toString()); + + for (int i = 0; i < 110; i++) { + testingClient.testing("test").onEvent(event); + } + + assertEquals(100, realm.getEvents(null, null, null, null, null, null, null, null).size()); + assertEquals(105, realm.getEvents(null, null, null, null, null, null, 0, 105).size()); + assertTrue(realm.getEvents(null, null, null, null, null, null, 0, 1000).size() >= 110); + } + /* Removed this test because it takes too long. The default interval for event cleanup is 15 minutes (900 seconds). I don't have time to figure out diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java index d61a517ce6..a1e6b0ad36 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java @@ -32,10 +32,10 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; + +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.MatcherAssert.assertThat; /** * @author Marko Strukelj @@ -119,7 +119,7 @@ public class GroupMappersTest extends AbstractGroupTest { Assert.assertNotNull(groups); Assert.assertTrue(groups.size() == 1); Assert.assertEquals("topGroup", groups.get(0)); - Assert.assertEquals("true", token.getOtherClaims().get("topAttribute")); + Assert.assertEquals(Collections.singletonList("true"), token.getOtherClaims().get("topAttribute")); } { UserRepresentation user = realm.users().search("level2GroupUser", -1, -1).get(0); @@ -132,8 +132,8 @@ public class GroupMappersTest extends AbstractGroupTest { Assert.assertNotNull(groups); Assert.assertTrue(groups.size() == 1); Assert.assertEquals("level2group", groups.get(0)); - Assert.assertEquals("true", token.getOtherClaims().get("topAttribute")); - Assert.assertEquals("true", token.getOtherClaims().get("level2Attribute")); + Assert.assertEquals(Collections.singletonList("true"), token.getOtherClaims().get("topAttribute")); + Assert.assertEquals(Collections.singletonList("true"), token.getOtherClaims().get("level2Attribute")); } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java index 1f0274e9cb..d16626f86a 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java @@ -19,8 +19,11 @@ package org.keycloak.testsuite.admin.group; import org.junit.Assert; import org.junit.Test; +import org.keycloak.admin.client.resource.GroupResource; +import org.keycloak.admin.client.resource.GroupsResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RoleMappingResource; +import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.models.Constants; @@ -578,4 +581,28 @@ public class GroupTest extends AbstractGroupTest { assertThat(userClient.realms().findAll(), // Any admin operation will do not(empty())); } + + @Test + public void defaultMaxResults() { + GroupsResource groups = adminClient.realms().realm("test").groups(); + Response response = groups.add(GroupBuilder.create().name("test").build()); + String groupId = ApiUtil.getCreatedId(response); + response.close(); + + GroupResource group = groups.group(groupId); + + UsersResource users = adminClient.realms().realm("test").users(); + + for (int i = 0; i < 110; i++) { + Response r = users.create(UserBuilder.create().username("test-" + i).build()); + String userId = ApiUtil.getCreatedId(r); + r.close(); + + users.get(userId).joinGroup(groupId); + } + + assertEquals(100, group.members(null, null).size()); + assertEquals(105, group.members(0, 105).size()); + assertEquals(110, group.members(0, 1000).size()); + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java index 2e5c4c6789..f5e9d2e732 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractUserAttributeMapperTest.java @@ -238,7 +238,6 @@ public abstract class AbstractUserAttributeMapperTest extends AbstractBaseBroker } @Test - @Ignore("Unignore to test KEYCLOAK-3648") public void testBasicMappingMultipleValues() { testValueMapping(ImmutableMap.>builder() .put(ATTRIBUTE_TO_MAP_NAME, ImmutableList.builder().add("value 1").add("value 2").build()) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java index 06ebacd883..15a8b6b9b4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java @@ -127,6 +127,26 @@ public class LoginTotpTest extends TestRealmKeycloakTest { events.expectLogin().assertEvent(); } + // KEYCLOAK-3835 + @Test + public void loginWithTotpRefreshTotpPage() throws Exception { + loginPage.open(); + loginPage.login("test-user@localhost", "password"); + + Assert.assertTrue(loginTotpPage.isCurrent()); + + // Refresh TOTP page + driver.navigate().refresh(); + + System.out.println(driver.getPageSource()); + + loginTotpPage.login(totp.generateTOTP("totpSecret")); + + Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); + + events.expectLogin().assertEvent(); + } + @Test public void loginWithTotpCancel() throws Exception { loginPage.open(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java index ac86d2023a..b896588852 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java @@ -29,7 +29,9 @@ import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ProtocolMappersResource; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.protocol.oidc.OIDCLoginProtocol; +import org.keycloak.protocol.oidc.mappers.AddressMapper; import org.keycloak.representations.AccessToken; +import org.keycloak.representations.AddressClaimSet; import org.keycloak.representations.IDToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation; @@ -96,11 +98,13 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest { user.singleAttribute("street", "5 Yawkey Way"); user.singleAttribute("locality", "Boston"); - user.singleAttribute("region", "MA"); + user.singleAttribute("region_some", "MA"); // Custom name for userAttribute name, which will be mapped to region user.singleAttribute("postal_code", "02115"); user.singleAttribute("country", "USA"); + user.singleAttribute("formatted", "6 Foo Street"); user.singleAttribute("phone", "617-777-6666"); + List departments = Arrays.asList("finance", "development"); user.getAttributes().put("departments", departments); userResource.update(user); @@ -108,6 +112,9 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest { ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app"); ProtocolMapperRepresentation mapper = createAddressMapper(true, true); + mapper.getConfig().put(AddressMapper.getModelPropertyName(AddressClaimSet.REGION), "region_some"); + mapper.getConfig().put(AddressMapper.getModelPropertyName(AddressClaimSet.COUNTRY), "country_some"); + mapper.getConfig().remove(AddressMapper.getModelPropertyName(AddressClaimSet.POSTAL_CODE)); // Even if we remove protocolMapper config property, it should still default to postal_code app.getProtocolMappers().createMapper(mapper); ProtocolMapperRepresentation hard = createHardcodedClaim("hard", "hard", "coded", "String", false, null, true, true); @@ -131,14 +138,15 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest { assertEquals(idToken.getAddress().getLocality(), "Boston"); assertEquals(idToken.getAddress().getRegion(), "MA"); assertEquals(idToken.getAddress().getPostalCode(), "02115"); - assertEquals(idToken.getAddress().getCountry(), "USA"); + assertNull(idToken.getAddress().getCountry()); // Null because we changed userAttribute name to "country_some", but user contains "country" + assertEquals(idToken.getAddress().getFormattedAddress(), "6 Foo Street"); assertNotNull(idToken.getOtherClaims().get("home_phone")); - assertEquals("617-777-6666", idToken.getOtherClaims().get("home_phone")); + assertThat((List) idToken.getOtherClaims().get("home_phone"), hasItems("617-777-6666")); assertEquals("coded", idToken.getOtherClaims().get("hard")); Map nested = (Map) idToken.getOtherClaims().get("nested"); assertEquals("coded-nested", nested.get("hard")); nested = (Map) idToken.getOtherClaims().get("home"); - assertEquals("617-777-6666", nested.get("phone")); + assertThat((List) nested.get("phone"), hasItems("617-777-6666")); List departments = (List) idToken.getOtherClaims().get("department"); assertEquals(2, departments.size()); assertTrue(departments.contains("finance") && departments.contains("development")); @@ -150,14 +158,15 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest { assertEquals(accessToken.getAddress().getLocality(), "Boston"); assertEquals(accessToken.getAddress().getRegion(), "MA"); assertEquals(accessToken.getAddress().getPostalCode(), "02115"); - assertEquals(accessToken.getAddress().getCountry(), "USA"); + assertNull(idToken.getAddress().getCountry()); // Null because we changed userAttribute name to "country_some", but user contains "country" + assertEquals(idToken.getAddress().getFormattedAddress(), "6 Foo Street"); assertNotNull(accessToken.getOtherClaims().get("home_phone")); - assertEquals("617-777-6666", accessToken.getOtherClaims().get("home_phone")); + assertThat((List) accessToken.getOtherClaims().get("home_phone"), hasItems("617-777-6666")); assertEquals("coded", accessToken.getOtherClaims().get("hard")); nested = (Map) accessToken.getOtherClaims().get("nested"); assertEquals("coded-nested", nested.get("hard")); nested = (Map) accessToken.getOtherClaims().get("home"); - assertEquals("617-777-6666", nested.get("phone")); + assertThat((List) nested.get("phone"), hasItems("617-777-6666")); departments = (List) idToken.getOtherClaims().get("department"); assertEquals(2, departments.size()); assertTrue(departments.contains("finance") && departments.contains("development")); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OfflineTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OfflineTokenTest.java index 36cab0bd1a..223a3f65ef 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OfflineTokenTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OfflineTokenTest.java @@ -285,7 +285,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest { oauth.scope(OAuth2Constants.OFFLINE_ACCESS); oauth.clientId("offline-client"); OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("secret1", "test-user@localhost", "password"); - tokenResponse.getErrorDescription(); + Assert.assertNull(tokenResponse.getErrorDescription()); AccessToken token = oauth.verifyToken(tokenResponse.getAccessToken()); String offlineTokenString = tokenResponse.getRefreshToken(); RefreshToken offlineToken = oauth.verifyRefreshToken(offlineTokenString); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java index c3b05cbbc2..cfd790727c 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java @@ -232,14 +232,14 @@ public class ServiceAccountTest extends AbstractKeycloakTest { RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken()); Assert.assertEquals("updated-client", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID)); - // Username still same. Client ID changed + // Username updated after client ID changed events.expectClientLogin() .client("updated-client") .user(userId) .session(accessToken.getSessionState()) .detail(Details.TOKEN_ID, accessToken.getId()) .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl") + .detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "updated-client") .assertEvent(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json index 362017077b..400fac3871 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/keycloak.json @@ -1,10 +1,10 @@ { "realm" : "demo", "resource" : "customer-db", - "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "auth-server-url": "http://localhost:8180/auth", "ssl-required" : "external", "bearer-only" : true, - "enable-cors" : true + "enable-cors" : true, + "public-key-cache-ttl": 600 } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/web.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/web.xml index cebfe6f5e5..56ed0e725a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/web.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/customer-db/WEB-INF/web.xml @@ -23,11 +23,22 @@ customer-db + + + AdapterActionsFilter + org.keycloak.testsuite.adapter.filter.AdapterActionsFilter + + Servlet org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet + + AdapterActionsFilter + /* + + Servlet /* @@ -42,6 +53,12 @@ user + + + Unsecured + /unsecured/* + + KEYCLOAK diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json index d65fa94847..b1f70e2738 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json @@ -117,6 +117,13 @@ ], "clients": [ + { + "clientId": "customer-db", + "enabled": true, + "adminUrl": "/customer-db", + "baseUrl": "/customer-db", + "bearerOnly": true + }, { "clientId": "customer-portal", "enabled": true, diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keycloak.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keycloak.json index de290de301..f3fa1a59f0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keycloak.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/secure-portal/WEB-INF/keycloak.json @@ -1,6 +1,5 @@ { "realm": "demo", - "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "auth-server-url": "http://localhost:8180/auth", "ssl-required": "external", "resource": "secure-portal", diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/as7/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/as7/pom.xml index 832de00bc1..807e22fbae 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/as7/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/as7/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-as7 diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/as7/src/test/java/org/keycloak/testsuite/adapter/AS7OIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/as7/src/test/java/org/keycloak/testsuite/adapter/AS7OIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..50cc0e9046 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/as7/src/test/java/org/keycloak/testsuite/adapter/AS7OIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("app-server-as7") +public class AS7OIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/pom.xml index 54e8084388..7f828eb67d 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-eap diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/src/test/java/org/keycloak/testsuite/adapter/EAPOIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/src/test/java/org/keycloak/testsuite/adapter/EAPOIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..df936d8cce --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap/src/test/java/org/keycloak/testsuite/adapter/EAPOIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("app-server-eap") +public class EAPOIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6-fuse/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6-fuse/pom.xml index d59e6b0ce0..9e3588e4fc 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6-fuse/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6-fuse/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-eap6-fuse diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml index c8b9bd5a50..0cc9426f33 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-eap6 diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/EAP6OIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/EAP6OIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..607ead848a --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/eap6/src/test/java/org/keycloak/testsuite/adapter/EAP6OIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("app-server-eap6") +public class EAP6OIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/pom.xml index 17a362f4dc..1c6e70e9e3 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-jboss diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/eap/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/eap/pom.xml index 358118625f..038c40ebcf 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/eap/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/eap/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss-relative - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-relative-eap diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/pom.xml index 16b40b54e6..9fd88589ad 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT pom diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/wildfly/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/wildfly/pom.xml index 8899d0aa98..34d2d61228 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/wildfly/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/relative/wildfly/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss-relative - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-relative-wildfly diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml index fb4621702d..6d6f0f97ce 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-wildfly diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/WildflyOIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/WildflyOIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..d54889be07 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly/src/test/java/org/keycloak/testsuite/adapter/WildflyOIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("app-server-wildfly") +public class WildflyOIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly8/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly8/pom.xml index f08f7b91b6..c0901a51e7 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly8/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly8/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-wildfly8 diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly8/src/test/java/org/keycloak/testsuite/adapter/Wildfly8OIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly8/src/test/java/org/keycloak/testsuite/adapter/Wildfly8OIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..0cad5fcfda --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly8/src/test/java/org/keycloak/testsuite/adapter/Wildfly8OIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("app-server-wildfly8") +public class Wildfly8OIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly9/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly9/pom.xml index 73aba180e1..afd4c65b11 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly9/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly9/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-jboss - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-wildfly9 diff --git a/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly9/src/test/java/org/keycloak/testsuite/adapter/Wildfly9OIDCPublicKeyRotationAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly9/src/test/java/org/keycloak/testsuite/adapter/Wildfly9OIDCPublicKeyRotationAdapterTest.java new file mode 100644 index 0000000000..a1b8118ef5 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/adapters/jboss/wildfly9/src/test/java/org/keycloak/testsuite/adapter/Wildfly9OIDCPublicKeyRotationAdapterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.testsuite.adapter; + +import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * @author Marek Posolda + */ +@AppServerContainer("app-server-wildfly9") +public class Wildfly9OIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { +} diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse61/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse61/pom.xml index 56e177c37b..f6b75cacb8 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse61/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse61/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-fuse61 diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/pom.xml index c5a7eb88da..d7a36368ef 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-fuse62 diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse63/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse63/pom.xml index ec311a6f06..2265346c16 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse63/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse63/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-fuse63 diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/karaf3/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/karaf/karaf3/pom.xml index 91a4b545bb..0e6eb39493 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/karaf/karaf3/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/karaf3/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-karaf - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-karaf3 diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml index 6393b23266..02ba176216 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-karaf diff --git a/testsuite/integration-arquillian/tests/other/adapters/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/pom.xml index 646a919fb8..2f722f785e 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-other - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters diff --git a/testsuite/integration-arquillian/tests/other/adapters/tomcat/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/tomcat/pom.xml index c0e89f1322..64fe6bf6b5 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/tomcat/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/tomcat/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-tomcat diff --git a/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat7/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat7/pom.xml index f565843711..b67fb8f0da 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat7/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat7/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-tomcat - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-tomcat7 diff --git a/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat8/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat8/pom.xml index 1f32e6d026..67ce9fc834 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat8/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat8/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-tomcat - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-tomcat8 diff --git a/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat9/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat9/pom.xml index 90ceb8e07f..96876e6e4b 100644 --- a/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat9/pom.xml +++ b/testsuite/integration-arquillian/tests/other/adapters/tomcat/tomcat9/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-adapters-tomcat - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-adapters-tomcat9 diff --git a/testsuite/integration-arquillian/tests/other/clean-start/pom.xml b/testsuite/integration-arquillian/tests/other/clean-start/pom.xml index d164e6a22e..6c975c914d 100644 --- a/testsuite/integration-arquillian/tests/other/clean-start/pom.xml +++ b/testsuite/integration-arquillian/tests/other/clean-start/pom.xml @@ -23,7 +23,7 @@ org.keycloak.testsuite integration-arquillian-tests-other - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-smoke-clean-start diff --git a/testsuite/integration-arquillian/tests/other/console/pom.xml b/testsuite/integration-arquillian/tests/other/console/pom.xml index 77d18aac11..5390cf0cc7 100644 --- a/testsuite/integration-arquillian/tests/other/console/pom.xml +++ b/testsuite/integration-arquillian/tests/other/console/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-other - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-console diff --git a/testsuite/integration-arquillian/tests/other/console_no_users/pom.xml b/testsuite/integration-arquillian/tests/other/console_no_users/pom.xml index cf29acdda9..a48b81d7c3 100644 --- a/testsuite/integration-arquillian/tests/other/console_no_users/pom.xml +++ b/testsuite/integration-arquillian/tests/other/console_no_users/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-other - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-console-no-users diff --git a/testsuite/integration-arquillian/tests/other/jpa-performance/pom.xml b/testsuite/integration-arquillian/tests/other/jpa-performance/pom.xml index 171cc643e7..a72798bc0e 100644 --- a/testsuite/integration-arquillian/tests/other/jpa-performance/pom.xml +++ b/testsuite/integration-arquillian/tests/other/jpa-performance/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-other - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-jpa-performance diff --git a/testsuite/integration-arquillian/tests/other/mod_auth_mellon/pom.xml b/testsuite/integration-arquillian/tests/other/mod_auth_mellon/pom.xml index b2bd6301ca..77272e25b3 100644 --- a/testsuite/integration-arquillian/tests/other/mod_auth_mellon/pom.xml +++ b/testsuite/integration-arquillian/tests/other/mod_auth_mellon/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-other - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-other-mod_auth_mellon diff --git a/testsuite/integration-arquillian/tests/other/nodejs_adapter/pom.xml b/testsuite/integration-arquillian/tests/other/nodejs_adapter/pom.xml index 2e3d915bca..b7f0689016 100644 --- a/testsuite/integration-arquillian/tests/other/nodejs_adapter/pom.xml +++ b/testsuite/integration-arquillian/tests/other/nodejs_adapter/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests-other - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-nodejs-adapter diff --git a/testsuite/integration-arquillian/tests/other/pom.xml b/testsuite/integration-arquillian/tests/other/pom.xml index ae956fa9bf..4838f7e130 100644 --- a/testsuite/integration-arquillian/tests/other/pom.xml +++ b/testsuite/integration-arquillian/tests/other/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian-tests - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT integration-arquillian-tests-other diff --git a/testsuite/integration-arquillian/tests/other/sssd/pom.xml b/testsuite/integration-arquillian/tests/other/sssd/pom.xml index 8269427025..5c0abdb027 100644 --- a/testsuite/integration-arquillian/tests/other/sssd/pom.xml +++ b/testsuite/integration-arquillian/tests/other/sssd/pom.xml @@ -5,7 +5,7 @@ integration-arquillian-tests-other org.keycloak.testsuite - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index bb9e838f6d..ce348e9cc0 100755 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -24,7 +24,7 @@ org.keycloak.testsuite integration-arquillian - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT pom diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml index 94283a90b8..131b7cc337 100755 --- a/testsuite/integration/pom.xml +++ b/testsuite/integration/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderOfflineTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderOfflineTest.java index b9f4f2aeda..fb4b3af81b 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderOfflineTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderOfflineTest.java @@ -107,7 +107,7 @@ public class UserSessionProviderOfflineTest { // Assert all previously saved offline sessions found for (Map.Entry entry : offlineSessions.entrySet()) { - Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), entry.getValue()) != null); + Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null); UserSessionModel offlineSession = session.sessions().getUserSession(realm, entry.getValue()); boolean found = false; @@ -187,7 +187,7 @@ public class UserSessionProviderOfflineTest { resetSession(); - ClientSessionModel offlineClientSession = sessionManager.findOfflineClientSession(fooRealm, clientSession.getId(), userSession.getId()); + ClientSessionModel offlineClientSession = sessionManager.findOfflineClientSession(fooRealm, clientSession.getId()); Assert.assertEquals("foo-app", offlineClientSession.getClient().getClientId()); Assert.assertEquals("user3", offlineClientSession.getUserSession().getUser().getUsername()); Assert.assertEquals(offlineClientSession.getId(), offlineClientSession.getUserSession().getClientSessions().get(0).getId()); @@ -206,7 +206,7 @@ public class UserSessionProviderOfflineTest { // Assert nothing loaded fooRealm = session.realms().getRealm("foo"); - Assert.assertNull(sessionManager.findOfflineClientSession(fooRealm, clientSession.getId(), userSession.getId())); + Assert.assertNull(sessionManager.findOfflineClientSession(fooRealm, clientSession.getId())); Assert.assertEquals(0, session.sessions().getOfflineSessionsCount(fooRealm, fooRealm.getClientByClientId("foo-app"))); // Cleanup @@ -338,7 +338,7 @@ public class UserSessionProviderOfflineTest { // Assert all previously saved offline sessions found for (Map.Entry entry : offlineSessions.entrySet()) { - Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), entry.getValue()) != null); + Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null); } UserSessionModel session0 = session.sessions().getOfflineUserSession(realm, origSessions[0].getId()); @@ -379,9 +379,9 @@ public class UserSessionProviderOfflineTest { for (Map.Entry entry : offlineSessions.entrySet()) { String userSessionId = entry.getValue(); if (userSessionId.equals(session1.getId())) { - Assert.assertFalse(sessionManager.findOfflineClientSession(realm, entry.getKey(), userSessionId) != null); + Assert.assertFalse(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null); } else { - Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), userSessionId) != null); + Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) != null); } } Assert.assertEquals(1, persister.getUserSessionsCount(true)); @@ -394,7 +394,7 @@ public class UserSessionProviderOfflineTest { resetSession(); for (Map.Entry entry : offlineSessions.entrySet()) { - Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey(), entry.getValue()) == null); + Assert.assertTrue(sessionManager.findOfflineClientSession(realm, entry.getKey()) == null); } Assert.assertEquals(0, persister.getUserSessionsCount(true)); diff --git a/testsuite/jetty/jetty81/pom.xml b/testsuite/jetty/jetty81/pom.xml index 9fcabbfd38..4fa3829392 100755 --- a/testsuite/jetty/jetty81/pom.xml +++ b/testsuite/jetty/jetty81/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/testsuite/jetty/jetty91/pom.xml b/testsuite/jetty/jetty91/pom.xml index da1d2b8ca6..b24c1e698a 100755 --- a/testsuite/jetty/jetty91/pom.xml +++ b/testsuite/jetty/jetty91/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/testsuite/jetty/jetty92/pom.xml b/testsuite/jetty/jetty92/pom.xml index d55eee77a2..a3df7a6698 100755 --- a/testsuite/jetty/jetty92/pom.xml +++ b/testsuite/jetty/jetty92/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/testsuite/jetty/jetty93/pom.xml b/testsuite/jetty/jetty93/pom.xml index eb2ba4f9e7..b686d2e1a7 100644 --- a/testsuite/jetty/jetty93/pom.xml +++ b/testsuite/jetty/jetty93/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/testsuite/jetty/pom.xml b/testsuite/jetty/pom.xml index 2c59a7d18c..d51e880880 100755 --- a/testsuite/jetty/pom.xml +++ b/testsuite/jetty/pom.xml @@ -20,7 +20,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml Keycloak SAML Jetty Testsuite Integration diff --git a/testsuite/pom.xml b/testsuite/pom.xml index fb0c228619..eb7da68594 100755 --- a/testsuite/pom.xml +++ b/testsuite/pom.xml @@ -21,7 +21,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/testsuite/proxy/pom.xml b/testsuite/proxy/pom.xml index 7530893fb0..603cc2ebd7 100755 --- a/testsuite/proxy/pom.xml +++ b/testsuite/proxy/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/testsuite/tomcat6/pom.xml b/testsuite/tomcat6/pom.xml index 5e3b7a0505..b00837305d 100755 --- a/testsuite/tomcat6/pom.xml +++ b/testsuite/tomcat6/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/testsuite/tomcat7/pom.xml b/testsuite/tomcat7/pom.xml index eb0d3f0cad..a5f9b350d0 100755 --- a/testsuite/tomcat7/pom.xml +++ b/testsuite/tomcat7/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/testsuite/tomcat8/pom.xml b/testsuite/tomcat8/pom.xml index d0c206bc13..21395da3c4 100755 --- a/testsuite/tomcat8/pom.xml +++ b/testsuite/tomcat8/pom.xml @@ -21,7 +21,7 @@ keycloak-testsuite-pom org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT ../pom.xml 4.0.0 diff --git a/themes/pom.xml b/themes/pom.xml index fa98402a70..0e1ecd6f4b 100755 --- a/themes/pom.xml +++ b/themes/pom.xml @@ -4,7 +4,7 @@ keycloak-parent org.keycloak - 2.4.1.Final-SNAPSHOT + 2.5.0.Final-SNAPSHOT 4.0.0 diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties index 29f1465944..8cf09f3b7a 100644 --- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties +++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties @@ -170,8 +170,18 @@ sectorIdentifierUri.label=Sector Identifier URI sectorIdentifierUri.tooltip=Providers that use pairwise sub values and support Dynamic Client Registration SHOULD use the sector_identifier_uri parameter. It provides a way for a group of websites under common administrative control to have consistent pairwise sub values independent of the individual domain names. It also provides a way for Clients to change redirect_uri domains without having to reregister all of their users. pairwiseSubAlgorithmSalt.label=Salt pairwiseSubAlgorithmSalt.tooltip=Salt used when calculating the pairwise subject identifier. If left blank, a salt will be generated. - - +addressClaim.street.label=User Attribute Name for Street +addressClaim.street.tooltip=Name of User Attribute, which will be used to map to 'street_address' subclaim inside 'address' token claim. Defaults to 'street' . +addressClaim.locality.label=User Attribute Name for Locality +addressClaim.locality.tooltip=Name of User Attribute, which will be used to map to 'locality' subclaim inside 'address' token claim. Defaults to 'locality' . +addressClaim.region.label=User Attribute Name for Region +addressClaim.region.tooltip=Name of User Attribute, which will be used to map to 'region' subclaim inside 'address' token claim. Defaults to 'region' . +addressClaim.postal_code.label=User Attribute Name for Postal Code +addressClaim.postal_code.tooltip=Name of User Attribute, which will be used to map to 'postal_code' subclaim inside 'address' token claim. Defaults to 'postal_code' . +addressClaim.country.label=User Attribute Name for Country +addressClaim.country.tooltip=Name of User Attribute, which will be used to map to 'country' subclaim inside 'address' token claim. Defaults to 'country' . +addressClaim.formatted.label=User Attribute Name for Formatted Address +addressClaim.formatted.tooltip=Name of User Attribute, which will be used to map to 'formatted' subclaim inside 'address' token claim. Defaults to 'formatted' . # client details clients.tooltip=Clients are trusted browser apps and web services in a realm. These clients can request a login. You can also define client specific roles. diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js index 5e6bdbaace..e451339015 100644 --- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js +++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js @@ -2638,13 +2638,21 @@ module.controller('RealmImportCtrl', function($scope, realm, $route, $scope.itemCount = function(section) { if (!$scope.importing) return 0; if ($scope.hasRealmRoles() && (section === 'roles.realm')) return $scope.fileContent.roles.realm.length; - if ($scope.hasClientRoles() && (section === 'roles.client')) return Object.keys($scope.fileContent.roles.client).length; + if ($scope.hasClientRoles() && (section === 'roles.client')) return clientRolesCount($scope.fileContent.roles.client); if (!$scope.fileContent.hasOwnProperty(section)) return 0; return $scope.fileContent[section].length; } + clientRolesCount = function(clientRoles) { + var total = 0; + for (var clientName in clientRoles) { + total += clientRoles[clientName].length; + } + return total; + } + $scope.hasResources = function() { return ($scope.importUsers && $scope.hasArray('users')) || ($scope.importGroups && $scope.hasArray('groups')) || diff --git a/themes/src/main/resources/theme/base/admin/resources/js/services.js b/themes/src/main/resources/theme/base/admin/resources/js/services.js index d70ade2d2c..b8cb2a3f8f 100755 --- a/themes/src/main/resources/theme/base/admin/resources/js/services.js +++ b/themes/src/main/resources/theme/base/admin/resources/js/services.js @@ -197,6 +197,9 @@ module.factory('ComponentUtils', function() { var utils = {}; utils.addLastEmptyValueToMultivaluedLists = function(properties, config) { + if (!properties) { + return; + } for (var i=0 ; i