diff --git a/.travis.yml b/.travis.yml index 5ac8744b37..c875dcc06a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,6 @@ env: - TESTS=old - TESTS=crossdc-server - TESTS=crossdc-adapter - - TESTS=ssl jdk: - oraclejdk8 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 b2d1874cd3..e3db2a31a5 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 @@ -282,6 +282,13 @@ public class KeycloakDeployment { this.sslRequired = sslRequired; } + public boolean isSSLEnabled() { + if (SslRequired.NONE == sslRequired) { + return false; + } + return true; + } + public int getConfidentialPort() { return confidentialPort; } 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 c05bcb69ef..5541864039 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 @@ -130,7 +130,7 @@ public class KeycloakDeploymentBuilder { 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"); } - if (realmKeyPem == null || !deployment.isBearerOnly() || deployment.isEnableBasicAuth() || deployment.isRegisterNodeAtStartup() || deployment.getRegisterNodePeriod() != -1) { + if (realmKeyPem == null || !deployment.isBearerOnly() || deployment.isSSLEnabled() || deployment.isEnableBasicAuth() || deployment.isRegisterNodeAtStartup() || deployment.getRegisterNodePeriod() != -1) { deployment.setClient(new HttpClientBuilder().build(adapterConfig)); } if (adapterConfig.getAuthServerUrl() == null && (!deployment.isBearerOnly() || realmKeyPem == null)) { diff --git a/core/src/main/java/org/keycloak/util/JsonSerialization.java b/core/src/main/java/org/keycloak/util/JsonSerialization.java index ed43e69228..a32ff733e9 100755 --- a/core/src/main/java/org/keycloak/util/JsonSerialization.java +++ b/core/src/main/java/org/keycloak/util/JsonSerialization.java @@ -41,7 +41,9 @@ public class JsonSerialization { public static final ObjectMapper sysPropertiesAwareMapper = new ObjectMapper(new SystemPropertiesJsonParserFactory()); static { + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + prettyMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); prettyMapper.enable(SerializationFeature.INDENT_OUTPUT); prettyMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); } diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java index 7b79074ace..e0fef4ac2d 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java @@ -27,7 +27,9 @@ import org.keycloak.admin.client.resource.RealmsResource; import org.keycloak.admin.client.resource.ServerInfoResource; import org.keycloak.admin.client.token.TokenManager; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; import java.net.URI; @@ -49,10 +51,10 @@ public class Keycloak implements AutoCloseable { private final String authToken; private final ResteasyWebTarget target; private final ResteasyClient client; - + Keycloak(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, String grantType, ResteasyClient resteasyClient, String authtoken) { config = new Config(serverUrl, realm, username, password, clientId, clientSecret, grantType); - client = resteasyClient != null ? resteasyClient : new ResteasyClientBuilder().connectionPoolSize(10).build(); + client = resteasyClient != null ? resteasyClient : newRestEasyClient(null, null, false); authToken = authtoken; tokenManager = authtoken == null ? new TokenManager(config, client) : null; @@ -64,33 +66,53 @@ public class Keycloak implements AutoCloseable { return authToken != null ? new BearerAuthFilter(authToken) : new BearerAuthFilter(tokenManager); } - public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext) { - return getInstance(serverUrl, realm, username, password, clientId, clientSecret, sslContext, null); - } - - public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext, ResteasyJackson2Provider customJacksonProvider) { + private static ResteasyClient newRestEasyClient(ResteasyJackson2Provider customJacksonProvider, SSLContext sslContext, boolean disableTrustManager) { ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder() - .sslContext(sslContext) - .hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.WILDCARD) - .connectionPoolSize(10); + .sslContext(sslContext) + .connectionPoolSize(10); + + if (disableTrustManager) { + // Disable PKIX path validation errors when running tests using SSL + clientBuilder.disableTrustManager().hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY); + } if (customJacksonProvider != null) { clientBuilder.register(customJacksonProvider, 100); } - return new Keycloak(serverUrl, realm, username, password, clientId, clientSecret, PASSWORD, clientBuilder.build(), null); + return clientBuilder.build(); + } + + public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext, ResteasyJackson2Provider customJacksonProvider, boolean disableTrustManager, String authToken) { + return new Keycloak(serverUrl, realm, username, password, clientId, clientSecret, PASSWORD, newRestEasyClient(customJacksonProvider, sslContext, disableTrustManager), authToken); } public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret) { - return new Keycloak(serverUrl, realm, username, password, clientId, clientSecret, PASSWORD, null, null); + return getInstance(serverUrl, realm, username, password, clientId, clientSecret, null, null, false, null); + } + + public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext) { + return getInstance(serverUrl, realm, username, password, clientId, clientSecret, sslContext, null, false, null); + } + + public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext, ResteasyJackson2Provider customJacksonProvider) { + return getInstance(serverUrl, realm, username, password, clientId, clientSecret, sslContext, null, false, null); } public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId) { - return new Keycloak(serverUrl, realm, username, password, clientId, null, PASSWORD, null, null); + return getInstance(serverUrl, realm, username, password, clientId, null, null, null, false, null); + } + + public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, SSLContext sslContext) { + return getInstance(serverUrl, realm, username, password, clientId, null, sslContext, null, false, null); } public static Keycloak getInstance(String serverUrl, String realm, String clientId, String authToken) { - return new Keycloak(serverUrl, realm, null, null, clientId, null, PASSWORD, null, authToken); + return getInstance(serverUrl, realm, null, null, clientId, null, null, null, false, authToken); + } + + public static Keycloak getInstance(String serverUrl, String realm, String clientId, String authToken, SSLContext sllSslContext) { + return getInstance(serverUrl, realm, null, null, clientId, null, sllSslContext, null, false, authToken); } public RealmsResource realms() { diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/AbstractAuthOptionsCmd.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/AbstractAuthOptionsCmd.java index 5c18ccb4ff..6b48a2643f 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/AbstractAuthOptionsCmd.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/AbstractAuthOptionsCmd.java @@ -89,6 +89,9 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd { @Option(name = "trustpass", description = "Truststore password (prompted for if not specified and --truststore is used)") String trustPass; + @Option(name = "insecure", description = "Turns off TLS validation", hasValue = false) + boolean insecure; + @Option(name = "token", description = "Token to use for invocations. With this option set, every other authentication option is ignored") String externalToken; @@ -178,6 +181,10 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd { throw new RuntimeException("Failed to load truststore: " + truststore, e); } } + + if (insecure) { + HttpUtil.setSkipCertificateValidation(); + } } protected ConfigData ensureAuthInfo(ConfigData config, CommandInvocation commandInvocation) { diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/util/HttpUtil.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/util/HttpUtil.java index f1261ab6d5..f2e27b3c7a 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/util/HttpUtil.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/util/HttpUtil.java @@ -30,9 +30,11 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContexts; import org.keycloak.client.admin.cli.httpcomponents.HttpDelete; import org.keycloak.client.admin.cli.operations.LocalSearch; @@ -53,6 +55,7 @@ import java.security.cert.CertificateException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import static org.keycloak.common.util.ObjectUtil.capitalize; @@ -68,6 +71,7 @@ public class HttpUtil { private static HttpClient httpClient; private static SSLConnectionSocketFactory sslsf; + private static final AtomicBoolean tlsWarningEmitted = new AtomicBoolean(); public static InputStream doGet(String url, String acceptType, String authorization) { try { @@ -257,11 +261,29 @@ public class HttpUtil { } SSLContext theContext = SSLContexts.custom() .useProtocol("TLS") - .loadTrustMaterial(file, password == null ? null : password.toCharArray()) + .loadTrustMaterial(file, password == null ? null : password.toCharArray(), TrustSelfSignedStrategy.INSTANCE) .build(); sslsf = new SSLConnectionSocketFactory(theContext); } + public static void setSkipCertificateValidation() { + if (!tlsWarningEmitted.getAndSet(true)) { + // Since this is a static util, it may happen that TLS is setup many times in one command + // invocation (e.g. when a command requires logging in). However, we would like to + // prevent this warning from appearing multiple times. That's why we need to guard it with a boolean. + System.err.println("The server is configured to use TLS but there is no truststore specified."); + System.err.println("The tool will skip certificate validation. This is highly discouraged for production use cases"); + } + + SSLContextBuilder builder = new SSLContextBuilder(); + try { + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + sslsf = new SSLConnectionSocketFactory(builder.build()); + } catch (Exception e) { + throw new RuntimeException("Failed setting up TLS", e); + } + } + public static String extractIdFromLocation(String location) { int last = location.lastIndexOf("/"); if (last != -1) { diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractAuthOptionsCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractAuthOptionsCmd.java index 196c789575..a00f88378c 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractAuthOptionsCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AbstractAuthOptionsCmd.java @@ -25,7 +25,6 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd { static final String DEFAULT_CLIENT = "admin-cli"; - @Option(name = "config", description = "Path to the config file (~/.keycloak/kcreg.config by default)", hasValue = true) protected String config; @@ -68,6 +67,9 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd { @Option(name = "trustpass", description = "Truststore password (prompted for if not specified and --truststore is used)", hasValue = true) protected String trustPass; + @Option(name = "insecure", description = "Turns off TLS validation", hasValue = false) + protected boolean insecure; + @Option(shortName = 't', name = "token", description = "Initial / Registration access token to use)", hasValue = true) protected String token; @@ -90,6 +92,7 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd { trustStore = parent.trustStore; trustPass = parent.trustPass; token = parent.token; + insecure = parent.insecure; } protected void applyDefaultOptionValues() { @@ -152,6 +155,10 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd { throw new RuntimeException("Failed to load truststore: " + truststore, e); } } + + if (insecure) { + HttpUtil.setSkipCertificateValidation(); + } } protected ConfigData ensureAuthInfo(ConfigData config, CommandInvocation commandInvocation) { diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/HttpUtil.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/HttpUtil.java index ec6e9bd131..6f2c58f764 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/HttpUtil.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/util/HttpUtil.java @@ -28,6 +28,8 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContexts; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; @@ -46,6 +48,7 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; /** * @author Marko Strukelj @@ -59,6 +62,7 @@ public class HttpUtil { private static HttpClient httpClient; private static SSLConnectionSocketFactory sslsf; + private static final AtomicBoolean tlsWarningEmitted = new AtomicBoolean(); public static InputStream doGet(String url, String acceptType, String authorization) { try { @@ -181,8 +185,26 @@ public class HttpUtil { } SSLContext theContext = SSLContexts.custom() .useProtocol("TLS") - .loadTrustMaterial(file, password == null ? null : password.toCharArray()) + .loadTrustMaterial(file, password == null ? null : password.toCharArray(), TrustSelfSignedStrategy.INSTANCE) .build(); sslsf = new SSLConnectionSocketFactory(theContext); } + + public static void setSkipCertificateValidation() { + if (!tlsWarningEmitted.getAndSet(true)) { + // Since this is a static util, it may happen that TLS is setup many times in one command + // invocation (e.g. when a command requires logging in). However, we would like to + // prevent this warning from appearing multiple times. That's why we need to guard it with a boolean. + System.err.println("The server is configured to use TLS but there is no truststore specified."); + System.err.println("The tool will skip certificate validation. This is highly discouraged for production use cases"); + } + + SSLContextBuilder builder = new SSLContextBuilder(); + try { + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + sslsf = new SSLConnectionSocketFactory(builder.build()); + } catch (Exception e) { + throw new RuntimeException("Failed setting up TLS", e); + } + } } diff --git a/testsuite/integration-arquillian/HOW-TO-RUN.md b/testsuite/integration-arquillian/HOW-TO-RUN.md index 8df630d9cf..13ecccc8d0 100644 --- a/testsuite/integration-arquillian/HOW-TO-RUN.md +++ b/testsuite/integration-arquillian/HOW-TO-RUN.md @@ -41,6 +41,10 @@ and adapter are all in the same JVM and you can debug them easily. If it is not -Dmaven.surefire.debug=true + +Or slightly longer version (that allows you to specify debugging port as well as wait till you attach the debugger): + + -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006 -Xnoagent -Djava.compiler=NONE" and you will be able to attach remote debugger to the test. Unfortunately server and adapter are running in different JVMs, so this won't help to debug those. @@ -486,27 +490,17 @@ To run the X.509 client certificate authentication tests: -Dbrowser=phantomjs \ "-Dtest=*.x509.*" -## Run Mutual TLS Client Certificate Bound Access Tokens tests +## Disabling TLS (SSL) in the tests -To run the Mutual TLS Client Certificate Bound Access Tokens tests: +All tests are executed with TLS by default. In order to disable it, you need to switch the `auth.server.ssl.required` property off. +Here's an example: mvn -f testsuite/integration-arquillian/pom.xml \ clean install \ - -Pauth-server-wildfly \ - -Dauth.server.ssl.required \ - -Dbrowser=phantomjs \ - -Dtest=org.keycloak.testsuite.hok.HoKTest + -Dauth.server.ssl.required=false -## Run Mutual TLS for the Client tests - -To run the Mutual TLS test for the client: - - mvn -f testsuite/integration-arquillian/pom.xml \ - clean install \ - -Pauth-server-wildfly \ - -Dauth.server.ssl.required \ - -Dbrowser=phantomjs \ - -Dtest=org.keycloak.testsuite.client.MutualTLSClientTest +NOTE: You can also do it ad-hoc from your IDE, however some tests (like AuthZ or JS Adapter tests) require rebuilt test applications. +so please make sure you rebuild all `testsuite/integration-arquillian` child modules. ## Cluster tests diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/common/cli/add-secured-deployments.cli b/testsuite/integration-arquillian/servers/app-server/jboss/common/cli/add-secured-deployments.cli index 04528ae7ed..10aef026fe 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/common/cli/add-secured-deployments.cli +++ b/testsuite/integration-arquillian/servers/app-server/jboss/common/cli/add-secured-deployments.cli @@ -3,8 +3,9 @@ embed-server --server-config=standalone.xml /subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/:add( \ realm=demo, \ resource=customer-portal-subsystem, \ - auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \ + auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.https.port:8543}/auth, \ ssl-required=EXTERNAL, \ + disable-trust-manager=true, \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ ) /subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/credential=secret/:add(value=password) @@ -12,8 +13,9 @@ embed-server --server-config=standalone.xml /subsystem=keycloak/secure-deployment=product-portal-subsystem.war/:add( \ realm=demo, \ resource=product-portal-subsystem, \ - auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \ + auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.https.port:8543}/auth, \ ssl-required=EXTERNAL, \ + disable-trust-manager=true, \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ ) /subsystem=keycloak/secure-deployment=product-portal-subsystem.war/credential=secret/:add(value=password) diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/eap6/src/main/resources/config/cli/add-secured-deployments.cli b/testsuite/integration-arquillian/servers/app-server/jboss/eap6/src/main/resources/config/cli/add-secured-deployments.cli index 2f79a71147..4e558eede6 100644 --- a/testsuite/integration-arquillian/servers/app-server/jboss/eap6/src/main/resources/config/cli/add-secured-deployments.cli +++ b/testsuite/integration-arquillian/servers/app-server/jboss/eap6/src/main/resources/config/cli/add-secured-deployments.cli @@ -1,8 +1,9 @@ /subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/:add( \ realm=demo, \ resource=customer-portal-subsystem, \ - auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \ + auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.http.port:8543}/auth, \ ssl-required=EXTERNAL, \ + disable-trust-manager=true, \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ ) /subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/credential=secret/:add(value=password) @@ -10,8 +11,9 @@ /subsystem=keycloak/secure-deployment=product-portal-subsystem.war/:add( \ realm=demo, \ resource=product-portal-subsystem, \ - auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \ + auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.https.port:8543}/auth, \ ssl-required=EXTERNAL, \ + disable-trust-manager=true, \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ ) /subsystem=keycloak/secure-deployment=product-portal-subsystem.war/credential=secret/:add(value=password) 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 9ccac413ed..295406628a 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 @@ -33,6 +33,7 @@ ${project.version} ${project.basedir}/target/classes/javascript + https://localhost:8543/auth @@ -68,6 +69,21 @@ + + + no-ssl + + + auth.server.ssl.required + false + + + + http://localhost:8180/auth + + + + diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java index c88dace6c5..b854fffe89 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java @@ -143,7 +143,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider { } sb.append("
"); - UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth"); + UriBuilder base = UriBuilder.fromUri("/auth"); sb.append("account"); sb.append(""); @@ -165,7 +165,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider { StringBuilder sb = new StringBuilder(); sb.append("" + title + ""); - UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth"); + UriBuilder base = UriBuilder.fromUri("/auth"); sb.append("account"); sb.append(""); diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java index 02e421403e..6cadd0ad95 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java @@ -137,7 +137,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide } sb.append("
"); - UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth"); + UriBuilder base = UriBuilder.fromUri("/auth"); sb.append("account"); sb.append(""); @@ -159,7 +159,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide StringBuilder sb = new StringBuilder(); sb.append("" + title + ""); - UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth"); + UriBuilder base = UriBuilder.fromUri("/auth"); sb.append("account"); sb.append(""); diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/javascript/keycloak.json b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/javascript/keycloak.json index 989e71efe2..328ec601fa 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/javascript/keycloak.json +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/javascript/keycloak.json @@ -1,7 +1,7 @@ { "realm" : "test", "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", - "auth-server-url" : "http://localhost:8180/auth", + "auth-server-url" : "${js-adapter.auth-server-url}", "ssl-required" : "external", "resource" : "js-console", "public-client" : true diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml b/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml index 675715ac4d..d2332eec7e 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/pom.xml @@ -28,8 +28,11 @@ integration-arquillian-servers-auth-server-undertow Auth Server - Undertow - + + ${basedir}/../jboss/common + + org.keycloak keycloak-testsuite-utils @@ -77,4 +80,15 @@ + + + + src/main/resources + + + ${common.resources}/keystore + + + + 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 1bbf6ba713..a5dbfa3b10 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 @@ -51,10 +51,19 @@ import org.keycloak.testsuite.utils.undertow.UndertowDeployerHelper; import org.keycloak.testsuite.utils.undertow.UndertowWarClassLoader; import org.keycloak.util.JsonSerialization; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import java.io.IOException; import java.lang.reflect.Field; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -180,12 +189,13 @@ public class KeycloakOnUndertow implements DeployableContainer keycloakConfigPropertyOverridesMap; private int bindHttpPortOffset = 0; + private int bindHttpsPortOffset = 0; + private int bindHttpsPort = DEFAULT_HTTPS_PORT; public int getWorkerThreads() { return workerThreads; @@ -63,6 +67,22 @@ public class KeycloakOnUndertowConfiguration extends UndertowContainerConfigurat this.bindHttpPortOffset = bindHttpPortOffset; } + public int getBindHttpsPortOffset() { + return bindHttpsPortOffset; + } + + public void setBindHttpsPortOffset(int bindHttpsPortOffset) { + this.bindHttpsPortOffset = bindHttpsPortOffset; + } + + public int getBindHttpsPort() { + return this.bindHttpsPort; + } + + public void setBindHttpsPort(int bindHttpsPort) { + this.bindHttpsPort = bindHttpsPort; + } + public String getRoute() { return route; } diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/TLSUtils.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/TLSUtils.java new file mode 100644 index 0000000000..7291a06856 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/TLSUtils.java @@ -0,0 +1,58 @@ +package org.keycloak.testsuite.arquillian.undertow; + +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +public class TLSUtils { + + private TLSUtils() {} + + private static final TrustManager TRUST_ALL_MANAGER = new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + }; + + public static SSLContext initializeTLS() { + try { + KeyStore keystore = KeyStore.getInstance("jks"); + keystore.load(KeycloakOnUndertow.class.getResourceAsStream("/keycloak.jks"), "secret".toCharArray()); + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keystore, "secret".toCharArray()); + KeyManager[] keyManagers = keyManagerFactory.getKeyManagers(); + + // Essentially, this is REQUEST CLIENT AUTH behavior. It doesn't fail if the client doesn't have a cert. + // However it will challenge him to send it. + KeyStore truststore = KeyStore.getInstance("jks"); + truststore.load(KeycloakOnUndertow.class.getResourceAsStream("/keycloak.truststore"), "secret".toCharArray()); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(truststore); + TrustManager[] trustManagers = new TrustManager[trustManagerFactory.getTrustManagers().length + 1]; + for (int i = 0; i < trustManagerFactory.getTrustManagers().length; ++i) { + trustManagers[i] = trustManagerFactory.getTrustManagers()[i]; + } + trustManagers[trustManagers.length - 1] = TRUST_ALL_MANAGER; + + SSLContext sslContext; + sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagers, trustManagers, null); + return sslContext; + } catch (Exception e) { + throw new IllegalStateException("Could not initialize TLS", e); + } + } +} diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancer.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancer.java index b27f8b5455..40f4bb28d7 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancer.java +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancer.java @@ -20,7 +20,6 @@ package org.keycloak.testsuite.arquillian.undertow.lb; import java.lang.reflect.Field; import java.net.URI; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -41,6 +40,8 @@ import io.undertow.util.Headers; import org.jboss.logging.Logger; import org.keycloak.common.util.reflections.Reflections; import org.keycloak.services.managers.AuthenticationSessionManager; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; + import java.util.LinkedHashMap; import java.util.StringTokenizer; @@ -56,19 +57,20 @@ public class SimpleUndertowLoadBalancer { private static final Logger log = Logger.getLogger(SimpleUndertowLoadBalancer.class); - static final String DEFAULT_NODES = "node1=http://localhost:8181,node2=http://localhost:8182"; + static final String DEFAULT_NODES_HTTP = "node1=http://localhost:8181,node2=http://localhost:8182"; private final String host; - private final int port; + private final int httpPort; + private final int httpsPort; private final Map backendNodes; private Undertow undertow; private LoadBalancingProxyClient lb; public static void main(String[] args) throws Exception { - String nodes = System.getProperty("keycloak.nodes", DEFAULT_NODES); + String nodes = System.getProperty("keycloak.nodes", DEFAULT_NODES_HTTP); - SimpleUndertowLoadBalancer lb = new SimpleUndertowLoadBalancer("localhost", 8180, nodes); + SimpleUndertowLoadBalancer lb = new SimpleUndertowLoadBalancer("localhost", 8180, 8543, nodes); lb.start(); Runtime.getRuntime().addShutdownHook(new Thread() { @@ -82,9 +84,10 @@ public class SimpleUndertowLoadBalancer { } - public SimpleUndertowLoadBalancer(String host, int port, String nodesString) { + public SimpleUndertowLoadBalancer(String host, int httpPort, int httpsPort, String nodesString) { this.host = host; - this.port = port; + this.httpPort = httpPort; + this.httpsPort = httpsPort; this.backendNodes = parseNodes(nodesString); log.infof("Keycloak nodes: %s", backendNodes); } @@ -95,12 +98,13 @@ public class SimpleUndertowLoadBalancer { HttpHandler proxyHandler = createHandler(); undertow = Undertow.builder() - .addHttpListener(port, host) + .addHttpListener(httpPort, host) + .addHttpsListener(httpsPort, host, TLSUtils.initializeTLS()) .setHandler(proxyHandler) .build(); undertow.start(); - log.infof("#### Loadbalancer started and ready to serve requests on http://%s:%d ####", host, port); + log.infof("#### Loadbalancer started and ready to serve requests on http://%s:%d, http://%s:%d ####", host, httpPort, host, httpsPort); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerConfiguration.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerConfiguration.java index 12d3564e00..1e52d7d240 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerConfiguration.java +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerConfiguration.java @@ -26,10 +26,14 @@ import org.jboss.logging.Logger; */ public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerConfiguration { + public static final int DEFAULT_HTTPS_PORT = Integer.valueOf(System.getProperty("auth.server.https.port", "8543")); + protected static final Logger log = Logger.getLogger(SimpleUndertowLoadBalancerConfiguration.class); - private String nodes = SimpleUndertowLoadBalancer.DEFAULT_NODES; + private String nodes = SimpleUndertowLoadBalancer.DEFAULT_NODES_HTTP; private int bindHttpPortOffset = 0; + private int bindHttpsPortOffset = 0; + private int bindHttpsPort = DEFAULT_HTTPS_PORT; public String getNodes() { return nodes; @@ -47,6 +51,22 @@ public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerCo this.bindHttpPortOffset = bindHttpPortOffset; } + public int getBindHttpsPortOffset() { + return bindHttpsPortOffset; + } + + public void setBindHttpsPortOffset(int bindHttpsPortOffset) { + this.bindHttpsPortOffset = bindHttpsPortOffset; + } + + public int getBindHttpsPort() { + return this.bindHttpsPort; + } + + public void setBindHttpsPort(int bindHttpsPort) { + this.bindHttpsPort = bindHttpsPort; + } + @Override public void validate() throws ConfigurationException { super.validate(); @@ -57,10 +77,9 @@ public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerCo throw new ConfigurationException(e); } - int basePort = getBindHttpPort(); - int newPort = basePort + bindHttpPortOffset; - setBindHttpPort(newPort); - log.info("SimpleUndertowLoadBalancer will listen on port: " + newPort); + setBindHttpPort(getBindHttpPort() + bindHttpPortOffset); + setBindHttpsPort(getBindHttpsPort() + bindHttpsPortOffset); + log.info("SimpleUndertowLoadBalancer will listen on ports: " + getBindHttpPort() + " " + getBindHttpsPort()); } } diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerContainer.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerContainer.java index a7f1ffed03..85cd2cf396 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerContainer.java +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/lb/SimpleUndertowLoadBalancerContainer.java @@ -51,7 +51,7 @@ public class SimpleUndertowLoadBalancerContainer implements DeployableContainer< @Override public void start() throws LifecycleException { - this.container = new SimpleUndertowLoadBalancer(configuration.getBindAddress(), configuration.getBindHttpPort(), configuration.getNodes()); + this.container = new SimpleUndertowLoadBalancer(configuration.getBindAddress(), configuration.getBindHttpPort(), configuration.getBindHttpsPort(), configuration.getNodes()); this.container.start(); } diff --git a/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js b/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js index d175bfd543..9b8424c834 100755 --- a/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js +++ b/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/js/app.js @@ -18,11 +18,7 @@ var module = angular.module('product', []); function getAuthServerUrl() { - var url = 'http://localhost-auth:8180'; - if (window.location.href.indexOf("8643") > -1) { - url = url.replace("8180","8543"); - url = url.replace("http","https"); - } + var url = 'https://localhost-auth:8543'; return url; } diff --git a/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/keycloak.json b/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/keycloak.json index af68d70d80..ee2f3a7b08 100755 --- a/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/keycloak.json +++ b/testsuite/integration-arquillian/test-apps/cors/angular-product/src/main/webapp/keycloak.json @@ -3,6 +3,7 @@ "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "auth-server-url" : "http://localhost-auth:8180/auth", "ssl-required" : "external", + "disable-trust-manager" : "true", "resource" : "angular-cors-product", "public-client" : true } \ No newline at end of file diff --git a/testsuite/integration-arquillian/test-apps/cors/database-service/src/main/webapp/WEB-INF/keycloak.json b/testsuite/integration-arquillian/test-apps/cors/database-service/src/main/webapp/WEB-INF/keycloak.json index 214a562088..1b4d3dddb6 100755 --- a/testsuite/integration-arquillian/test-apps/cors/database-service/src/main/webapp/WEB-INF/keycloak.json +++ b/testsuite/integration-arquillian/test-apps/cors/database-service/src/main/webapp/WEB-INF/keycloak.json @@ -5,6 +5,7 @@ "auth-server-url": "http://localhost-auth:8180/auth", "bearer-only" : true, "ssl-required": "external", + "disable-trust-manager" : "true", "enable-cors": true, "cors-exposed-headers": "X-Custom1", "credentials": { diff --git a/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/error.jsp b/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/error.jsp index 00d25b3025..4ac61c3cf0 100644 --- a/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/error.jsp +++ b/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/error.jsp @@ -19,9 +19,16 @@ <%@ page import="org.keycloak.common.util.KeycloakUriBuilder" %> <%@ page import="org.keycloak.constants.ServiceUrlConstants" %> +<% + boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true")); + String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180"); + String authScheme = isTLSEnabled ? "https" : "http"; + String authUri = authScheme + "://localhost:" + authPort + "/auth"; +%> + -

">Logout

Access Denied !

diff --git a/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/index.jsp b/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/index.jsp index c511b2da9d..4db42a7cce 100644 --- a/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/index.jsp +++ b/testsuite/integration-arquillian/test-apps/hello-world-authz-service/src/main/webapp/index.jsp @@ -24,11 +24,16 @@ <% KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext(); + + boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true")); + String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180"); + String authScheme = isTLSEnabled ? "https" : "http"; + String authUri = authScheme + "://localhost:" + authPort + "/auth"; %>

Welcome !

-

">Logout

Your permissions are:

diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json b/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json index e44fec390c..83019c909f 100644 --- a/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json +++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-realm.json @@ -140,9 +140,9 @@ "consentRequired" : true, "fullScopeAllowed" : true, "redirectUris": [ - "/photoz-html5-client/*" + "*" ], - "webOrigins": ["http://localhost:8280"] + "webOrigins": ["*"] }, { "clientId": "photoz-restful-api", @@ -150,9 +150,9 @@ "baseUrl": "/photoz-restful-api", "authorizationServicesEnabled" : true, "redirectUris": [ - "/photoz-restful-api/*" + "*" ], - "webOrigins" : ["http://localhost:8280"], + "webOrigins" : ["*"], "clientAuthenticatorType": "client-jwt", "attributes" : { "jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==" diff --git a/testsuite/integration-arquillian/test-apps/servlet-authz/src/main/webapp/logout-include.jsp b/testsuite/integration-arquillian/test-apps/servlet-authz/src/main/webapp/logout-include.jsp index 21ef2edebf..25a0881797 100644 --- a/testsuite/integration-arquillian/test-apps/servlet-authz/src/main/webapp/logout-include.jsp +++ b/testsuite/integration-arquillian/test-apps/servlet-authz/src/main/webapp/logout-include.jsp @@ -6,6 +6,12 @@ int port = request.getServerPort(); String contextPath = request.getContextPath(); String redirectUri = scheme + "://" + host + ":" + port + contextPath; + + + boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true")); + String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180"); + String authScheme = isTLSEnabled ? "https" : "http"; + String authUri = authScheme + "://localhost:" + authPort + "/auth"; %> -

Click here Click here ">Sign Out

\ No newline at end of file diff --git a/testsuite/integration-arquillian/test-apps/servlet-policy-enforcer/src/main/webapp/logout-include.jsp b/testsuite/integration-arquillian/test-apps/servlet-policy-enforcer/src/main/webapp/logout-include.jsp index 3c55fd98c4..54b851fc88 100644 --- a/testsuite/integration-arquillian/test-apps/servlet-policy-enforcer/src/main/webapp/logout-include.jsp +++ b/testsuite/integration-arquillian/test-apps/servlet-policy-enforcer/src/main/webapp/logout-include.jsp @@ -6,6 +6,12 @@ int port = request.getServerPort(); String contextPath = request.getContextPath(); String redirectUri = scheme + "://" + host + ":" + port + contextPath; + + + boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true")); + String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180"); + String authScheme = isTLSEnabled ? "https" : "http"; + String authUri = authScheme + "://localhost:" + authPort + "/auth"; %> -

Click here Click here ">Sign Out

\ No newline at end of file diff --git a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java index 5a4eb1e765..4a28fa5bea 100755 --- a/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java +++ b/testsuite/integration-arquillian/test-apps/servlets/src/main/java/org/keycloak/testsuite/adapter/servlet/SamlSPFacade.java @@ -90,7 +90,7 @@ public class SamlSPFacade extends HttpServlet { */ private String getSamlRequest() { if (System.getProperty("auth.server.ssl.required", "false").equals("true")) { - return "jVLbTgIxEP2Vpu9Ly3JZbFgSlBhJUDeAPvhianeQJt127XS9%2FL1lwWiiokkfms6ZOZfpGGVlajFtwtYu4akBDOS1MhZFW8hp461wEjUKKytAEZRYTS8XIu1wUXsXnHKG7luOgyUi%2BKCdpWT6cT1zFpsK%2FAr8s1Zws1zkdBtCjYIx45Q0W4dBjIb9HoOqNu4NgFEyiyK1lbsBP8IHES6jIeZBmgpZCZVjH1rZzhcl584raF3ndCMNAiXzWU7ns%2Ft%2BOYKBgjTJUj5M%2Bln6kMjRSZak5aiX8ROuOB9EMBbRkH6Gz3bEBuYWg7QhpynvDhLeS%2FhwnaYinm7WicLuKCkOQk61LbV9PB7awx6E4mK9LpLierWm5BY8ttYjgE7IeGdItOz%2By%2Br%2Bu4zJX3mP2ReCA10truLI%2BaxwRqs3MjXGvZzFtEOMI%2FgG2nwrGX4X0e102xddJpsWKhqLNSi90VBSFnnY9585eQc%3D"; + return "jVJLbxshEL5Xyn9A3Ndg%2FNgN8lpyYkW1lDYr2%2B2hl4qw4xiJhQ3Dus2%2FD17HSqqoaQUHBN%2FM9xhmqBrbykUX924Njx1gJL8b61D2DyXtgpNeoUHpVAMoo5abxZdbKQZctsFHr72lp5KPwQoRQjTeUbI4H6%2B9w66BsIFwMBq%2BrW9Luo%2BxlYxZr5Xde4yyEAVn0LTWPwEwSpZJo3HqWH9C45%2FwyXjEVPLDAijbIKuh8ewslR1tUXLjg4bedEl3yiJQslqWdLX8Oa4LmGgQWS74NBvn4j5TxWWeiboY5fySa84nCYxV8mMO8FqO2MHKYVQullTw4STjo4xPt0LItIf5IAn7QUn1IuTKuNq4h48zuz%2BBUH7ebqusuttsKfkOAXvrCUDnZHY0JHv28GZy%2FzuL%2BT%2FinrE3%2FV%2FYWvk1dVwtK2%2BNfiILa%2F2v6xR2TGnE0EEfb6Pi3zUMB8P%2BxtTZrofKzmEL2uwM1JQlHvb%2BX84vPh3XMw%3D%3D"; } return "jZJRT9swFIX%2FiuX31I5pSbCaSoVqWiXYIlp42Asyzu1qybGDr1PWfz83LQKJAZP8YNnf9T3nXE9RtbaT8z5u3S089YCR%2FGmtQzlcVLQPTnqFBqVTLaCMWq7mN9dSjLjsgo9ee0uPJZ%2FDChFCNN5RMn%2FZXnmHfQthBWFnNNzdXld0G2MnGbNeK7v1GGUpSs6g7azfAzBKFkmjcepQ%2Fy86T7RKdlgAZVtkDbSevShlB1eUfPNBw%2BC5ohtlEShZLiq6XDyMmxImGkRWCH6ejQvxmKnyoshEU54V%2FIJrzicJxjrZMTt4LUfsYekwKhcrKng%2ByfhZxs%2FXQsi08mJUTsa%2FKKlPQi6Na4z7%2FXlkj0cI5ff1us7qn6s1JfcQcHCeADoj04MhOXQPbwb3v6OYfZH2lL15%2F9Stkz%2FSi8tF7a3RezK31j9fpbBjSiOGHoZ4WxU%2F1pCP8uHENNlmQGXvsANtNgYaylIf9v5bzv4C"; diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml index bd020d7532..257d65f5be 100644 --- a/testsuite/integration-arquillian/tests/base/pom.xml +++ b/testsuite/integration-arquillian/tests/base/pom.xml @@ -271,6 +271,25 @@ + + unpack-undertow-server + generate-test-resources + + unpack + + + + + org.keycloak.testsuite + integration-arquillian-servers-auth-server-undertow + ${project.version} + jar + ${containers.home}/auth-server-undertow + + + *.jks,*.crt,*.truststore + + diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java index a56b2d4d9d..7dffc28763 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java @@ -39,9 +39,19 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.util.LogChecker; import org.keycloak.testsuite.util.OAuthClient; +import org.wildfly.extras.creaper.commands.undertow.AddUndertowListener; +import org.wildfly.extras.creaper.commands.undertow.RemoveUndertowListener; +import org.wildfly.extras.creaper.commands.undertow.SslVerifyClient; +import org.wildfly.extras.creaper.commands.undertow.UndertowListenerType; +import org.wildfly.extras.creaper.core.CommandFailedException; import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.online.CliException; import org.wildfly.extras.creaper.core.online.OnlineManagementClient; import org.wildfly.extras.creaper.core.online.OnlineOptions; +import org.wildfly.extras.creaper.core.online.operations.Address; +import org.wildfly.extras.creaper.core.online.operations.OperationException; +import org.wildfly.extras.creaper.core.online.operations.Operations; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; import java.io.IOException; import java.net.MalformedURLException; @@ -50,6 +60,7 @@ import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import javax.ws.rs.NotFoundException; @@ -72,6 +83,8 @@ public class AuthServerTestEnricher { @Inject private Event stopContainerEvent; + protected static final boolean AUTH_SERVER_SSL_REQUIRED = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true")); + public static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow"; public static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container"; public static final String AUTH_SERVER_CONTAINER = System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT); @@ -114,9 +127,8 @@ public class AuthServerTestEnricher { int httpPort = Integer.parseInt(System.getProperty("auth.server.http.port")); // property must be set int httpsPort = Integer.parseInt(System.getProperty("auth.server.https.port")); // property must be set - boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required")); - String scheme = sslRequired ? "https" : "http"; - int port = sslRequired ? httpsPort : httpPort; + String scheme = AUTH_SERVER_SSL_REQUIRED ? "https" : "http"; + int port = AUTH_SERVER_SSL_REQUIRED ? httpsPort : httpPort; return String.format("%s://%s:%s", scheme, host, port + clusterPortOffset); } @@ -322,7 +334,56 @@ public class AuthServerTestEnricher { testContextProducer.set(testContext); } - public void initializeOAuthClient(@Observes(precedence = 3) BeforeClass event) { + public void initializeTLS(@Observes(precedence = 3) BeforeClass event) throws Exception { + // TLS for Undertow is configured in KeycloakOnUndertow since it requires + // SSLContext while initializing HTTPS handlers + if (AUTH_SERVER_SSL_REQUIRED && isAuthServerJBossBased() && !suiteContext.isAuthServerCrossDc()) { + log.info("\n\n### Setting up TLS ##\n\n"); + + try { + OnlineManagementClient client = getManagementClient(); + enableTLS(client); + client.close(); + } catch (Exception e) { + log.warn("Failed to set up TLS. This may lead to unexpected behavior unless the test" + + " sets it up manually", e); + } + } + } + + protected static void enableTLS(OnlineManagementClient client) throws Exception { + Administration administration = new Administration(client); + Operations operations = new Operations(client); + + if(!operations.exists(Address.coreService("management").and("security-realm", "UndertowRealm"))) { + client.execute("/core-service=management/security-realm=UndertowRealm:add()"); + client.execute("/core-service=management/security-realm=UndertowRealm/server-identity=ssl:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.jks"); + client.execute("/core-service=management/security-realm=UndertowRealm/authentication=truststore:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.truststore"); + + client.apply(new RemoveUndertowListener.Builder(UndertowListenerType.HTTPS_LISTENER, "https") + .forDefaultServer()); + + administration.reloadIfRequired(); + + client.apply(new AddUndertowListener.HttpsBuilder("https", "default-server", "https") + .securityRealm("UndertowRealm") + .verifyClient(SslVerifyClient.REQUESTED) + .build()); + + administration.reloadIfRequired(); + } else { + log.info("## The Auth Server has already configured TLS. Skipping... ##"); + } + } + + protected boolean isAuthServerJBossBased() { + return containerRegistry.get().getContainers().stream() + .map(ContainerInfo::new) + .filter(ci -> ci.isJBossBased()) + .findFirst().isPresent(); + } + + public void initializeOAuthClient(@Observes(precedence = 4) BeforeClass event) { // TODO workaround. Check if can be removed OAuthClient.updateURLs(suiteContext.getAuthServerInfo().getContextRoot().toString()); OAuthClient oAuthClient = new OAuthClient(); diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CrossDCTestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CrossDCTestEnricher.java index 64963e88bc..3c4e735bb8 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CrossDCTestEnricher.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CrossDCTestEnricher.java @@ -32,11 +32,13 @@ import org.jboss.arquillian.core.api.annotation.Inject; import org.jboss.arquillian.core.api.annotation.Observes; import org.jboss.arquillian.test.spi.event.suite.After; import org.jboss.arquillian.test.spi.event.suite.Before; +import org.jboss.arquillian.test.spi.event.suite.BeforeClass; import org.jboss.logging.Logger; import static org.junit.Assert.assertThat; import org.keycloak.admin.client.Keycloak; import org.keycloak.models.Constants; import org.keycloak.testsuite.arquillian.annotation.InitialDcState; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.crossdc.DC; @@ -49,6 +51,9 @@ import org.jboss.arquillian.container.spi.event.StopContainer; import org.jboss.arquillian.container.spi.event.StopSuiteContainers; import org.jboss.arquillian.core.api.Event; import org.jboss.arquillian.test.spi.event.suite.AfterSuite; +import org.wildfly.extras.creaper.core.ManagementClient; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.OnlineOptions; /** * @@ -154,7 +159,34 @@ public class CrossDCTestEnricher { suspendPeriodicTasks(); } - + + private static void initializeTLS(ContainerInfo containerInfo) { + if (AuthServerTestEnricher.AUTH_SERVER_SSL_REQUIRED) { + log.infof("\n\n### Setting up TLS for %s ##\n\n", containerInfo); + try { + OnlineManagementClient client = getManagementClient(containerInfo); + AuthServerTestEnricher.enableTLS(client); + client.close(); + } catch (Exception e) { + log.warn("Failed to set up TLS. This may lead to unexpected behavior unless the test" + + " sets it up manually", e); + } + + } + } + + private static OnlineManagementClient getManagementClient(ContainerInfo containerInfo) { + try { + return ManagementClient.online(OnlineOptions + .standalone() + .hostAndPort("localhost", Integer.valueOf(containerInfo.getProperties().get("managementPort"))) + .build() + ); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public void afterTest(@Observes After event) { if (!suiteContext.isAuthServerCrossDc()) return; @@ -196,7 +228,7 @@ public class CrossDCTestEnricher { backendTestingClients.put(node, createTestingClientFor(node)); } } - + private static void removeRESTClientsForNode(ContainerInfo node) { if (backendAdminClients.containsKey(node)) { backendAdminClients.get(node).close(); @@ -219,15 +251,15 @@ public class CrossDCTestEnricher { private static Keycloak createAdminClientFor(ContainerInfo node) { log.info("--DC: Initializing admin client for " + node.getContextRoot() + "/auth"); - return Keycloak.getInstance(node.getContextRoot() + "/auth", AuthRealm.MASTER, AuthRealm.ADMIN, AuthRealm.ADMIN, Constants.ADMIN_CLI_CLIENT_ID); + return Keycloak.getInstance(node.getContextRoot() + "/auth", AuthRealm.MASTER, AuthRealm.ADMIN, AuthRealm.ADMIN, Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()); } - + private static KeycloakTestingClient createTestingClientFor(ContainerInfo node) { log.info("--DC: Initializing testing client for " + node.getContextRoot() + "/auth"); return KeycloakTestingClient.getInstance(node.getContextRoot() + "/auth"); } - // Disable periodic tasks in cross-dc tests. It's needed to have some scenarios more stable. + private static void suspendPeriodicTasks() { log.debug("--DC: suspendPeriodicTasks"); backendTestingClients.values().stream().forEach((KeycloakTestingClient testingClient) -> { @@ -275,7 +307,7 @@ public class CrossDCTestEnricher { containerController.get().stop(qualifier); - // Workaround for possible arquillian bug. Needs to cleanup dir manually + // Workaround for possible arquillian bug. Needs to cleanup dir manually String setupCleanServerBaseDir = getContainerProperty(getCacheServer(dc), "setupCleanServerBaseDir"); String cleanServerBaseDir = getContainerProperty(getCacheServer(dc), "cleanServerBaseDir"); @@ -327,6 +359,7 @@ public class CrossDCTestEnricher { if (! containerInfo.isStarted()) { log.infof("--DC: Starting backend auth-server node: %s", containerInfo.getQualifier()); containerController.get().start(containerInfo.getQualifier()); + initializeTLS(containerInfo); createRESTClientsForNode(containerInfo); } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java index e9254de0a8..126bc03420 100755 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java @@ -17,6 +17,9 @@ package org.keycloak.testsuite.client; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; @@ -42,6 +45,10 @@ public class KeycloakTestingClient implements AutoCloseable { } else { ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder(); resteasyClientBuilder.connectionPoolSize(10); + if (serverUrl.startsWith("https")) { + // Disable PKIX path validation errors when running tests using SSL + resteasyClientBuilder.disableTrustManager().hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY); + } resteasyClientBuilder.httpEngine(AdminClientUtil.getCustomClientHttpEngine(resteasyClientBuilder, 10)); client = resteasyClientBuilder.build(); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/drone/KeycloakWebDriverConfigurator.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/drone/KeycloakWebDriverConfigurator.java index 91536e3d9c..d6948ea257 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/drone/KeycloakWebDriverConfigurator.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/drone/KeycloakWebDriverConfigurator.java @@ -28,6 +28,7 @@ import org.jboss.arquillian.drone.webdriver.spi.BrowserCapabilitiesRegistry; import org.jboss.logging.Logger; import org.openqa.selenium.Capabilities; import org.openqa.selenium.phantomjs.PhantomJSDriverService; +import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; import java.util.Arrays; @@ -53,11 +54,17 @@ public class KeycloakWebDriverConfigurator { updateCapabilityKeys("htmlUnit", webDriverCfg, capabilitiesToAdd); updateCapabilityKeys("appium", webDriverCfg, capabilitiesToAdd); configurePhantomJSDriver(webDriverCfg, capabilitiesToAdd); + acceptAllSSLCerts(capabilitiesToAdd); BrowserCapabilities browserCap = registryInstance.get().getEntryFor(webDriverCfg.getBrowser()); webDriverCfg.setBrowserInternal(new KcBrowserCapabilities(capabilitiesToAdd, browserCap)); } + private void acceptAllSSLCerts(DesiredCapabilities capabilitiesToAdd) { + capabilitiesToAdd.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true); + capabilitiesToAdd.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS, true); + } + private void configurePhantomJSDriver(WebDriverConfiguration webDriverCfg, DesiredCapabilities capabilitiesToAdd) { if (!webDriverCfg.getBrowser().equals("phantomjs")) { return; diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java index 37b0e8480e..3f551ad370 100755 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java @@ -21,6 +21,7 @@ import org.jboss.arquillian.test.api.ArquillianResource; import org.junit.Assert; import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.testsuite.arquillian.SuiteContext; +import org.keycloak.testsuite.util.OAuthClient; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -38,6 +39,9 @@ public abstract class AbstractPage { @ArquillianResource protected WebDriver driver; + @ArquillianResource + protected OAuthClient oauth; + public void assertCurrent() { String name = getClass().getSimpleName(); Assert.assertTrue("Expected " + name + " but was " + driver.getTitle() + " (" + driver.getCurrentUrl() + ")", diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppPage.java index 406ab08ecb..72260db8b8 100755 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppPage.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AppPage.java @@ -29,20 +29,17 @@ import javax.ws.rs.core.UriBuilder; */ public class AppPage extends AbstractPage { - public static final String AUTH_SERVER_URL = "http://localhost:8180/auth"; - public static final String baseUrl = "http://localhost:8180/auth/realms/master/app/auth"; - @FindBy(id = "account") private WebElement accountLink; @Override public void open() { - driver.navigate().to(baseUrl); + driver.navigate().to(oauth.APP_AUTH_ROOT); } @Override public boolean isCurrent() { - return driver.getCurrentUrl().startsWith(baseUrl); + return driver.getCurrentUrl().startsWith(oauth.APP_AUTH_ROOT); } public RequestType getRequestType() { @@ -58,10 +55,9 @@ public class AppPage extends AbstractPage { } public void logout() { - String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(AUTH_SERVER_URL)) - .queryParam(OAuth2Constants.REDIRECT_URI,baseUrl).build("test").toString(); + String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(oauth.AUTH_SERVER_ROOT)) + .queryParam(OAuth2Constants.REDIRECT_URI, oauth.APP_AUTH_ROOT).build("test").toString(); driver.navigate().to(logoutUri); - } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/servlet/ApplicationServlet.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/servlet/ApplicationServlet.java index b5db222e02..eaaa920ae3 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/servlet/ApplicationServlet.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/servlet/ApplicationServlet.java @@ -46,7 +46,7 @@ public class ApplicationServlet extends HttpServlet { PrintWriter pw = resp.getWriter(); pw.printf("%s", title); - UriBuilder base = UriBuilder.fromUri("http://localhost:8081/auth"); + UriBuilder base = UriBuilder.fromUri("/auth"); pw.printf(LINK, RealmsResource.accountUrl(base).build("test"), "account", "account"); pw.print(""); diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java index d0f83cc58f..538ccd29c3 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java @@ -91,6 +91,7 @@ public class OAuthClient { public static String SERVER_ROOT; public static String AUTH_SERVER_ROOT; public static String APP_ROOT; + public static String APP_AUTH_ROOT; private static final boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required")); static { @@ -102,6 +103,7 @@ public class OAuthClient { SERVER_ROOT = serverRoot; AUTH_SERVER_ROOT = SERVER_ROOT + "/auth"; APP_ROOT = AUTH_SERVER_ROOT + "/realms/master/app"; + APP_AUTH_ROOT = APP_ROOT + "/auth"; } private WebDriver driver; @@ -659,7 +661,7 @@ public class OAuthClient { public OIDCConfigurationRepresentation doWellKnownRequest(String realm) { try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - return SimpleHttp.doGet(AUTH_SERVER_ROOT + "/realms/" + realm + "/.well-known/openid-configuration", client).asJson(OIDCConfigurationRepresentation.class); + return SimpleHttp.doGet(baseUrl + "/realms/" + realm + "/.well-known/openid-configuration", client).asJson(OIDCConfigurationRepresentation.class); } catch (IOException ex) { throw new RuntimeException(ex); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java index 600e80d671..797722466c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java @@ -35,9 +35,11 @@ import org.keycloak.admin.client.resource.UserResource; import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.common.util.Time; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.services.resources.account.AccountFormService; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.KcArquillian; @@ -70,7 +72,17 @@ import org.wildfly.extras.creaper.core.online.operations.Operations; import org.wildfly.extras.creaper.core.online.operations.admin.Administration; import javax.ws.rs.NotFoundException; +import javax.ws.rs.core.UriBuilder; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintWriter; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -79,6 +91,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Scanner; import java.util.concurrent.TimeoutException; import static org.hamcrest.Matchers.equalTo; @@ -98,6 +111,8 @@ import static org.keycloak.testsuite.util.URLUtils.navigateToUri; public abstract class AbstractKeycloakTest { protected static final boolean AUTH_SERVER_SSL_REQUIRED = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "false")); + protected static final String AUTH_SERVER_SCHEME = AUTH_SERVER_SSL_REQUIRED ? "https" : "http"; + protected static final String AUTH_SERVER_PORT = AUTH_SERVER_SSL_REQUIRED ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180"); protected static final String ENGLISH_LOCALE_NAME = "English"; @@ -145,13 +160,6 @@ public abstract class AbstractKeycloakTest { private boolean resetTimeOffset; - @BeforeClass - public static void setUpAuthServer() throws Exception { - if (AUTH_SERVER_SSL_REQUIRED) { - enableHTTPSForAuthServer(); - } - } - @Before public void beforeAbstractKeycloakTest() throws Exception { adminClient = testContext.getAdminClient(); @@ -364,10 +372,66 @@ public abstract class AbstractKeycloakTest { addTestRealms(); log.info("importing test realms"); for (RealmRepresentation testRealm : testRealmReps) { + if (modifyRealmForSSL()) { + if (AUTH_SERVER_SSL_REQUIRED) { + log.debugf("Modifying %s for SSL", testRealm.getId()); + for (ClientRepresentation cr : testRealm.getClients()) { + modifyMainUrls(cr); + modifyRedirectUrls(cr); + modifySamlAttributes(cr); + } + } + } importRealm(testRealm); } } + private void modifySamlAttributes(ClientRepresentation cr) { + if (cr.getProtocol() != null && cr.getProtocol().equals("saml")) { + log.info("Modifying attributes of SAML client: " + cr.getClientId()); + for (Map.Entry entry : cr.getAttributes().entrySet()) { + cr.getAttributes().put(entry.getKey(), replaceHttpValuesWithHttps(entry.getValue())); + } + } + } + + private void modifyRedirectUrls(ClientRepresentation cr) { + if (cr.getRedirectUris() != null && cr.getRedirectUris().size() > 0) { + List redirectUrls = cr.getRedirectUris(); + List fixedRedirectUrls = new ArrayList<>(redirectUrls.size()); + for (String url : redirectUrls) { + fixedRedirectUrls.add(replaceHttpValuesWithHttps(url)); + } + cr.setRedirectUris(fixedRedirectUrls); + } + } + + private void modifyMainUrls(ClientRepresentation cr) { + cr.setBaseUrl(replaceHttpValuesWithHttps(cr.getBaseUrl())); + cr.setAdminUrl(replaceHttpValuesWithHttps(cr.getAdminUrl())); + } + + private String replaceHttpValuesWithHttps(String input) { + if (input == null) { + return null; + } + if ("".equals(input)) { + return ""; + } + return input + .replace("http", "https") + .replace("8080", "8543") + .replace("8180", "8543"); + } + + /** + * @return Return true if you wish to automatically post-process realm and replace + * all http values with https (and correct ports). + */ + protected boolean modifyRealmForSSL() { + return false; + } + protected void removeAllRealmsDespiteMaster() { // remove all realms (accidentally left by other tests) except for master @@ -536,28 +600,31 @@ public abstract class AbstractKeycloakTest { return log; } - private static void enableHTTPSForAuthServer() throws IOException, CommandFailedException, TimeoutException, InterruptedException, CliException, OperationException { - OnlineManagementClient client = AuthServerTestEnricher.getManagementClient(); - Administration administration = new Administration(client); - Operations operations = new Operations(client); + protected String getAccountRedirectUrl(String realm) { + return AccountFormService + .loginRedirectUrl(UriBuilder.fromUri(oauth.AUTH_SERVER_ROOT)) + .build(realm) + .toString(); + } - if(!operations.exists(Address.coreService("management").and("security-realm", "UndertowRealm"))) { - client.execute("/core-service=management/security-realm=UndertowRealm:add()"); - client.execute("/core-service=management/security-realm=UndertowRealm/server-identity=ssl:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.jks"); - client.execute("/core-service=management/security-realm=UndertowRealm/authentication=truststore:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.truststore"); + protected String getAccountRedirectUrl() { + return getAccountRedirectUrl("test"); + } + + protected static InputStream httpsAwareConfigurationStream(InputStream input) throws IOException { + if (!AUTH_SERVER_SSL_REQUIRED) { + return input; } - - client.apply(new RemoveUndertowListener.Builder(UndertowListenerType.HTTPS_LISTENER, "https") - .forDefaultServer()); - - administration.reloadIfRequired(); - - client.apply(new AddUndertowListener.HttpsBuilder("https", "default-server", "https") - .securityRealm("UndertowRealm") - .verifyClient(SslVerifyClient.REQUESTED) - .build()); - - administration.reloadIfRequired(); - client.close(); + PipedInputStream in = new PipedInputStream(); + final PipedOutputStream out = new PipedOutputStream(in); + try (PrintWriter pw = new PrintWriter(out)) { + try (Scanner s = new Scanner(input)) { + while (s.hasNextLine()) { + String lineWithReplaces = s.nextLine().replace("http://localhost:8180/auth", AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT + "/auth"); + pw.println(lineWithReplaces); + } + } + } + return in; } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java index 107493cb11..755a537d3a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java @@ -53,7 +53,8 @@ public class AssertEvents implements TestRule { public static final String DEFAULT_REALM = "test"; public static final String DEFAULT_USERNAME = "test-user@localhost"; - String defaultRedirectUri = "http://localhost:8180/auth/realms/master/app/auth"; + public static final String DEFAULT_HTTP_REDIRECT_URI = "http://localhost:8180/auth/realms/master/app/auth"; + public static final String DEFAULT_HTTPS_REDIRECT_URI = "https://localhost:8543/auth/realms/master/app/auth"; private AbstractKeycloakTest context; @@ -100,7 +101,7 @@ public class AssertEvents implements TestRule { //.detail(Details.USERNAME, DEFAULT_USERNAME) //.detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL) //.detail(Details.AUTH_TYPE, AuthorizationEndpoint.CODE_AUTH_TYPE) - .detail(Details.REDIRECT_URI, defaultRedirectUri) + .detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI))) .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) .session(isUUID()); } @@ -119,7 +120,7 @@ public class AssertEvents implements TestRule { .detail(Details.CODE_ID, isCodeId()) .detail(Details.USERNAME, DEFAULT_USERNAME) .detail(Details.AUTH_METHOD, "form") - .detail(Details.REDIRECT_URI, defaultRedirectUri) + .detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI))) .session(isUUID()); } @@ -145,7 +146,7 @@ public class AssertEvents implements TestRule { public ExpectedEvent expectLogout(String sessionId) { return expect(EventType.LOGOUT).client((String) null) - .detail(Details.REDIRECT_URI, defaultRedirectUri) + .detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI))) .session(sessionId); } @@ -163,7 +164,7 @@ public class AssertEvents implements TestRule { .detail(Details.USERNAME, username) .detail(Details.EMAIL, email) .detail(Details.REGISTER_METHOD, "form") - .detail(Details.REDIRECT_URI, defaultRedirectUri); + .detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI))); } public ExpectedEvent expectAccount(EventType event) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountFormServiceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountFormServiceTest.java index 755a0422b6..c8c1901d01 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountFormServiceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/AccountFormServiceTest.java @@ -38,7 +38,6 @@ import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.services.resources.RealmsResource; import org.keycloak.services.resources.account.AccountFormService; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -70,7 +69,6 @@ import java.util.Collections; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; -import javax.ws.rs.core.UriBuilder; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -85,6 +83,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import javax.ws.rs.core.UriBuilder; + /** * @author Stian Thorgersen * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. @@ -135,11 +135,13 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { RealmBuilder.edit(testRealm) .user(user2) .user(realmAdmin); - } - private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth"); - private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString(); - public static String ACCOUNT_REDIRECT = AccountFormService.loginRedirectUrl(BASE.clone()).build("test").toString(); + if (AUTH_SERVER_SSL_REQUIRED) { + // Some scenarios here use redirections, so we need to fix the base url + findTestApp(testRealm) + .setBaseUrl(String.format("%s://localhost:%s/auth/realms/master/app/auth", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT)); + } + } // Create second session @Drone @@ -203,12 +205,12 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { Assert.assertTrue(appPage.isCurrent()); - driver.navigate().to(profilePage.getPath() + "?referrer=test-app&referrer_uri=http://localhost:8180/auth/realms/master/app/auth?test"); + driver.navigate().to(String.format("%s?referrer=test-app&referrer_uri=%s://localhost:%s/auth/realms/master/app/auth?test", profilePage.getPath(), AUTH_SERVER_SCHEME, AUTH_SERVER_PORT)); Assert.assertTrue(profilePage.isCurrent()); profilePage.backToApplication(); Assert.assertTrue(appPage.isCurrent()); - Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl()); + Assert.assertEquals(oauth.APP_AUTH_ROOT + "?test", driver.getCurrentUrl()); driver.navigate().to(profilePage.getPath() + "?referrer=test-app"); Assert.assertTrue(profilePage.isCurrent()); @@ -242,7 +244,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - EventRepresentation event = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + EventRepresentation event = events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); String sessionId = event.getSessionId(); String userId = event.getUserId(); @@ -288,7 +290,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { public void changePasswordWithBlankCurrentPassword() { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("", "new", "new"); Assert.assertEquals("Please specify password.", profilePage.getError()); @@ -305,7 +307,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("password", "1234", "1234"); Assert.assertEquals("Invalid password: minimum length 8.", profilePage.getError()); @@ -322,7 +324,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("password", "invalidPassword1", "invalidPassword1"); Assert.assertEquals("Invalid password: must contain at least 2 numerical digits.", profilePage.getError()); @@ -339,7 +341,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("password", "iNVALIDPASSWORD", "iNVALIDPASSWORD"); Assert.assertEquals("Invalid password: must contain at least 2 lower case characters.", profilePage.getError()); @@ -356,7 +358,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("password", "Invalidpassword", "Invalidpassword"); Assert.assertEquals("Invalid password: must contain at least 2 upper case characters.", profilePage.getError()); @@ -374,7 +376,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("password", "invalidPassword*", "invalidPassword*"); Assert.assertEquals("Invalid password: must contain at least 2 special characters.", profilePage.getError()); @@ -392,7 +394,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("password", "test-user@localhost", "test-user@localhost"); Assert.assertEquals("Invalid password: must not be equal to the username.", profilePage.getError()); @@ -410,7 +412,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); changePasswordPage.changePassword("password", "invalidPassword", "invalidPassword"); Assert.assertEquals("Invalid password: fails to match regex pattern(s).", profilePage.getError()); @@ -456,7 +458,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("user-changePasswordWithPasswordHistoryPolicyThreePasswords", "password"); - events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); assertChangePasswordFails ("password", "password"); // current: password assertNumberOfStoredCredentials(1); @@ -491,7 +493,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("user-changePasswordWithPasswordHistoryPolicyTwoPasswords", "password"); - events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); assertChangePasswordFails ("password", "password"); // current: password assertNumberOfStoredCredentials(1); @@ -522,7 +524,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("user-changePasswordWithPasswordHistoryPolicyOnePwds", "password"); - events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); assertChangePasswordFails ("password", "password"); // current: password assertNumberOfStoredCredentials(1); @@ -543,7 +545,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("user-changePasswordWithPasswordHistoryPolicyZeroPwdsInHistory", "password"); - events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); assertChangePasswordFails ("password", "password"); // current: password assertNumberOfStoredCredentials(1); @@ -564,7 +566,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { changePasswordPage.open(); loginPage.login("user-changePasswordWithPasswordHistoryPolicyExpiration", "password"); - events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent(); + events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent(); assertNumberOfStoredCredentials(1); assertChangePasswordSucceeds("password", "password2"); // current: password @@ -597,7 +599,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { profilePage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent(); Assert.assertEquals("test-user@localhost", profilePage.getUsername()); Assert.assertEquals("Tom", profilePage.getFirstName()); @@ -736,7 +738,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { profilePage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent(); Assert.assertEquals("test-user@localhost", profilePage.getUsername()); Assert.assertEquals("Tom", profilePage.getFirstName()); @@ -845,7 +847,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { profilePage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent(); Assert.assertEquals("test-user@localhost", profilePage.getUsername()); Assert.assertEquals("test-user@localhost", profilePage.getEmail()); @@ -883,7 +885,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { profilePage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent(); Assert.assertEquals("test-user@localhost", profilePage.getUsername()); Assert.assertEquals("test-user@localhost", profilePage.getEmail()); @@ -899,7 +901,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { totpPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=totp").assertEvent(); Assert.assertTrue(totpPage.isCurrent()); @@ -968,7 +970,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { UserRepresentation noAccessUser = this.findUser("test-user-no-access@localhost"); events.expectLogin().client("account").user(noAccessUser.getId()) .detail(Details.USERNAME, "test-user-no-access@localhost") - .detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent(); + .detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent(); Assert.assertTrue("Expected errorPage but was " + driver.getTitle() + " (" + driver.getCurrentUrl() + "). Page source: " + driver.getPageSource(), errorPage.isCurrent()); Assert.assertEquals("No access", errorPage.getError()); @@ -1126,7 +1128,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { applicationsPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=applications").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=applications").assertEvent(); applicationsPage.assertCurrent(); Map apps = applicationsPage.getApplications(); @@ -1140,13 +1142,13 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { "Offline access" )); Assert.assertThat(accountEntry.getClientScopesGranted(), containsInAnyOrder("Full Access")); - Assert.assertEquals("http://localhost:8180/auth/realms/test/account", accountEntry.getHref()); + Assert.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test/account", accountEntry.getHref()); AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app"); Assert.assertEquals(6, testAppEntry.getRolesAvailable().size()); Assert.assertTrue(testAppEntry.getRolesAvailable().contains("Offline access")); Assert.assertTrue(testAppEntry.getClientScopesGranted().contains("Full Access")); - Assert.assertEquals("http://localhost:8180/auth/realms/master/app/auth", testAppEntry.getHref()); + Assert.assertEquals(oauth.APP_AUTH_ROOT, testAppEntry.getHref()); AccountApplicationsPage.AppEntry thirdPartyEntry = apps.get("third-party"); Assert.assertEquals(3, thirdPartyEntry.getRolesAvailable().size()); @@ -1162,7 +1164,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest { Assert.assertEquals("http://localhost:8180/foo/bar/baz", rootUrlClient.getHref()); AccountApplicationsPage.AppEntry authzApp = apps.get("test-app-authz"); - Assert.assertEquals("http://localhost:8180/test-app-authz", authzApp.getHref()); + Assert.assertEquals(oauth.SERVER_ROOT + "/test-app-authz", authzApp.getHref()); AccountApplicationsPage.AppEntry namedApp = apps.get("My Named Test App"); Assert.assertEquals("http://localhost:8180/namedapp/base", namedApp.getHref()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomAuthFlowOTPTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomAuthFlowOTPTest.java index 7bc6e67b6c..686b72a167 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomAuthFlowOTPTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomAuthFlowOTPTest.java @@ -352,7 +352,7 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest { public void conditionalOTPRequestHeaderSkip() { //prepare config - request header skip, default to force Map config = new HashMap<>(); - String port = System.getProperty("auth.server.http.port", "8180"); + String port = AUTH_SERVER_PORT; config.put(SKIP_OTP_FOR_HTTP_HEADER, "Host: localhost:" + port); config.put(DEFAULT_OTP_OUTCOME, FORCE); @@ -368,7 +368,7 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest { public void conditionalOTPRequestHeaderForce() { //prepare config - equest header force, default to skip Map config = new HashMap<>(); - String port = System.getProperty("auth.server.http.port", "8180"); + String port = AUTH_SERVER_PORT; config.put(FORCE_OTP_FOR_HTTP_HEADER, "Host: localhost:" + port); config.put(DEFAULT_OTP_OUTCOME, SKIP); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomThemeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomThemeTest.java index d9e30b3383..1ecebf58ee 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomThemeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/custom/CustomThemeTest.java @@ -17,6 +17,8 @@ package org.keycloak.testsuite.account.custom; +import javax.ws.rs.core.UriBuilder; + import org.jboss.arquillian.graphene.page.Page; import org.junit.Assert; import org.junit.Rule; @@ -25,6 +27,7 @@ import org.keycloak.events.Details; import org.keycloak.events.EventType; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.services.resources.account.AccountFormService; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.account.AccountFormServiceTest; @@ -68,7 +71,7 @@ public class CustomThemeTest extends AbstractTestRealmKeycloakTest { profilePage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, AccountFormServiceTest.ACCOUNT_REDIRECT).assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent(); Assert.assertEquals("test-user@localhost", profilePage.getEmail()); Assert.assertEquals("", profilePage.getAttribute("street")); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java index ee958fa419..aad688cce0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractAdapterTest.java @@ -89,23 +89,31 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest { log.info("Setting redirect-uris in test realm '" + tr.getRealm() + "' as " + (isRelative() ? "" : "non-") + "relative"); modifyClientRedirectUris(tr, "http://localhost:8080", ""); + modifyClientRedirectUris(tr, "^(/.*/\\*)", + "http://localhost:" + System.getProperty("app.server.http.port", "8280") + "$1", + "http://localhost:" + System.getProperty("auth.server.http.port", "8180") + "$1", + "https://localhost:" + System.getProperty("app.server.https.port", "8643") + "$1", + "https://localhost:" + System.getProperty("auth.server.http.port", "8543") + "$1"); + + modifyClientWebOrigins(tr, "http://localhost:8080", + "http://localhost:" + System.getProperty("app.server.http.port", "8280"), + "http://localhost:" + System.getProperty("auth.server.http.port", "8180"), + "https://localhost:" + System.getProperty("app.server.https.port", "8643"), + "https://localhost:" + System.getProperty("auth.server.http.port", "8543")); + modifyClientUrls(tr, "http://localhost:8080", ""); if (isRelative()) { - modifyClientRedirectUris(tr, appServerContextRootPage.toString(), ""); modifyClientUrls(tr, appServerContextRootPage.toString(), ""); - modifyClientWebOrigins(tr, "8080", System.getProperty("auth.server.http.port", null)); modifySamlMasterURLs(tr, "/", "http://localhost:" + System.getProperty("auth.server.http.port", null) + "/"); modifySAMLClientsAttributes(tr, "8080", System.getProperty("auth.server.http.port", "8180")); } else { - modifyClientRedirectUris(tr, "^(/.*/\\*)", appServerContextRootPage.toString() + "$1"); modifyClientUrls(tr, "^(/.*)", appServerContextRootPage.toString() + "$1"); - modifyClientWebOrigins(tr, "8080", System.getProperty("app.server.http.port", null)); - modifySamlMasterURLs(tr, "8080", System.getProperty("auth.server.http.port", null)); + modifySamlMasterURLs(tr, "8080", AUTH_SERVER_PORT); modifySAMLClientsAttributes(tr, "http://localhost:8080", appServerContextRootPage.toString()); modifyClientJWKSUrl(tr, "^(/.*)", appServerContextRootPage.toString() + "$1"); } - if ("true".equals(System.getProperty("auth.server.ssl.required"))) { + if (AUTH_SERVER_SSL_REQUIRED) { tr.setSslRequired("all"); } } @@ -135,14 +143,17 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest { return testContext.isRelativeAdapterTest(); } - protected void modifyClientRedirectUris(RealmRepresentation realm, String regex, String replacement) { + protected void modifyClientRedirectUris(RealmRepresentation realm, String regex, String... replacement) { if (realm.getClients() != null) { for (ClientRepresentation client : realm.getClients()) { List redirectUris = client.getRedirectUris(); if (redirectUris != null) { List newRedirectUris = new ArrayList<>(); for (String uri : redirectUris) { - newRedirectUris.add(uri.replaceAll(regex, replacement)); + for (String uriReplacement : replacement) { + newRedirectUris.add(uri.replaceAll(regex, uriReplacement)); + } + } client.setRedirectUris(newRedirectUris); } @@ -165,14 +176,16 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest { } } - protected void modifyClientWebOrigins(RealmRepresentation realm, String regex, String replacement) { + protected void modifyClientWebOrigins(RealmRepresentation realm, String regex, String... replacement) { if (realm.getClients() != null) { for (ClientRepresentation client : realm.getClients()) { List webOrigins = client.getWebOrigins(); if (webOrigins != null) { List newWebOrigins = new ArrayList<>(); for (String uri : webOrigins) { - newWebOrigins.add(uri.replaceAll(regex, replacement)); + for (String originReplacement : replacement) { + newWebOrigins.add(uri.replaceAll(regex, originReplacement)); + } } client.setWebOrigins(newWebOrigins); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractExampleAdapterTest.java index 2966a78b26..19cd73810f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/AbstractExampleAdapterTest.java @@ -23,11 +23,14 @@ import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; +import org.keycloak.testsuite.utils.arquillian.DeploymentArchiveProcessorUtils; import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.file.Paths; +import java.util.function.Consumer; +import java.util.function.Supplier; /** * @@ -55,13 +58,37 @@ public abstract class AbstractExampleAdapterTest extends AbstractAdapterTest { EXAMPLES_WEB_XML = EXAMPLES_HOME + "/web.xml"; } - protected static WebArchive exampleDeployment(String name) throws IOException { - return ShrinkWrap.createFromZipFile(WebArchive.class, - new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war")) - .addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML); + protected static WebArchive exampleDeployment(String name) { + return exampleDeployment(name, webArchive -> {}); + } + + protected static WebArchive exampleDeployment(String name, Consumer additionalResources) { + WebArchive webArchive = ShrinkWrap.createFromZipFile(WebArchive.class, + new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war")) + .addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML); + + additionalResources.accept(webArchive); + + modifyOIDCAdapterConfig(webArchive); + + return webArchive; + } + + protected static void modifyOIDCAdapterConfig(WebArchive webArchive) { + if (webArchive.contains(DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH)) { + DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(webArchive, DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH); + } + + if (webArchive.contains(DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH_JS)) { + DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(webArchive, DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH_JS); + } } protected static WebArchive exampleDeployment(String name, String contextPath) throws IOException { + return exampleDeployment(name, contextPath, webArchive -> {}); + } + + protected static WebArchive exampleDeployment(String name, String contextPath, Consumer additionalResources) throws IOException { URL webXML = Paths.get(EXAMPLES_WEB_XML).toUri().toURL(); String webXmlContent = IOUtils.toString(webXML.openStream(), "UTF-8") .replace("%CONTEXT_PATH%", contextPath); @@ -69,12 +96,12 @@ public abstract class AbstractExampleAdapterTest extends AbstractAdapterTest { new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war")) .addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML) .add(new StringAsset(webXmlContent), "/WEB-INF/web.xml"); + + additionalResources.accept(webArchive); + + modifyOIDCAdapterConfig(webArchive); + return webArchive; } - protected static JavaArchive exampleJarDeployment(String name) { - return ShrinkWrap.createFromZipFile(JavaArchive.class, - new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".jar")); - } - } \ No newline at end of file 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 79198086b8..9e2e703fdc 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 @@ -24,6 +24,7 @@ import org.jboss.shrinkwrap.api.spec.WebArchive; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; import org.keycloak.testsuite.util.WaitUtils; +import org.keycloak.testsuite.utils.arquillian.DeploymentArchiveProcessorUtils; import org.keycloak.testsuite.utils.io.IOUtil; import org.openqa.selenium.By; @@ -51,9 +52,16 @@ public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest { URL config2Url = AbstractServletsAdapterTest.class.getResource(webInfPath + config2); Assert.assertNotNull("config2Url should be in " + webInfPath + config2, config2Url); - return servletDeployment + servletDeployment .add(new UrlAsset(config1Url), "/WEB-INF/classes/" + config1) .add(new UrlAsset(config2Url), "/WEB-INF/classes/" + config2); + + // In this scenario DeploymentArchiveProcessorUtils can not act automatically since the adapter configurations + // are not stored in typical places. We need to modify them manually. + DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(servletDeployment, "/WEB-INF/classes/" + config1); + DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(servletDeployment, "/WEB-INF/classes/" + config2); + + return servletDeployment; } protected static WebArchive servletDeployment(String name, Class... servletClasses) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java index 030ad7243e..eb4a2de583 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/AbstractPhotozJavascriptExecutorTest.java @@ -2,7 +2,9 @@ package org.keycloak.testsuite.adapter.example.authorization; import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.graphene.page.Page; +import org.junit.Assume; import org.junit.Before; +import org.junit.BeforeClass; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest; @@ -52,6 +54,11 @@ public abstract class AbstractPhotozJavascriptExecutorTest extends AbstractExamp protected UserRepresentation jdoeUser = UserBuilder.create().username("jdoe").password("jdoe").build(); + @BeforeClass + public static void checkIfTLSIsTurnedOn() { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); + } + @Before public void setDefaultValues() { jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java index df41c8bcf7..f9c84269b2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/authorization/PhotozExampleLazyLoadPathsAdapterTest.java @@ -44,7 +44,7 @@ public class PhotozExampleLazyLoadPathsAdapterTest extends AbstractPhotozExample @Deployment(name = RESOURCE_SERVER_ID, managed = false, testable = false) public static WebArchive deploymentResourceServer() throws IOException { - return exampleDeployment(RESOURCE_SERVER_ID) - .addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/photoz/keycloak-lazy-load-path-authz-service.json"), "keycloak.json"); + return exampleDeployment(RESOURCE_SERVER_ID, + webArchive -> webArchive.addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/photoz/keycloak-lazy-load-path-authz-service.json"), "keycloak.json")); } } \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/CorsExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/CorsExampleAdapterTest.java index 7574fc02d8..926ae06b2d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/CorsExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/cors/CorsExampleAdapterTest.java @@ -55,7 +55,14 @@ import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad; import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; /** - * Created by fkiss. + * Tests CORS fuctionality in adapters. + * + *

+ * Note, for SSL this test disables TLS certificate verification. Since CORS uses different hostnames + * (localhost-auth for example), the Subject Name won't match. + *

+ * + * @author fkiss */ @AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY) @AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY_DEPRECATED) @@ -88,7 +95,7 @@ public class CorsExampleAdapterTest extends AbstractExampleAdapterTest { @JavascriptBrowser private Account jsDriverTestRealmAccount; - @Deployment(name = AngularCorsProductTestApp.DEPLOYMENT_NAME) + @Deployment(name = AngularCorsProductTestApp.DEPLOYMENT_NAME, managed = false) protected static WebArchive angularCorsProductExample() throws IOException { return exampleDeployment(AngularCorsProductTestApp.CLIENT_ID); } @@ -108,11 +115,13 @@ public class CorsExampleAdapterTest extends AbstractExampleAdapterTest { public void onBefore() { Assume.assumeFalse(System.getProperty("os.name").startsWith("Windows")); deployer.deploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME); + deployer.deploy(AngularCorsProductTestApp.DEPLOYMENT_NAME); } @After public void onAfter() { deployer.undeploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME); + deployer.undeploy(AngularCorsProductTestApp.DEPLOYMENT_NAME); } static{ diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/jaas/LoginModulesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/jaas/LoginModulesTest.java index 62da9d0a9e..12bf4edc00 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/jaas/LoginModulesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/jaas/LoginModulesTest.java @@ -17,10 +17,19 @@ package org.keycloak.testsuite.adapter.jaas; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.lang.invoke.MethodHandles; +import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Scanner; import java.util.Set; import javax.security.auth.Subject; @@ -36,7 +45,10 @@ import javax.security.auth.login.LoginException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; + +import org.junit.Assume; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.keycloak.KeycloakPrincipal; import org.keycloak.adapters.jaas.AbstractKeycloakLoginModule; @@ -55,11 +67,50 @@ import org.keycloak.testsuite.utils.io.IOUtil; */ public class LoginModulesTest extends AbstractKeycloakTest { + public static final URI DIRECT_GRANT_CONFIG; + public static final URI BEARER_CONFIG; + + private static final File DIRECT_GRANT_CONFIG_FILE; + private static final File BEARER_CONFIG_FILE; + + static { + try { + DIRECT_GRANT_CONFIG = MethodHandles.lookup().lookupClass().getResource("/adapter-test/customer-portal/WEB-INF/keycloak.json").toURI(); + BEARER_CONFIG = MethodHandles.lookup().lookupClass().getResource("/adapter-test/customer-db-audience-required/WEB-INF/keycloak.json").toURI(); + + DIRECT_GRANT_CONFIG_FILE = File.createTempFile("LoginModulesTest", "testDirectAccessGrantLoginModuleLoginFailed"); + BEARER_CONFIG_FILE = File.createTempFile("LoginModulesTest", "testBearerLoginFailedLogin"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Override public void addTestRealms(List testRealms) { testRealms.add(IOUtil.loadRealm("/adapter-test/demorealm.json")); } + @BeforeClass + public static void createTemporaryFiles() throws Exception { + copyContentAndReplaceAuthServerAddress(new File(DIRECT_GRANT_CONFIG), DIRECT_GRANT_CONFIG_FILE); + copyContentAndReplaceAuthServerAddress(new File(BEARER_CONFIG), BEARER_CONFIG_FILE); + } + + public void removeTemporaryFiles() { + DIRECT_GRANT_CONFIG_FILE.deleteOnExit(); + BEARER_CONFIG_FILE.deleteOnExit(); + } + + private static void copyContentAndReplaceAuthServerAddress(File input, File output) throws IOException { + try (InputStream inputStream = httpsAwareConfigurationStream(new FileInputStream(input))) { + try (FileOutputStream outputStream = new FileOutputStream(output)) { + byte[] buffer = new byte[inputStream.available()]; + inputStream.read(buffer); + outputStream.write(buffer); + } + } + } + @Before public void generateAudienceClientScope() { if (ApiUtil.findClientScopeByName(adminClient.realm("demo"), "customer-db-audience-required") != null) { @@ -76,6 +127,10 @@ public class LoginModulesTest extends AbstractKeycloakTest { @Test public void testDirectAccessGrantLoginModuleLoginFailed() throws Exception { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); + + + LoginContext loginContext = new LoginContext("does-not-matter", null, createJaasCallbackHandler("bburke@redhat.com", "bad-password"), createJaasConfigurationForDirectGrant(null)); @@ -91,6 +146,7 @@ public class LoginModulesTest extends AbstractKeycloakTest { @Test public void testDirectAccessGrantLoginModuleLoginSuccess() throws Exception { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); oauth.realm("demo"); LoginContext loginContext = directGrantLogin(null); @@ -113,6 +169,7 @@ public class LoginModulesTest extends AbstractKeycloakTest { @Test public void testBearerLoginFailedLogin() throws Exception { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); oauth.realm("demo"); LoginContext directGrantCtx = directGrantLogin(null); @@ -137,6 +194,7 @@ public class LoginModulesTest extends AbstractKeycloakTest { @Test public void testBearerLoginSuccess() throws Exception { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); oauth.realm("demo"); LoginContext directGrantCtx = directGrantLogin("customer-db-audience-required"); @@ -213,7 +271,7 @@ public class LoginModulesTest extends AbstractKeycloakTest { @Override public AppConfigurationEntry[] getAppConfigurationEntry(String name) { Map options = new HashMap<>(); - options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, "classpath:adapter-test/customer-portal/WEB-INF/keycloak.json"); + options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, DIRECT_GRANT_CONFIG_FILE.getAbsolutePath()); if (scope != null) { options.put(DirectAccessGrantsLoginModule.SCOPE_OPTION, scope); } @@ -231,7 +289,7 @@ public class LoginModulesTest extends AbstractKeycloakTest { @Override public AppConfigurationEntry[] getAppConfigurationEntry(String name) { Map options = new HashMap<>(); - options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, "classpath:adapter-test/customer-db-audience-required/WEB-INF/keycloak.json"); + options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, BEARER_CONFIG_FILE.getAbsolutePath()); AppConfigurationEntry LMConfiguration = new AppConfigurationEntry(BearerTokenLoginModule.class.getName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); return new AppConfigurationEntry[] { LMConfiguration }; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java index a649840900..376138abfb 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/AbstractJavascriptTest.java @@ -112,7 +112,7 @@ public abstract class AbstractJavascriptTest extends AbstractAuthTest { .client( ClientBuilder.create() .clientId(CLIENT_ID) - .redirectUris(JAVASCRIPT_URL + "/*", JAVASCRIPT_ENCODED_SPACE_URL + "/*") + .redirectUris(oauth.SERVER_ROOT + JAVASCRIPT_URL + "/*", oauth.SERVER_ROOT + JAVASCRIPT_ENCODED_SPACE_URL + "/*") .publicClient() ) .accessTokenLifespan(30 + TOKEN_LIFESPAN_LEEWAY) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java index e344eea93d..d2df9ac657 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/javascript/JavascriptAdapterTest.java @@ -94,6 +94,10 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { jsDriver.manage().deleteAllCookies(); setStandardFlowForClient(); + + //tests cleanup + oauth.setDriver(driver); + setTimeOffset(0); } protected JSObjectBuilder defaultArguments() { @@ -175,44 +179,46 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { ClientResource clientResource = ApiUtil.findClientResourceByClientId(adminClient.realm(REALM_NAME), CLIENT_ID); ClientRepresentation client = clientResource.toRepresentation(); - client.setConsentRequired(true); - clientResource.update(client); + try { + client.setConsentRequired(true); + clientResource.update(client); - testExecutor.init(defaultArguments(), this::assertInitNotAuth) - .login(this::assertOnLoginPage) - .loginForm(testUser, (driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1)) + testExecutor.init(defaultArguments(), this::assertInitNotAuth) + .login(this::assertOnLoginPage) + .loginForm(testUser, (driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1)) // I am not sure why is this driver1 argument to isCurrent necessary, but I got exception without it - ); + ); - oAuthGrantPage.accept(); + oAuthGrantPage.accept(); - EventRepresentation loginEvent = events.expectLogin() - .client(CLIENT_ID) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .detail(Details.REDIRECT_URI, testAppUrl) - .detail(Details.USERNAME, testUser.getUsername()) - .assertEvent(); - String codeId = loginEvent.getDetails().get(Details.CODE_ID); + EventRepresentation loginEvent = events.expectLogin() + .client(CLIENT_ID) + .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) + .detail(Details.REDIRECT_URI, testAppUrl) + .detail(Details.USERNAME, testUser.getUsername()) + .assertEvent(); + String codeId = loginEvent.getDetails().get(Details.CODE_ID); - testExecutor.init(defaultArguments(), this::assertSuccessfullyLoggedIn); + testExecutor.init(defaultArguments(), this::assertSuccessfullyLoggedIn); - applicationsPage.navigateTo(); - events.expectCodeToToken(codeId, loginEvent.getSessionId()).client(CLIENT_ID).assertEvent(); + applicationsPage.navigateTo(); + events.expectCodeToToken(codeId, loginEvent.getSessionId()).client(CLIENT_ID).assertEvent(); - applicationsPage.revokeGrantForApplication(CLIENT_ID); - events.expect(EventType.REVOKE_GRANT) - .client("account") - .detail(Details.REVOKED_CLIENT, CLIENT_ID) - .assertEvent(); + applicationsPage.revokeGrantForApplication(CLIENT_ID); + events.expect(EventType.REVOKE_GRANT) + .client("account") + .detail(Details.REVOKED_CLIENT, CLIENT_ID) + .assertEvent(); - jsDriver.navigate().to(testAppUrl); - testExecutor.configure() // need to configure because we refreshed page - .init(defaultArguments(), this::assertInitNotAuth) - .login((driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1))); - - // Clean - client.setConsentRequired(false); - clientResource.update(client); + jsDriver.navigate().to(testAppUrl); + testExecutor.configure() // need to configure because we refreshed page + .init(defaultArguments(), this::assertInitNotAuth) + .login((driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1))); + } finally { + // Clean + client.setConsentRequired(false); + clientResource.update(client); + } } @Test @@ -268,18 +274,20 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { public void implicitFlowOnTokenExpireTest() { RealmRepresentation realm = adminClient.realms().realm(REALM_NAME).toRepresentation(); Integer storeAccesTokenLifespan = realm.getAccessTokenLifespanForImplicitFlow(); - realm.setAccessTokenLifespanForImplicitFlow(5); - adminClient.realms().realm(REALM_NAME).update(realm); + try { + realm.setAccessTokenLifespanForImplicitFlow(5); + adminClient.realms().realm(REALM_NAME).update(realm); - setImplicitFlowForClient(); - testExecutor.logInAndInit(defaultArguments().implicitFlow(), testUser, this::assertSuccessfullyLoggedIn) - .addTimeSkew(-5); // Move in time instead of wait + setImplicitFlowForClient(); + testExecutor.logInAndInit(defaultArguments().implicitFlow(), testUser, this::assertSuccessfullyLoggedIn) + .addTimeSkew(-5); // Move in time instead of wait - waitUntilElement(eventsArea).text().contains("Access token expired"); - - // Get to origin state - realm.setAccessTokenLifespanForImplicitFlow(storeAccesTokenLifespan); - adminClient.realms().realm(REALM_NAME).update(realm); + waitUntilElement(eventsArea).text().contains("Access token expired"); + } finally { + // Get to origin state + realm.setAccessTokenLifespanForImplicitFlow(storeAccesTokenLifespan); + adminClient.realms().realm(REALM_NAME).update(realm); + } } @Test @@ -350,8 +358,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { .sendXMLHttpRequest(request, assertResponseStatus(401)) .refreshToken(5, assertEventsContains("Auth Refresh Success")) .sendXMLHttpRequest(request, assertResponseStatus(200)); - - setTimeOffset(0); } @Test @@ -418,27 +424,28 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { // it looks like phantomjs double encode %20 => %25%20 Assume.assumeTrue("This test doesn't work with phantomjs", !"phantomjs".equals(System.getProperty("js.browser"))); - adminClient.realm(REALM_NAME).update(RealmBuilder.edit(adminClient.realm(REALM_NAME).toRepresentation()).name(SPACE_REALM_NAME).build()); + try { + adminClient.realm(REALM_NAME).update(RealmBuilder.edit(adminClient.realm(REALM_NAME).toRepresentation()).name(SPACE_REALM_NAME).build()); - JSObjectBuilder configuration = JSObjectBuilder.create() - .add("url", authServerContextRootPage + "/auth") - .add("realm", SPACE_REALM_NAME) - .add("clientId", CLIENT_ID); + JSObjectBuilder configuration = JSObjectBuilder.create() + .add("url", authServerContextRootPage + "/auth") + .add("realm", SPACE_REALM_NAME) + .add("clientId", CLIENT_ID); - testAppUrl = authServerContextRootPage + JAVASCRIPT_ENCODED_SPACE_URL + "/index.html"; - jsDriver.navigate().to(testAppUrl); - jsDriverTestRealmLoginPage.setAuthRealm(SPACE_REALM_NAME); + testAppUrl = authServerContextRootPage + JAVASCRIPT_ENCODED_SPACE_URL + "/index.html"; + jsDriver.navigate().to(testAppUrl); + jsDriverTestRealmLoginPage.setAuthRealm(SPACE_REALM_NAME); - testExecutor.configure(configuration) - .init(defaultArguments(), this::assertInitNotAuth) - .login(this::assertOnLoginPage) - .loginForm(testUser, this::assertOnTestAppUrl) - .configure(configuration) - .init(defaultArguments(), this::assertSuccessfullyLoggedIn); - - // Clean - adminClient.realm(SPACE_REALM_NAME).update(RealmBuilder.edit(adminClient.realm(SPACE_REALM_NAME).toRepresentation()).name(REALM_NAME).build()); - jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME); + testExecutor.configure(configuration) + .init(defaultArguments(), this::assertInitNotAuth) + .login(this::assertOnLoginPage) + .loginForm(testUser, this::assertOnTestAppUrl) + .configure(configuration) + .init(defaultArguments(), this::assertSuccessfullyLoggedIn); + } finally { + adminClient.realm(SPACE_REALM_NAME).update(RealmBuilder.edit(adminClient.realm(SPACE_REALM_NAME).toRepresentation()).name(REALM_NAME).build()); + jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME); + } } @Test @@ -460,9 +467,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { .add("refreshToken", refreshToken) , this::assertSuccessfullyLoggedIn) .refreshToken(9999, assertEventsContains("Auth Refresh Success")); - - - oauth.setDriver(driver); } @Test @@ -496,15 +500,12 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { both(greaterThan(-600L - TIME_SKEW_TOLERANCE)) .and(lessThan(-600L + TIME_SKEW_TOLERANCE)) ))); - - setTimeOffset(0); - - oauth.setDriver(driver); // Clean } @Test // KEYCLOAK-4503 public void initializeWithRefreshToken() { + oauth.setDriver(jsDriver); // Oauth need to login with jsDriver oauth.realm(REALM_NAME); @@ -523,8 +524,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest { assertInitNotAuth(driver1, output, events); waitUntilElement(events).text().not().contains("Auth Success"); }); - - oauth.setDriver(driver); // Clean } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SecuredDeploymentsAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SecuredDeploymentsAdapterTest.java index 00d9d1770c..a733c355ec 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SecuredDeploymentsAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SecuredDeploymentsAdapterTest.java @@ -31,7 +31,9 @@ import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.After; +import org.junit.Assume; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; @@ -74,6 +76,11 @@ public class SecuredDeploymentsAdapterTest extends AbstractServletsAdapterTest i return servletDeployment(CustomerDb.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class); } + @BeforeClass + public static void assumeTLSEnabled() { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); + } + @Before @Override public void startServer() { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java index 557177be21..7ab95805a4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/CrossRealmPermissionsTest.java @@ -27,6 +27,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.UserBuilder; @@ -61,7 +62,7 @@ public class CrossRealmPermissionsTest extends AbstractKeycloakTest { .addPassword("password")); testRealms.add(builder.build()); - realm1 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret").realm(REALM_NAME); + realm1 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret", TLSUtils.initializeTLS()).realm(REALM_NAME); builder = RealmBuilder.create().name(REALM2_NAME).testMail(); builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); @@ -73,7 +74,7 @@ public class CrossRealmPermissionsTest extends AbstractKeycloakTest { testRealms.add(builder.build()); - realm2 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM2_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret").realm(REALM2_NAME); + realm2 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM2_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret", TLSUtils.initializeTLS()).realm(REALM2_NAME); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java index ec48d451f2..29f912881d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/FineGrainAdminUnitTest.java @@ -48,6 +48,7 @@ import org.keycloak.services.resources.admin.permissions.GroupPermissionManageme import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.runonserver.RunOnServerDeployment; import org.keycloak.testsuite.util.AdminClientUtil; @@ -893,7 +894,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest { Assert.assertNotNull(exchanged); Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, exchanged); + AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, exchanged, TLSUtils.initializeTLS()); Assert.assertNotNull(client.realm("master").roles().get("offline_access")); } @@ -949,7 +950,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest { }); Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - "test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID); + "test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()); List result = client.realm("test").users().search(null, "test", null, null, -1, 20); @@ -961,7 +962,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest { Assert.assertEquals(0, result.size()); client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - "test", "regular-admin-user", "password", Constants.ADMIN_CLI_CLIENT_ID); + "test", "regular-admin-user", "password", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()); result = client.realm("test").users().search(null, "test", null, null, -1, 20); @@ -974,7 +975,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest { Assert.assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("a")))); client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - "test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID); + "test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()); result = client.realm("test").users().search(null, null, null, null, -1, 20); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java index 3db47535a8..e27a7683ac 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java @@ -638,7 +638,7 @@ public class IdentityProviderTest extends AbstractAdminTest { Assert.assertEquals("Parsed export type", EntityDescriptorType.class, entBody.getClass()); EntityDescriptorType entity = (EntityDescriptorType) entBody; - Assert.assertEquals("EntityID", "http://localhost:8180/auth/realms/admin-client-test", entity.getEntityID()); + Assert.assertEquals("EntityID", oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test", entity.getEntityID()); Assert.assertNotNull("ChoiceType not null", entity.getChoiceType()); Assert.assertEquals("ChoiceType.size", 1, entity.getChoiceType().size()); @@ -667,7 +667,7 @@ public class IdentityProviderTest extends AbstractAdminTest { IndexedEndpointType endpoint = desc.getAssertionConsumerService().get(0); Assert.assertEquals("AssertionConsumerService.Location", - new URI("http://localhost:8180/auth/realms/admin-client-test/broker/saml/endpoint"), endpoint.getLocation()); + new URI(oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test/broker/saml/endpoint"), endpoint.getLocation()); Assert.assertEquals("AssertionConsumerService.Binding", new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), endpoint.getBinding()); Assert.assertTrue("AssertionConsumerService.isDefault", endpoint.isIsDefault()); @@ -679,7 +679,7 @@ public class IdentityProviderTest extends AbstractAdminTest { EndpointType sloEndpoint = desc.getSingleLogoutService().get(0); Assert.assertEquals("SingleLogoutService.Location", - new URI("http://localhost:8180/auth/realms/admin-client-test/broker/saml/endpoint"), sloEndpoint.getLocation()); + new URI(oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test/broker/saml/endpoint"), sloEndpoint.getLocation()); Assert.assertEquals("SingleLogoutService.Binding", new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), sloEndpoint.getBinding()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java index a086208ed9..1454746de0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java @@ -57,6 +57,7 @@ import org.keycloak.services.resources.admin.AdminAuth.Resource; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.util.AdminClientUtil; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.CredentialBuilder; @@ -194,31 +195,31 @@ public class PermissionsTest extends AbstractKeycloakTest { clients.put(AdminRoles.REALM_ADMIN, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", - "secret")); + "secret", TLSUtils.initializeTLS())); clients.put("none", - Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "none", "password", "test-client", "secret")); + Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "none", "password", "test-client", "secret", TLSUtils.initializeTLS())); clients.put("multi", - Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "multi", "password", "test-client", "secret")); + Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "multi", "password", "test-client", "secret", TLSUtils.initializeTLS())); for (String role : AdminRoles.ALL_REALM_ROLES) { - clients.put(role, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, role, "password", "test-client")); + clients.put(role, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, role, "password", "test-client", TLSUtils.initializeTLS())); } - clients.put("REALM2", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "realm2", "admin", "password", "test-client")); + clients.put("REALM2", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "realm2", "admin", "password", "test-client", TLSUtils.initializeTLS())); clients.put("master-admin", adminClient); clients.put("master-none", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-none", "password", - Constants.ADMIN_CLI_CLIENT_ID)); + Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())); for (String role : AdminRoles.ALL_REALM_ROLES) { clients.put("master-" + role, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-" + role, "password", - Constants.ADMIN_CLI_CLIENT_ID)); + Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTotpTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTotpTest.java index f2448e1df5..1fffa50fd7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTotpTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTotpTest.java @@ -44,9 +44,6 @@ import java.util.List; */ public class UserTotpTest extends AbstractTestRealmKeycloakTest { - private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth"); - public static String ACCOUNT_REDIRECT = AccountFormService.loginRedirectUrl(BASE.clone()).build("test").toString(); - @Rule public AssertEvents events = new AssertEvents(this); @@ -71,7 +68,7 @@ public class UserTotpTest extends AbstractTestRealmKeycloakTest { totpPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=totp").assertEvent(); Assert.assertTrue(totpPage.isCurrent()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerClaimsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerClaimsTest.java index d232c441d4..0c2267ed9d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerClaimsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerClaimsTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; @@ -102,7 +103,7 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { .directAccessGrants()) .client(ClientBuilder.create().clientId("public-client-test") .publicClient() - .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*") .directAccessGrants()) .build()); } @@ -347,7 +348,11 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest { } private InputStream getAdapterConfiguration(String fileName) { - return getClass().getResourceAsStream("/authorization-test/" + fileName); + try { + return httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + fileName)); + } catch (IOException e) { + throw new AssertionError("Could not load keycloak configuration", e); + } } private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java index 239663aad1..a4fae18647 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java @@ -26,6 +26,7 @@ import javax.ws.rs.HttpMethod; import javax.ws.rs.core.HttpHeaders; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; @@ -73,7 +74,6 @@ import org.keycloak.representations.idm.authorization.RolePolicyRepresentation; import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation; import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; @@ -116,7 +116,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { .directAccessGrants()) .client(ClientBuilder.create().clientId("public-client-test") .publicClient() - .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*") .directAccessGrants()) .build()); } @@ -486,7 +486,11 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest { } private InputStream getAdapterConfiguration(String fileName) { - return getClass().getResourceAsStream("/authorization-test/" + fileName); + try { + return httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + fileName)); + } catch (IOException e) { + throw new AssertionError("Unexpected I/O error while dealing with configuration", e); + } } private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/AbstractConcurrencyTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/AbstractConcurrencyTest.java index 5cd0110994..e115777bad 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/AbstractConcurrencyTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/AbstractConcurrencyTest.java @@ -23,6 +23,8 @@ import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; + import java.util.LinkedList; import java.util.Collection; import java.util.List; @@ -68,7 +70,7 @@ public abstract class AbstractConcurrencyTest extends AbstractTestRealmKeycloakT ThreadLocal keycloaks = new ThreadLocal() { @Override protected Keycloak initialValue() { - return Keycloak.getInstance(testImpl.getAuthServerRoot().toString(), "master", "admin", "admin", org.keycloak.models.Constants.ADMIN_CLI_CLIENT_ID); + return Keycloak.getInstance(testImpl.getAuthServerRoot().toString(), "master", "admin", "admin", org.keycloak.models.Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()); } }; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/ConcurrentLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/ConcurrentLoginTest.java index 4a5aadaa7b..3ac00cf244 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/ConcurrentLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/concurrency/ConcurrentLoginTest.java @@ -24,6 +24,9 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Map; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; import javax.ws.rs.core.Response; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; @@ -33,11 +36,13 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.LaxRedirectStrategy; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; +import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jsoup.Jsoup; import org.jsoup.nodes.Element; import org.junit.Assert; @@ -89,8 +94,8 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest { ClientRepresentation client = ClientBuilder.create() .clientId("client" + i) .directAccessGrants() - .redirectUris("http://localhost:8180/auth/realms/master/app/*") - .addWebOrigin("http://localhost:8180") + .redirectUris("*") + .addWebOrigin("*") .secret("password") .build(); @@ -111,7 +116,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest { AtomicReference userSessionId = new AtomicReference<>(); LoginTask loginTask = null; - try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) { + try (CloseableHttpClient httpClient = getHttpsAwareClient()) { loginTask = new LoginTask(httpClient, userSessionId, 100, 1, false, Arrays.asList( createHttpClientContextForUser(httpClient, "test-user@localhost", "password") )); @@ -126,6 +131,15 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest { } } + protected CloseableHttpClient getHttpsAwareClient() { + HttpClientBuilder builder = HttpClientBuilder.create() + .setRedirectStrategy(new LaxRedirectStrategy()); + if (AUTH_SERVER_SSL_REQUIRED) { + builder.setSSLHostnameVerifier((s, sslSession) -> true); + } + return builder.build(); + } + protected HttpClientContext createHttpClientContextForUser(final CloseableHttpClient httpClient, String userName, String password) throws IOException { final HttpClientContext context = HttpClientContext.create(); CookieStore cookieStore = new BasicCookieStore(); @@ -143,7 +157,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest { AtomicReference userSessionId = new AtomicReference<>(); LoginTask loginTask = null; - try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) { + try (CloseableHttpClient httpClient = getHttpsAwareClient()) { loginTask = new LoginTask(httpClient, userSessionId, 100, 1, true, Arrays.asList( createHttpClientContextForUser(httpClient, "test-user@localhost", "password") )); @@ -166,7 +180,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest { AtomicReference userSessionId = new AtomicReference<>(); LoginTask loginTask = null; - try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) { + try (CloseableHttpClient httpClient = getHttpsAwareClient()) { loginTask = new LoginTask(httpClient, userSessionId, 100, 1, false, Arrays.asList( createHttpClientContextForUser(httpClient, "test-user@localhost", "password"), createHttpClientContextForUser(httpClient, "john-doh@localhost", "password"), diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java index f08dea8059..c1644ee972 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java @@ -34,6 +34,7 @@ import org.keycloak.testsuite.AbstractAuthTest; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.AssertAdminEvents; import org.keycloak.testsuite.util.ClientBuilder; @@ -128,7 +129,7 @@ public class AdminEventAuthDetailsTest extends AbstractAuthTest { private void testClient(String realmName, String username, String password, String clientId, String expectedRealmId, String expectedClientUuid, String expectedUserId) { try (Keycloak keycloak = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - realmName, username, password, clientId)) { + realmName, username, password, clientId, TLSUtils.initializeTLS())) { UserRepresentation rep = UserBuilder.create().id(appUserId).username("app-user").email("foo@email.org").build(); keycloak.realm("test").users().get(appUserId).update(rep); 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 a74903bb06..800b778132 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 @@ -36,6 +36,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.RoleBuilder; @@ -540,7 +541,7 @@ public class GroupTest extends AbstractGroupTest { createUser(realmName, userName, "pwd"); try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID)) { + realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) { expectedException.expect(ClientErrorException.class); expectedException.expectMessage(String.valueOf(Response.Status.FORBIDDEN.getStatusCode())); @@ -569,7 +570,7 @@ public class GroupTest extends AbstractGroupTest { mappings.realmLevel().add(Collections.singletonList(adminRole)); Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID); + realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()); assertThat(userClient.realms().findAll(), // Any admin operation will do not(empty())); @@ -601,7 +602,7 @@ public class GroupTest extends AbstractGroupTest { realm.users().get(userId).joinGroup(groupId); } try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID)) { + realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) { assertThat(userClient.realms().findAll(), // Any admin operation will do not(empty())); @@ -636,7 +637,7 @@ public class GroupTest extends AbstractGroupTest { mappings.realmLevel().add(Collections.singletonList(adminRole)); } try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID)) { + realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) { assertThat(userClient.realms().findAll(), // Any admin operation will do not(empty())); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java index b441591343..a15f87cb63 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java @@ -48,6 +48,7 @@ import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AbstractAdminTest; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.runonserver.RunOnServerDeployment; @@ -271,7 +272,7 @@ public class RealmTest extends AbstractAdminTest { public void loginAfterRemoveRealm() { realm.remove(); - try (Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID)) { + try (Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) { client.serverInfo().getInfo(); } @@ -662,7 +663,7 @@ public class RealmTest extends AbstractAdminTest { GlobalRequestResult globalRequestResult = realm.pushRevocation(); assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM); - assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/app/admin")); + assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder(oauth.AUTH_SERVER_ROOT + "/realms/master/app/admin")); assertNull(globalRequestResult.getFailedRequests()); PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore(); @@ -684,8 +685,8 @@ public class RealmTest extends AbstractAdminTest { GlobalRequestResult globalRequestResult = realm.pushRevocation(); assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM); - assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/app/admin")); - assertThat(globalRequestResult.getFailedRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/saml-app/saml")); + assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder(oauth.AUTH_SERVER_ROOT + "/realms/master/app/admin")); + assertThat(globalRequestResult.getFailedRequests(), Matchers.containsInAnyOrder(oauth.AUTH_SERVER_ROOT + "/realms/master/saml-app/saml")); PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore(); assertEquals(time, adminPushNotBefore.getNotBefore()); @@ -709,7 +710,7 @@ public class RealmTest extends AbstractAdminTest { assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all", globalRequestResult, ResourceType.REALM); assertEquals(1, globalRequestResult.getSuccessRequests().size()); - assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0)); + assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0)); assertNull(globalRequestResult.getFailedRequests()); assertNotNull(testingClient.testApp().getAdminLogoutAction()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java index a8e33a6474..6141fbcc05 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AbstractResourceServerTest.java @@ -75,7 +75,7 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest { .directAccessGrants() .serviceAccountsEnabled(true)) .client(ClientBuilder.create().clientId("test-app") - .redirectUris("http://localhost:8180/auth/realms/master/app/auth") + .redirectUris("http://localhost:8180/auth/realms/master/app/auth", "https://localhost:8543/auth/realms/master/app/auth") .publicClient()) .build()); } @@ -165,7 +165,11 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest { } protected AuthzClient getAuthzClient() { - return AuthzClient.create(getClass().getResourceAsStream("/authorization-test/default-keycloak-uma2.json")); + try { + return AuthzClient.create(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/default-keycloak-uma2.json"))); + } catch (IOException cause) { + throw new RuntimeException("Failed to create authz client", cause); + } } protected void assertPermissions(Collection permissions, String expectedResource, String... expectedScopes) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java index 5a80c24fa0..e451e7c171 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/AuthorizationAPITest.java @@ -19,6 +19,7 @@ package org.keycloak.testsuite.authz; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import java.io.IOException; import java.util.List; import javax.ws.rs.core.Response; @@ -208,6 +209,10 @@ public class AuthorizationAPITest extends AbstractAuthzTest { } private AuthzClient getAuthzClient(String configFile) { - return AuthzClient.create(getClass().getResourceAsStream("/authorization-test/" + configFile)); + try { + return AuthzClient.create(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + configFile))); + } catch (IOException cause) { + throw new RuntimeException("Failed to create authz client", cause); + } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java index 2b984c183a..13a0922941 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/EntitlementAPITest.java @@ -142,7 +142,7 @@ public class EntitlementAPITest extends AbstractAuthzTest { .directAccessGrants()) .client(ClientBuilder.create().clientId(PUBLIC_TEST_CLIENT) .secret("secret") - .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*") .publicClient()) .build()); } @@ -1374,7 +1374,7 @@ public class EntitlementAPITest extends AbstractAuthzTest { if (authzClient == null) { Configuration configuration; try { - configuration = JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/" + configFile), Configuration.class); + configuration = JsonSerialization.readValue(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + configFile)), Configuration.class); } catch (IOException e) { throw new RuntimeException("Failed to read configuration", e); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java index 1a43d2eff8..5b21bb5911 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/PermissionClaimTest.java @@ -451,6 +451,10 @@ public class PermissionClaimTest extends AbstractAuthzTest { } private AuthzClient getAuthzClient() { - return AuthzClient.create(getClass().getResourceAsStream("/authorization-test/default-keycloak.json")); + try { + return AuthzClient.create(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/default-keycloak.json"))); + } catch (IOException cause) { + throw new RuntimeException("Failed to create authz client", cause); + } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java index 25877d48e5..05f5d6d92c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerConfiguration.java @@ -153,7 +153,8 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration { .fullScopeEnabled(true) .protocol(SamlProtocol.LOGIN_PROTOCOL) .baseUrl("http://localhost:8080/sales-post") - .addRedirectUri("http://localhost:8080/sales-post/*") + .addRedirectUri("http://localhost:8180/sales-post/*") + .addRedirectUri("https://localhost:8543/sales-post/*") .attribute(SamlConfigAttributes.SAML_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE) .attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE) .build(), @@ -163,7 +164,8 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration { .fullScopeEnabled(true) .protocol(SamlProtocol.LOGIN_PROTOCOL) .baseUrl("http://localhost:8080/sales-post") - .addRedirectUri("http://localhost:8080/sales-post/*") + .addRedirectUri("http://localhost:8180/sales-post/*") + .addRedirectUri("https://localhost:8543/sales-post/*") .attribute(SamlConfigAttributes.SAML_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE) .attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE) .build(), diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java index 3766f4a13a..04328572e8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlBrokerTest.java @@ -138,7 +138,7 @@ public class KcSamlBrokerTest extends AbstractBrokerTest { // KEYCLOAK-6106 @Test public void loginClientWithDotsInName() throws Exception { - AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST + ".dot/ted", AbstractSamlTest.SAML_ASSERTION_CONSUMER_URL_SALES_POST, null); + AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST + ".dot/ted", AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT + "/sales-post/saml", null); Document doc = SAML2Request.convert(loginRep); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java index b8e7d24001..56ba994448 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlSignedBrokerTest.java @@ -1,6 +1,5 @@ package org.keycloak.testsuite.broker; -import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.broker.saml.SAMLIdentityProviderConfig; import org.keycloak.crypto.Algorithm; import org.keycloak.dom.saml.v2.protocol.AuthnRequestType; @@ -210,7 +209,7 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest { // KEYCLOAK-5581 @Test public void loginUserAllNamespacesInTopElement() { - AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST, AbstractSamlTest.SAML_ASSERTION_CONSUMER_URL_SALES_POST, null); + AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST, AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT + "/sales-post/saml", null); Document doc; try { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/AbstractCliTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/AbstractCliTest.java index 8df18ae021..73fedaf944 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/AbstractCliTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/AbstractCliTest.java @@ -1,9 +1,11 @@ package org.keycloak.testsuite.cli; import org.junit.Assert; +import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.cli.exec.AbstractExec; +import java.io.File; import java.util.List; /** @@ -11,6 +13,23 @@ import java.util.List; */ public abstract class AbstractCliTest extends AbstractKeycloakTest { + protected String serverUrl = "http://localhost:" + getAuthServerHttpPort() + "/auth"; + + static int getAuthServerHttpPort() { + try { + return Integer.valueOf(System.getProperty("auth.server.http.port")); + } catch (Exception e) { + throw new RuntimeException("System property 'auth.server.http.port' not set or invalid: '" + + System.getProperty("auth.server.http.port") + "'"); + } + } + + @Override + public void addTestRealms(List testRealms) { + for (RealmRepresentation tr : testRealms) { + tr.setSslRequired("external"); + } + } public void assertExitCodeAndStdOutSize(AbstractExec exe, int exitCode, int stdOutLineCount) { assertExitCodeAndStreamSizes(exe, exitCode, stdOutLineCount, -1); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java index a8be4252dc..994614072f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java @@ -17,6 +17,13 @@ package org.keycloak.testsuite.cli; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.mail.internet.MimeMessage; + import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.graphene.page.Page; import org.jboss.shrinkwrap.api.spec.WebArchive; @@ -26,17 +33,22 @@ import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; import org.keycloak.admin.client.resource.UserResource; -import org.keycloak.authentication.RequiredActionProvider; -import org.keycloak.authentication.authenticators.console.ConsoleUsernamePasswordAuthenticatorFactory; import org.keycloak.authentication.requiredactions.TermsAndConditions; import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.common.Profile; import org.keycloak.credential.CredentialModel; -import org.keycloak.models.*; +import org.keycloak.models.AuthenticationExecutionModel; +import org.keycloak.models.AuthenticationFlowBindings; +import org.keycloak.models.AuthenticationFlowModel; +import org.keycloak.models.ClientModel; +import org.keycloak.models.PasswordPolicy; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RequiredActionProviderModel; +import org.keycloak.models.UserCredentialModel; +import org.keycloak.models.UserModel; import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.models.utils.TimeBasedOTP; -import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation; @@ -46,28 +58,14 @@ import org.keycloak.services.resources.admin.permissions.AdminPermissions; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.actions.DummyRequiredActionFactory; -import org.keycloak.testsuite.authentication.PushButtonAuthenticator; import org.keycloak.testsuite.authentication.PushButtonAuthenticatorFactory; -import org.keycloak.testsuite.forms.PassThroughAuthenticator; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.ErrorPage; import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.runonserver.RunOnServerDeployment; import org.keycloak.testsuite.util.GreenMailRule; import org.keycloak.testsuite.util.MailUtils; -import org.keycloak.testsuite.util.OAuthClient; -import org.keycloak.util.JsonSerialization; import org.keycloak.utils.TotpUtils; import org.openqa.selenium.By; -import javax.mail.internet.MimeMessage; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * Test that clients can override auth flows * @@ -111,7 +109,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest { ClientModel kcinit = realm.addClient(KCINIT_CLIENT); kcinit.setEnabled(true); - kcinit.addRedirectUri("http://localhost:*"); + kcinit.addRedirectUri("*"); kcinit.setPublicClient(true); kcinit.removeRole(realm.getRole(OAuth2Constants.OFFLINE_ACCESS)); @@ -239,7 +237,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest { .executeAsync(); exe.waitForStderr("Open browser and continue login? [y/n]"); exe.sendLine("y"); - exe.waitForStdout("http://"); + exe.waitForStdout("http"); // the --fake-browser skips launching a browser and outputs url to stdout String redirect = exe.stdoutString().trim(); @@ -312,7 +310,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest { exe.waitForStderr("Open browser and continue login? [y/n]"); exe.sendLine("y"); - exe.waitForStdout("http://"); + exe.waitForStdout("http"); // the --fake-browser skips launching a browser and outputs url to stdout String redirect = exe.stdoutString().trim(); @@ -348,7 +346,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest { //exe.waitForStderr("(y/n):"); //exe.sendLine("n"); exe.waitForStderr("Authentication server URL [http://localhost:8080/auth]:"); - exe.sendLine(OAuthClient.AUTH_SERVER_ROOT); + exe.sendLine(oauth.AUTH_SERVER_ROOT); //System.out.println(exe.stderrString()); exe.waitForStderr("Name of realm [master]:"); exe.sendLine("test"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/AbstractAdmCliTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/AbstractAdmCliTest.java index f7d15c4b9c..930643c211 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/AbstractAdmCliTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/AbstractAdmCliTest.java @@ -11,6 +11,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.cli.AbstractCliTest; import org.keycloak.testsuite.cli.KcAdmExec; +import org.keycloak.testsuite.cli.KcRegExec; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.util.JsonSerialization; @@ -37,40 +38,14 @@ import static org.keycloak.testsuite.cli.KcAdmExec.execute; */ public abstract class AbstractAdmCliTest extends AbstractCliTest { - protected String serverUrl = isAuthServerSSL() ? - "https://localhost:" + getAuthServerHttpsPort() + "/auth" : - "http://localhost:" + getAuthServerHttpPort() + "/auth"; - static boolean runIntermittentlyFailingTests() { return "true".equals(System.getProperty("test.intermittent")); } - static boolean isAuthServerSSL() { - return "true".equals(System.getProperty("auth.server.ssl.required")); - } - static File getDefaultConfigFilePath() { return new File(System.getProperty("user.home") + "/.keycloak/kcadm.config"); } - static int getAuthServerHttpsPort() { - try { - return Integer.valueOf(System.getProperty("auth.server.https.port")); - } catch (Exception e) { - throw new RuntimeException("System property 'auth.server.https.port' not set or invalid: '" - + System.getProperty("auth.server.https.port") + "'"); - } - } - - static int getAuthServerHttpPort() { - try { - return Integer.valueOf(System.getProperty("auth.server.http.port")); - } catch (Exception e) { - throw new RuntimeException("System property 'auth.server.http.port' not set or invalid: '" - + System.getProperty("auth.server.http.port") + "'"); - } - } - @Override public void addTestRealms(List testRealms) { @@ -320,7 +295,7 @@ public abstract class AbstractAdmCliTest extends AbstractCliTest { exe = execute("delete clients/" + client.getId() + " --no-config --server " + serverUrl + " --realm test " + credentials + " " + extraOptions); - int linecountOffset = loginMessage.equals("") ? 1 : 0; // if there is no login, then there is one less stdErrLinecount + int linecountOffset = "".equals(loginMessage) ? 1 : 0; // if there is no login, then there is one less stdErrLinecount assertExitCodeAndStreamSizes(exe, 0, 0, 1 - linecountOffset); lastModified2 = configFile.exists() ? configFile.lastModified() : 0; @@ -376,13 +351,7 @@ public abstract class AbstractAdmCliTest extends AbstractCliTest { KcAdmExec exe = KcAdmExec.execute("config credentials --server " + server + " --realm " + realm + " --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath()); - Assert.assertEquals("exitCode == 0", 0, exe.exitCode()); - - List lines = exe.stdoutLines(); - Assert.assertTrue("stdout output empty", lines.size() == 0); - - lines = exe.stderrLines(); - Assert.assertTrue("stderr output one line", lines.size() == 1); - Assert.assertEquals("stderr first line", "Logging into " + server + " as user " + user + " of realm " + realm, lines.get(0)); + assertExitCodeAndStreamSizes(exe, 0, 0, 1); } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTest.java index 9c586004f0..651d1f1ce7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTest.java @@ -577,6 +577,8 @@ public class KcAdmTest extends AbstractAdmCliTest { * Test create, get, update, and delete using on-the-fly authentication - without using any config file. * Login is performed by each operation again, and again using username, password, and client secret. */ + //non-TLS endpoint + oauth.baseUrl(serverUrl); oauth.realm("master"); oauth.clientId("admin-cli"); String token = oauth.doGrantAccessTokenRequest("", "admin", "admin").getAccessToken(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTruststoreTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTruststoreTest.java index 9ab712836a..877d657cb7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTruststoreTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmTruststoreTest.java @@ -33,7 +33,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest { Assert.assertEquals("try help", "Try '" + OsUtil.CMD + " help config truststore' for more information", exe.stderrLines().get(1)); // only run this test if ssl protected keycloak server is available - if (!isAuthServerSSL()) { + if (!AUTH_SERVER_SSL_REQUIRED) { System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'"); return; } @@ -51,7 +51,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest { // perform authentication against server - asks for password, then for truststore password exe = KcAdmExec.newBuilder() - .argsLine("config credentials --server " + serverUrl + " --realm test --user user1" + + .argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" + " --config '" + configFile.getName() + "'") .executeAsync(); @@ -71,7 +71,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest { // perform authentication against server - asks for password, then for truststore password exe = KcAdmExec.newBuilder() - .argsLine("config credentials --server " + serverUrl + " --realm test --user user1" + + .argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" + " --config '" + configFile.getName() + "'") .executeAsync(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractRegCliTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractRegCliTest.java index e171ccafe0..91120037ed 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractRegCliTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractRegCliTest.java @@ -2,6 +2,7 @@ package org.keycloak.testsuite.cli.registration; import org.junit.Assert; import org.junit.Before; +import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.resource.ClientInitialAccessResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator; @@ -47,11 +48,6 @@ import static org.keycloak.testsuite.cli.KcRegExec.execute; */ public abstract class AbstractRegCliTest extends AbstractCliTest { - protected String serverUrl = isAuthServerSSL() ? - "https://localhost:" + getAuthServerHttpsPort() + "/auth" : - "http://localhost:" + getAuthServerHttpPort() + "/auth"; - - @Before public void deleteDefaultConfig() { getDefaultConfigFilePath().delete(); @@ -61,33 +57,10 @@ public abstract class AbstractRegCliTest extends AbstractCliTest { return "true".equals(System.getProperty("test.intermittent")); } - static boolean isAuthServerSSL() { - return "true".equals(System.getProperty("auth.server.ssl.required")); - } - - static int getAuthServerHttpsPort() { - try { - return Integer.valueOf(System.getProperty("auth.server.https.port")); - } catch (Exception e) { - throw new RuntimeException("System property 'auth.server.https.port' not set or invalid: '" - + System.getProperty("auth.server.https.port") + "'"); - } - } - - static int getAuthServerHttpPort() { - try { - return Integer.valueOf(System.getProperty("auth.server.http.port")); - } catch (Exception e) { - throw new RuntimeException("System property 'auth.server.http.port' not set or invalid: '" - + System.getProperty("auth.server.http.port") + "'"); - } - } - static File getDefaultConfigFilePath() { return new File(System.getProperty("user.home") + "/.keycloak/kcreg.config"); } - @Override public void addTestRealms(List testRealms) { RealmRepresentation realmRepresentation = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); @@ -159,23 +132,13 @@ public abstract class AbstractRegCliTest extends AbstractCliTest { .build(); realmRepresentation.getClients().add(regClient); - } - void loginAsUser(File configFile, String server, String realm, String user, String password) { - KcRegExec exe = execute("config credentials --server " + server + " --realm " + realm + " --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath()); - Assert.assertEquals("exitCode == 0", 0, exe.exitCode()); - - List lines = exe.stdoutLines(); - Assert.assertTrue("stdout output empty", lines.size() == 0); - - lines = exe.stderrLines(); - Assert.assertTrue("stderr output one line", lines.size() == 1); - Assert.assertEquals("stderr first line", "Logging into " + server + " as user " + user + " of realm " + realm, lines.get(0)); + assertExitCodeAndStreamSizes(exe, 0, 0, 1); } void assertFieldsEqualWithExclusions(ConfigData config1, ConfigData config2, String ... excluded) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java index fa5a1dfcfb..c2ef8517ef 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegCreateTest.java @@ -2,6 +2,8 @@ package org.keycloak.testsuite.cli.registration; import org.hamcrest.Matchers; import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; import org.junit.Test; import org.keycloak.OAuth2Constants; import org.keycloak.admin.client.resource.ClientResource; @@ -32,6 +34,11 @@ import static org.keycloak.testsuite.cli.KcRegExec.execute; */ public class KcRegCreateTest extends AbstractRegCliTest { + @Before + public void assumeTLSEnabled() { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); + } + @Test public void testCreateWithRealmOverride() throws IOException { @@ -41,15 +48,15 @@ public class KcRegCreateTest extends AbstractRegCliTest { // authenticate as a regular user against one realm KcRegExec exe = execute("config credentials -x --config '" + configFile.getName() + - "' --server " + serverUrl + " --realm master --user admin --password admin"); + "' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm master --user admin --password admin"); - assertExitCodeAndStreamSizes(exe, 0, 0, 1); + assertExitCodeAndStreamSizes(exe, 0, 0, 3); // use initial token of another realm with server, and realm override String token = issueInitialAccessToken("test"); - exe = execute("create --config '" + configFile.getName() + "' --server " + serverUrl + " --realm test -s clientId=my_first_client -t " + token); + exe = execute("create --config '" + configFile.getName() + "' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm test -s clientId=my_first_client -t " + token); - assertExitCodeAndStreamSizes(exe, 0, 0, 1); + assertExitCodeAndStreamSizes(exe, 0, 0, 3); } } @@ -66,15 +73,15 @@ public class KcRegCreateTest extends AbstractRegCliTest { final String realm = "test"; KcRegExec exe = execute("config initial-token -x --config '" + configFile.getName() + - "' --server " + serverUrl + " --realm " + realm + " " + token); + "' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm " + realm + " " + token); assertExitCodeAndStreamSizes(exe, 0, 0, 0); // check that current server, realm, and initial token are saved in the file ConfigData config = handler.loadConfig(); - Assert.assertEquals("Config serverUrl", serverUrl, config.getServerUrl()); + Assert.assertEquals("Config serverUrl", oauth.AUTH_SERVER_ROOT, config.getServerUrl()); Assert.assertEquals("Config realm", realm, config.getRealm()); - Assert.assertEquals("Config initial access token", token, config.ensureRealmConfigData(serverUrl, realm).getInitialToken()); + Assert.assertEquals("Config initial access token", token, config.ensureRealmConfigData(oauth.AUTH_SERVER_ROOT, realm).getInitialToken()); // create configuration from file using stdin redirect ... output an object String content = "{\n" + @@ -96,9 +103,9 @@ public class KcRegCreateTest extends AbstractRegCliTest { try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) { - exe = execute("create --config '" + configFile.getName() + "' -o -f - < '" + tmpFile.getName() + "'"); + exe = execute("create --insecure --config '" + configFile.getName() + "' -o -f - < '" + tmpFile.getName() + "'"); - assertExitCodeAndStdErrSize(exe, 0, 0); + assertExitCodeAndStdErrSize(exe, 0, 2); ClientRepresentation client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); Assert.assertNotNull("id", client.getId()); @@ -119,12 +126,12 @@ public class KcRegCreateTest extends AbstractRegCliTest { Assert.assertNull("mappers are null", client.getProtocolMappers()); // create configuration from file as a template and override clientId and other attributes ... output an object - exe = execute("create --config '" + configFile.getName() + "' -o -f '" + tmpFile.getName() + + exe = execute("create --insecure --config '" + configFile.getName() + "' -o -f '" + tmpFile.getName() + "' -s clientId=my_client2 -s enabled=false -s 'redirectUris=[\"http://localhost:8980/myapp2/*\"]'" + " -s 'name=My Client App II' -s protocol=openid-connect -s 'webOrigins=[\"http://localhost:8980/myapp2\"]'" + " -s baseUrl=http://localhost:8980/myapp2 -s rootUrl=http://localhost:8980/myapp2"); - assertExitCodeAndStdErrSize(exe, 0, 0); + assertExitCodeAndStdErrSize(exe, 0, 2); ClientRepresentation client2 = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); Assert.assertNotNull("id", client2.getId()); @@ -152,16 +159,16 @@ public class KcRegCreateTest extends AbstractRegCliTest { } // simple create, output an id - exe = execute("create --config '" + configFile.getName() + "' -i -s clientId=my_client3"); + exe = execute("create --insecure --config '" + configFile.getName() + "' -i -s clientId=my_client3"); - assertExitCodeAndStreamSizes(exe, 0, 1, 0); + assertExitCodeAndStreamSizes(exe, 0, 1, 2); Assert.assertEquals("only clientId returned", "my_client3", exe.stdoutLines().get(0)); // simple create, default output - exe = execute("create --config '" + configFile.getName() + "' -s clientId=my_client4"); + exe = execute("create --insecure --config '" + configFile.getName() + "' -s clientId=my_client4"); - assertExitCodeAndStreamSizes(exe, 0, 0, 1); - Assert.assertEquals("only clientId returned", "Registered new client with client_id 'my_client4'", exe.stderrLines().get(0)); + assertExitCodeAndStreamSizes(exe, 0, 0, 3); + Assert.assertEquals("only clientId returned", "Registered new client with client_id 'my_client4'", exe.stderrLines().get(2)); @@ -176,11 +183,11 @@ public class KcRegCreateTest extends AbstractRegCliTest { try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) { - exe = execute("create --config '" + configFile.getName() + "' -s 'client_name=My Client App V' " + + exe = execute("create --insecure --config '" + configFile.getName() + "' -s 'client_name=My Client App V' " + " -s 'redirect_uris=[\"http://localhost:8980/myapp5/*\"]' -s client_uri=http://localhost:8980/myapp5" + " -o -f - < '" + tmpFile.getName() + "'"); - assertExitCodeAndStdErrSize(exe, 0, 0); + assertExitCodeAndStdErrSize(exe, 0, 2); OIDCClientRepresentation client = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class); @@ -205,9 +212,9 @@ public class KcRegCreateTest extends AbstractRegCliTest { File samlSpMetaFile = new File(System.getProperty("user.dir") + "/src/test/resources/cli/kcreg/saml-sp-metadata.xml"); Assert.assertTrue("saml-sp-metadata.xml exists", samlSpMetaFile.isFile()); - exe = execute("create --config '" + configFile.getName() + "' -o -f - < '" + samlSpMetaFile.getAbsolutePath() + "'"); + exe = execute("create --insecure --config '" + configFile.getName() + "' -o -f - < '" + samlSpMetaFile.getAbsolutePath() + "'"); - assertExitCodeAndStdErrSize(exe, 0, 0); + assertExitCodeAndStdErrSize(exe, 0, 2); ClientRepresentation client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class); Assert.assertNotNull("id", client.getId()); @@ -219,7 +226,7 @@ public class KcRegCreateTest extends AbstractRegCliTest { // delete initial token - exe = execute("config initial-token --config '" + configFile.getName() + "' --server " + serverUrl + " --realm " + realm + " --delete"); + exe = execute("config initial-token --config '" + configFile.getName() + "' --insecure --server " + serverUrl + " --realm " + realm + " --delete"); assertExitCodeAndStreamSizes(exe, 0, 0, 0); config = handler.loadConfig(); @@ -234,12 +241,12 @@ public class KcRegCreateTest extends AbstractRegCliTest { try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) { KcRegExec exe = execute("config credentials -x --config '" + configFile.getName() + - "' --server " + serverUrl + " --realm master --user admin --password admin"); - assertExitCodeAndStreamSizes(exe, 0, 0, 1); + "' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm master --user admin --password admin"); + assertExitCodeAndStreamSizes(exe, 0, 0, 3); String token = issueInitialAccessToken("test"); - exe = execute("create --config '" + configFile.getName() + "' --server " + serverUrl + " --realm test -s clientId=authz-client -s authorizationServicesEnabled=true -t " + token); - assertExitCodeAndStreamSizes(exe, 0, 0, 1); + exe = execute("create --config '" + configFile.getName() + "' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm test -s clientId=authz-client -s authorizationServicesEnabled=true -t " + token); + assertExitCodeAndStreamSizes(exe, 0, 0, 3); RealmResource realm = adminClient.realm("test"); ClientsResource clients = realm.clients(); @@ -271,11 +278,11 @@ public class KcRegCreateTest extends AbstractRegCliTest { try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) { - exe = execute("create --config '" + configFile.getName() + "' -s 'client_name=My Reg Authz' --realm test -t " + token + + exe = execute("create --insecure --config '" + configFile.getName() + "' -s 'client_name=My Reg Authz' --realm test -t " + token + " -s 'redirect_uris=[\"http://localhost:8980/myapp5/*\"]' -s client_uri=http://localhost:8980/myapp5" + " -o -f - < '" + tmpFile.getName() + "'"); - assertExitCodeAndStdErrSize(exe, 0, 0); + assertExitCodeAndStdErrSize(exe, 0, 2); OIDCClientRepresentation oidcClient = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java index e24d7d440f..b804c0da29 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java @@ -1,6 +1,7 @@ package org.keycloak.testsuite.cli.registration; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; import org.keycloak.client.registration.cli.config.ConfigData; import org.keycloak.client.registration.cli.config.FileConfigHandler; @@ -571,24 +572,25 @@ public class KcRegTest extends AbstractRegCliTest { } @Test - public void testCreateDeleteWithInitialAndRegistrationTokens() throws IOException { + public void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption() throws IOException { /* * Test create using initial client token, and subsequent delete using registration access token. * A config file is used to save registration access token for newly created client. */ - testCreateDeleteWithInitialAndRegistrationTokens(true); + testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption(true); } @Test - public void testCreateDeleteWithInitialAndRegistrationTokensNoConfig() throws IOException { + public void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOptionNoConfig() throws IOException { /* * Test create using initial client token, and subsequent delete using registration access token. * No config file is used so registration access token for newly created client is not saved to config. */ - testCreateDeleteWithInitialAndRegistrationTokens(false); + testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption(false); } - private void testCreateDeleteWithInitialAndRegistrationTokens(boolean useConfig) throws IOException { + private void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption(boolean useConfig) throws IOException { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); // prepare for loading a config file // only used when useConfig is true @@ -601,7 +603,7 @@ public class KcRegTest extends AbstractRegCliTest { final String realm = "master"; KcRegExec exe = execute("create " + (useConfig ? ("--config '" + configFile.getAbsolutePath()) + "'" : "--no-config") - + " --server " + serverUrl + " --realm " + realm + " -s clientId=test-client2 -o -t " + token); + + " --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm " + realm + " -s clientId=test-client2 -o -t " + token); Assert.assertEquals("exitCode == 0", 0, exe.exitCode()); @@ -615,15 +617,15 @@ public class KcRegTest extends AbstractRegCliTest { if (useConfig) { ConfigData config = handler.loadConfig(); Assert.assertEquals("Registration Access Token in config file", client.getRegistrationAccessToken(), - config.ensureRealmConfigData(serverUrl, realm).getClients().get("test-client2")); + config.ensureRealmConfigData(oauth.AUTH_SERVER_ROOT, realm).getClients().get("test-client2")); } else { Assert.assertFalse("There should be no config file", configFile.isFile()); } exe = execute("delete test-client2 " + (useConfig ? ("--config '" + configFile.getAbsolutePath()) + "'" : "--no-config") - + " --server " + serverUrl + " --realm " + realm + " -t " + client.getRegistrationAccessToken()); + + " --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm " + realm + " -t " + client.getRegistrationAccessToken()); - assertExitCodeAndStreamSizes(exe, 0, 0, 0); + assertExitCodeAndStreamSizes(exe, 0, 0, 2); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java index fcfdeb23d8..a09995cec0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java @@ -33,7 +33,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest { Assert.assertEquals("try help", "Try '" + OsUtil.CMD + " help config truststore' for more information", exe.stderrLines().get(1)); // only run the rest of this test if ssl protected keycloak server is available - if (!isAuthServerSSL()) { + if (!AUTH_SERVER_SSL_REQUIRED) { System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'"); return; } @@ -51,7 +51,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest { // perform authentication against server - asks for password, then for truststore password exe = KcRegExec.newBuilder() - .argsLine("config credentials --server " + serverUrl + " --realm test --user user1" + + .argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" + " --config '" + configFile.getName() + "'") .executeAsync(); @@ -71,7 +71,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest { // perform authentication against server - asks for password, then for truststore password exe = KcRegExec.newBuilder() - .argsLine("config credentials --server " + serverUrl + " --realm test --user user1" + + .argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" + " --config '" + configFile.getName() + "'") .executeAsync(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java index 693cd8664e..0516b03ed0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractClusterTest.java @@ -9,6 +9,7 @@ import org.keycloak.models.Constants; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.arquillian.ContainerInfo; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.util.ContainerAssume; @@ -118,7 +119,7 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest { protected Keycloak createAdminClientFor(ContainerInfo node) { log.info("Initializing admin client for " + node.getContextRoot() + "/auth"); return Keycloak.getInstance(node.getContextRoot() + "/auth", - MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID); + MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()); } protected KeycloakTestingClient createTestingClientFor(ContainerInfo node) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java index 9c97d2652d..9eede4a5e9 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java @@ -94,7 +94,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest { .name("REALM_COMPOSITE_1_APPLICATION") .fullScopeEnabled(Boolean.FALSE) // addScopeMapping(realmComposite1) - .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*") .baseUrl("http://localhost:8180/auth/realms/master/app/auth") .adminUrl("http://localhost:8180/auth/realms/master/app/logout") .secret("password"); @@ -105,7 +105,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest { .name("REALM_ROLE_1_APPLICATION") .fullScopeEnabled(Boolean.FALSE) // addScopeMapping(realmRole1) - .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*") .baseUrl("http://localhost:8180/auth/realms/master/app/auth") .adminUrl("http://localhost:8180/auth/realms/master/app/logout") .secret("password"); @@ -115,7 +115,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest { .clientId("APP_ROLE_APPLICATION") .name("APP_ROLE_APPLICATION") .fullScopeEnabled(Boolean.FALSE) - .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*") .baseUrl("http://localhost:8180/auth/realms/master/app/auth") .adminUrl("http://localhost:8180/auth/realms/master/app/logout") .defaultRoles("APP_ROLE_1", "APP_ROLE_2") @@ -139,7 +139,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest { .fullScopeEnabled(Boolean.FALSE) //.scopeMapping(appRole2) .defaultRoles("APP_COMPOSITE_ROLE") - .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*") .baseUrl("http://localhost:8180/auth/realms/master/app/auth") .adminUrl("http://localhost:8180/auth/realms/master/app/logout") .secret("password"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java index ed87fcfc83..8391fc991e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java @@ -32,8 +32,6 @@ import java.util.concurrent.atomic.AtomicReference; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.LaxRedirectStrategy; import org.junit.Test; import org.keycloak.testsuite.arquillian.annotation.InitialDcState; @@ -75,7 +73,7 @@ public class ConcurrentLoginCrossDCTest extends ConcurrentLoginTest { AtomicReference userSessionId = new AtomicReference<>(); LoginTask loginTask = null; - try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) { + try (CloseableHttpClient httpClient = getHttpsAwareClient()) { loginTask = new LoginTask(httpClient, userSessionId, LOGIN_TASK_DELAY_MS, LOGIN_TASK_RETRIES, false, Arrays.asList( createHttpClientContextForUser(httpClient, "test-user@localhost", "password") )); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java index 95cdd49dea..5164fa0db1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java @@ -92,8 +92,9 @@ public class SessionExpirationCrossDCTest extends AbstractAdminCrossDCTest { ClientRepresentation client = ClientBuilder.create() .clientId("test-app") .directAccessGrants() - .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*") .addWebOrigin("http://localhost:8180") + .addWebOrigin("https://localhost:8543") .secret("password") .build(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ChallengeFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ChallengeFlowTest.java index 5855979eb2..03ebc899eb 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ChallengeFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ChallengeFlowTest.java @@ -88,6 +88,8 @@ public class ChallengeFlowTest extends AbstractTestRealmKeycloakTest { @Before public void setupFlows() { + SerializableApplicationData serializedApplicationData = new SerializableApplicationData(oauth.APP_AUTH_ROOT, oauth.APP_ROOT + "/admin", oauth.APP_AUTH_ROOT + "/*"); + testingClient.server().run(session -> { RealmModel realm = session.realms().getRealmByName("test"); @@ -116,10 +118,10 @@ public class ChallengeFlowTest extends AbstractTestRealmKeycloakTest { client = realm.addClient(TEST_APP_FLOW); client.setSecret("password"); - client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); - client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); + client.setBaseUrl(serializedApplicationData.applicationBaseUrl); + client.setManagementUrl(serializedApplicationData.applicationManagementUrl); client.setEnabled(true); - client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*"); + client.addRedirectUri(serializedApplicationData.applicationRedirectUrl); client.addRedirectUri("urn:ietf:wg:oauth:2.0:oob"); client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId()); client.setPublicClient(false); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java index dd3613eedf..a79cca75a6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java @@ -17,7 +17,6 @@ package org.keycloak.testsuite.forms; -import org.apache.http.client.utils.URLEncodedUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.graphene.page.Page; import org.jboss.shrinkwrap.api.spec.WebArchive; @@ -58,7 +57,6 @@ import javax.ws.rs.core.Form; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; -import java.nio.charset.Charset; import java.util.List; import static org.junit.Assert.assertEquals; @@ -99,9 +97,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest { .addPackages(true, "org.keycloak.testsuite"); } - @Before public void setupFlows() { + SerializableApplicationData serializedApplicationData = new SerializableApplicationData(oauth.APP_AUTH_ROOT, oauth.APP_ROOT + "/admin", oauth.APP_AUTH_ROOT + "/*"); + testingClient.server().run(session -> { RealmModel realm = session.realms().getRealmByName("test"); @@ -113,8 +112,6 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest { client = session.realms().getClientByClientId("test-app", realm); client.setDirectAccessGrantsEnabled(true); - - // Parent flow AuthenticationFlowModel browser = new AuthenticationFlowModel(); browser.setAlias("parent-flow"); @@ -163,10 +160,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest { client = realm.addClient(TEST_APP_FLOW); client.setSecret("password"); - client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); - client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); + client.setBaseUrl(serializedApplicationData.applicationBaseUrl); + client.setManagementUrl(serializedApplicationData.applicationManagementUrl); client.setEnabled(true); - client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*"); + client.addRedirectUri(serializedApplicationData.applicationRedirectUrl); client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId()); client.setPublicClient(false); @@ -206,10 +203,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest { client = realm.addClient(TEST_APP_DIRECT_OVERRIDE); client.setSecret("password"); - client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); - client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); + client.setBaseUrl(serializedApplicationData.applicationBaseUrl); + client.setManagementUrl(serializedApplicationData.applicationManagementUrl); client.setEnabled(true); - client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*"); + client.addRedirectUri(serializedApplicationData.applicationRedirectUrl); client.setPublicClient(false); client.setDirectAccessGrantsEnabled(true); client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId()); @@ -218,10 +215,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest { client = realm.addClient(TEST_APP_HTTP_CHALLENGE); client.setSecret("password"); - client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); - client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); + client.setBaseUrl(serializedApplicationData.applicationBaseUrl); + client.setManagementUrl(serializedApplicationData.applicationManagementUrl); client.setEnabled(true); - client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*"); + client.addRedirectUri(serializedApplicationData.applicationRedirectUrl); client.setPublicClient(true); client.setDirectAccessGrantsEnabled(true); client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.DIRECT_GRANT_BINDING, realm.getFlowByAlias("http challenge").getId()); @@ -522,7 +519,7 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest { form.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE); form.param(OAuth2Constants.CLIENT_ID, TEST_APP_HTTP_CHALLENGE); - form.param(OAuth2Constants.REDIRECT_URI, "http://localhost:8180/auth/realms/master/app/auth"); + form.param(OAuth2Constants.REDIRECT_URI, oauth.APP_AUTH_ROOT); form.param(OAuth2Constants.CODE, location.substring(location.indexOf(OAuth2Constants.CODE) + OAuth2Constants.CODE.length() + 1)); // exchange code to token diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java index a4b29f169c..fff627871e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java @@ -73,7 +73,7 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest { String sessionId = events.expectLogin().assertEvent().getSessionId(); - String redirectUri = AppPage.baseUrl + "?logout"; + String redirectUri = oauth.APP_AUTH_ROOT + "?logout"; String logoutUrl = oauth.getLogoutUrl().redirectUri(redirectUri).build(); driver.navigate().to(logoutUrl); @@ -130,8 +130,8 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest { events.expectLogin().session(sessionId).removeDetail(Details.USERNAME).assertEvent(); // Logout session 1 by redirect - driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build()); - events.expectLogout(sessionId).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent(); + driver.navigate().to(oauth.getLogoutUrl().redirectUri(oauth.APP_AUTH_ROOT).build()); + events.expectLogout(sessionId).detail(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT).assertEvent(); // Check session 1 not logged-in oauth.openLoginForm(); @@ -147,8 +147,8 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest { events.expectLogin().session(sessionId3).removeDetail(Details.USERNAME).assertEvent(); // Logout session 3 by redirect - driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build()); - events.expectLogout(sessionId3).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent(); + driver.navigate().to(oauth.getLogoutUrl().redirectUri(oauth.APP_AUTH_ROOT).build()); + events.expectLogout(sessionId3).detail(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT).assertEvent(); } //KEYCLOAK-2741 diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java index a1388eefdf..e7494de8be 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java @@ -60,6 +60,11 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { public void configureTestRealm(RealmRepresentation testRealm) { } + @Override + protected boolean modifyRealmForSSL() { + return true; + } + @Before public void setup() { UserRepresentation user = UserBuilder.create() @@ -269,15 +274,16 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { // KEYCLOAK-5797 @Test public void loginWithDifferentClients() throws Exception { - // Open tab1 and start login here - oauth.openLoginForm(); - loginPage.assertCurrent(); - loginPage.login("login-test", "bad-password"); - String tab1Url = driver.getCurrentUrl(); + String redirectUri = String.format("%s://localhost:%s/foo/bar/baz", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT); + // Open tab1 and start login here + oauth.openLoginForm(); + loginPage.assertCurrent(); + loginPage.login("login-test", "bad-password"); + String tab1Url = driver.getCurrentUrl(); - // Go to tab2 and start login with different client "root-url-client" - oauth.clientId("root-url-client"); - oauth.redirectUri("http://localhost:8180/foo/bar/baz"); + // Go to tab2 and start login with different client "root-url-client" + oauth.clientId("root-url-client"); + oauth.redirectUri(redirectUri); oauth.openLoginForm(); loginPage.assertCurrent(); String tab2Url = driver.getCurrentUrl(); @@ -294,16 +300,18 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { // Go back to tab2 and finish login here. Should be on the root-url-client page driver.navigate().to(tab2Url); String currentUrl = driver.getCurrentUrl(); - Assert.assertThat(currentUrl, Matchers.startsWith("http://localhost:8180/foo/bar/baz")); + Assert.assertThat(currentUrl, Matchers.startsWith(redirectUri)); } // KEYCLOAK-5938 @Test public void loginWithSameClientDifferentStatesLoginInTab1() throws Exception { + String redirectUri1 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix1", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT); + String redirectUri2 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix2", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT); // Open tab1 and start login here oauth.stateParamHardcoded("state1"); - oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix1"); + oauth.redirectUri(redirectUri1); oauth.openLoginForm(); loginPage.assertCurrent(); loginPage.login("login-test", "bad-password"); @@ -311,7 +319,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { // Go to tab2 and start login with different client "root-url-client" oauth.stateParamHardcoded("state2"); - oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix2"); + oauth.redirectUri(redirectUri2); oauth.openLoginForm(); loginPage.assertCurrent(); String tab2Url = driver.getCurrentUrl(); @@ -325,7 +333,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { // Assert I am redirected to the appPage in tab1 and have state corresponding to tab1 appPage.assertCurrent(); String currentUrl = driver.getCurrentUrl(); - Assert.assertThat(currentUrl, Matchers.startsWith("http://localhost:8180/auth/realms/master/app/auth/suffix1")); + Assert.assertThat(currentUrl, Matchers.startsWith(redirectUri1)); Assert.assertTrue(currentUrl.contains("state1")); } @@ -333,9 +341,11 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { // KEYCLOAK-5938 @Test public void loginWithSameClientDifferentStatesLoginInTab2() throws Exception { + String redirectUri1 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix1", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT); + String redirectUri2 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix2", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT); // Open tab1 and start login here oauth.stateParamHardcoded("state1"); - oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix1"); + oauth.redirectUri(redirectUri1); oauth.openLoginForm(); loginPage.assertCurrent(); loginPage.login("login-test", "bad-password"); @@ -343,7 +353,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { // Go to tab2 and start login with different client "root-url-client" oauth.stateParamHardcoded("state2"); - oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix2"); + oauth.redirectUri(redirectUri2); oauth.openLoginForm(); loginPage.assertCurrent(); String tab2Url = driver.getCurrentUrl(); @@ -356,7 +366,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest { // Assert I am redirected to the appPage in tab2 and have state corresponding to tab2 appPage.assertCurrent(); String currentUrl = driver.getCurrentUrl(); - Assert.assertThat(currentUrl, Matchers.startsWith("http://localhost:8180/auth/realms/master/app/auth/suffix2")); + Assert.assertThat(currentUrl, Matchers.startsWith(redirectUri2)); Assert.assertTrue(currentUrl.contains("state2")); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/SerializableApplicationData.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/SerializableApplicationData.java new file mode 100644 index 0000000000..18222e822a --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/SerializableApplicationData.java @@ -0,0 +1,20 @@ +package org.keycloak.testsuite.forms; + +import java.io.Serializable; + +/** + * The only purpose of this class is to serialize data obtained from oauth field + * and pass it to the server. + */ +public class SerializableApplicationData implements Serializable { + + public final String applicationBaseUrl; + public final String applicationManagementUrl; + public final String applicationRedirectUrl; + + public SerializableApplicationData(String applicationBaseUrl, String applicationManagementUrl, String applicationRedirectUrl) { + this.applicationBaseUrl = applicationBaseUrl; + this.applicationManagementUrl = applicationManagementUrl; + this.applicationRedirectUrl = applicationRedirectUrl; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java index 67200906cc..2aa3b3f282 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java @@ -488,7 +488,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { } Response response = executeGrantAccessTokenRequest(grantTarget); - assertEquals(403, response.getStatus()); + assertEquals(AUTH_SERVER_SSL_REQUIRED ? 200 : 403, response.getStatus()); response.close(); { @@ -932,7 +932,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { adminClient.realm("test").clients().create(ClientBuilder.create() .clientId("sample-public-client") .authenticatorType("client-secret") - .redirectUris("http://localhost:8180/auth/realms/master/app/*") + .redirectUris(oauth.getRedirectUri() + "/*") .publicClient() .build()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java index 1bffdcc0f9..83e0988ce6 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java @@ -88,9 +88,9 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { String title = PageUtils.getPageTitle(driver); Assert.assertEquals("Success code", title); - String code = driver.findElement(By.id(OAuth2Constants.CODE)).getAttribute("value"); + driver.findElement(By.id(OAuth2Constants.CODE)).getAttribute("value"); - String codeId = events.expectLogin().detail(Details.REDIRECT_URI, "http://localhost:8180/auth/realms/test/protocol/openid-connect/oauth/oob").assertEvent().getDetails().get(Details.CODE_ID); + events.expectLogin().detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/protocol/openid-connect/oauth/oob").assertEvent().getDetails().get(Details.CODE_ID); ClientManager.realm(adminClient.realm("test")).clientId("test-app").removeRedirectUris(Constants.INSTALLED_APP_URN); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java index 70f614257a..a93715b2c2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java @@ -140,13 +140,13 @@ public class LogoutTest extends AbstractKeycloakTest { String logoutUrl = oauth.getLogoutUrl() .idTokenHint(idTokenString) - .postLogoutRedirectUri(AppPage.baseUrl) + .postLogoutRedirectUri(oauth.APP_AUTH_ROOT) .build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); - assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl)); + assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT)); } } @@ -165,13 +165,13 @@ public class LogoutTest extends AbstractKeycloakTest { String logoutUrl = oauth.getLogoutUrl() .idTokenHint(idTokenString) - .postLogoutRedirectUri(AppPage.baseUrl) + .postLogoutRedirectUri(oauth.APP_AUTH_ROOT) .build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); - assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl)); + assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT)); } } @@ -190,13 +190,13 @@ public class LogoutTest extends AbstractKeycloakTest { // Logout should succeed with user already logged out, see KEYCLOAK-3399 String logoutUrl = oauth.getLogoutUrl() .idTokenHint(idTokenString) - .postLogoutRedirectUri(AppPage.baseUrl) + .postLogoutRedirectUri(oauth.APP_AUTH_ROOT) .build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); - assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl)); + assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT)); } } @@ -226,13 +226,13 @@ public class LogoutTest extends AbstractKeycloakTest { String logoutUrl = oauth.getLogoutUrl() .idTokenHint(idTokenString) - .postLogoutRedirectUri(AppPage.baseUrl) + .postLogoutRedirectUri(oauth.APP_AUTH_ROOT) .build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); - assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl)); + assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT)); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java index 618ba4ece1..f617f0c51c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java @@ -17,7 +17,10 @@ package org.keycloak.testsuite.oauth; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import org.hamcrest.Matchers; import org.jboss.arquillian.graphene.page.Page; @@ -76,7 +79,8 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest { ClientRepresentation client = new ClientRepresentation(); client.setClientId("more-uris-client"); client.setEnabled(true); - client.setRedirectUris(Arrays.asList("http://localhost:8180/auth/realms/master/app/auth", "http://localhost:8180/foo")); + client.setRedirectUris(Arrays.asList("http://localhost:8180/auth/realms/master/app/auth", "http://localhost:8180/foo", + "https://localhost:8543/auth/realms/master/app/auth", "https://localhost:8543/foo")); client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); testRealm.getClients().add(client); @@ -85,6 +89,15 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest { .filter(cl -> cl.getClientId().equals("test-app")) .findFirst().get(); testApp.setImplicitFlowEnabled(true); + trimRedirectUris(testApp); + } + + // testMissingRedirectUri requires only one redirection url defined in the client. We need to trim the other one. + private final void trimRedirectUris(ClientRepresentation testApp) { + List filteredUris = testApp.getRedirectUris().stream() + .filter(uri -> AUTH_SERVER_SSL_REQUIRED ? uri.startsWith("https://") : uri.startsWith("http://")) + .collect(Collectors.toList()); + testApp.setRedirectUris(filteredUris); } @Before @@ -93,7 +106,7 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest { /* * Configure the default client ID. Seems like OAuthClient is keeping the state of clientID * For example: If some test case configure oauth.clientId("sample-public-client"), other tests - * will faile and the clientID will always be "sample-public-client + * will fail and the clientID will always be "sample-public-client * @see AccessTokenTest#testAuthorizationNegotiateHeaderIgnored() */ oauth.init(driver); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java index 73ffc22037..faea4b5fba 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java @@ -144,7 +144,7 @@ public class OAuthRedirectUriTest extends AbstractKeycloakTest { realm.client(installedApp7); ClientBuilder installedApp8 = ClientBuilder.create().id("test-fragment").name("test-fragment") - .redirectUris("http://localhost/*") + .redirectUris("http://localhost/*", "https://localhost:8543/*") .secret("password"); realm.client(installedApp8); 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 d4a1fc67ad..7363db2ee3 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 @@ -89,12 +89,6 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest { @Rule public AssertEvents events = new AssertEvents(this); - - @Override - public void beforeAbstractKeycloakTest() throws Exception { - super.beforeAbstractKeycloakTest(); - } - @Before public void clientConfiguration() { ClientManager.realm(adminClient.realm("test")).clientId("test-app").directAccessGrant(true); @@ -237,8 +231,7 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest { Assert.assertThat(accessToken.getAudience(), arrayContainingInAnyOrder( "app", "account")); // Assert allowed origins - String expectedOrigin = UriUtils.getOrigin(oauth.getRedirectUri()); - Assert.assertNames(accessToken.getAllowedOrigins(), expectedOrigin); + Assert.assertNames(accessToken.getAllowedOrigins(), "http://localhost:8180", "https://localhost:8543"); oauth.openLogout(); } 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 c53fdd72db..4416e5b20a 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 @@ -51,6 +51,7 @@ import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.account.AccountFormServiceTest; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.arquillian.undertow.TLSUtils; import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.pages.AccountApplicationsPage; import org.keycloak.testsuite.pages.LoginPage; @@ -514,7 +515,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest { // Use accessToken to admin REST request try (Keycloak offlineTokenAdmin = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", - AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, tokenResponse.getAccessToken())) { + AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, tokenResponse.getAccessToken(), TLSUtils.initializeTLS())) { RealmRepresentation testRealm = offlineTokenAdmin.realm("test").toRepresentation(); Assert.assertNotNull(testRealm); } @@ -560,7 +561,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest { // Go to account mgmt applications page applicationsPage.open(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().client("account").detail(Details.REDIRECT_URI, AccountFormServiceTest.ACCOUNT_REDIRECT + "?path=applications").assertEvent(); + events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=applications").assertEvent(); assertTrue(applicationsPage.isCurrent()); Map apps = applicationsPage.getApplications(); assertTrue(apps.containsKey("offline-client-2")); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java index 6ba71c7827..176db8f3a6 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java @@ -776,7 +776,7 @@ public class RefreshTokenTest extends AbstractKeycloakTest { response.close(); } - { // test checkSsl + if (!AUTH_SERVER_SSL_REQUIRED) { // test checkSsl RealmResource realmResource = adminClient.realm("test"); { RealmManager.realm(realmResource).sslRequired(SslRequired.ALL.toString()); @@ -789,7 +789,6 @@ public class RefreshTokenTest extends AbstractKeycloakTest { { RealmManager.realm(realmResource).sslRequired(SslRequired.EXTERNAL.toString()); } - } { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/openshift/OpenShiftTokenReviewEndpointTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/openshift/OpenShiftTokenReviewEndpointTest.java index e61050399c..1c36d3c880 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/openshift/OpenShiftTokenReviewEndpointTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/openshift/OpenShiftTokenReviewEndpointTest.java @@ -109,8 +109,7 @@ public class OpenShiftTokenReviewEndpointTest extends AbstractTestRealmKeycloakT @Test public void basicTest() { - Review r = new Review().invoke() - .assertSuccess(); + Review r = new Review().invoke(); String userId = testRealm().users().search(r.username).get(0).getId(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java index 7045c0d47d..5c659230d4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java @@ -23,13 +23,13 @@ public abstract class AbstractSamlTest extends AbstractAuthTest { public static final String REALM_PRIVATE_KEY = "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y="; public static final String REALM_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB"; - public static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST = "http://localhost:8080/sales-post/saml"; + public static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST = AUTH_SERVER_SCHEME + "://localhost:" + (AUTH_SERVER_SSL_REQUIRED ? AUTH_SERVER_PORT : 8080) + "/sales-post/saml"; public static final String SAML_CLIENT_ID_SALES_POST = "http://localhost:8280/sales-post/"; - public static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST2 = "http://localhost:8080/sales-post2/saml"; + public static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST2 = AUTH_SERVER_SCHEME + "://localhost:" + (AUTH_SERVER_SSL_REQUIRED ? AUTH_SERVER_PORT : 8080) + "/sales-post2/saml"; public static final String SAML_CLIENT_ID_SALES_POST2 = "http://localhost:8280/sales-post2/"; - public static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST_SIG = "http://localhost:8080/sales-post-sig/"; + public static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST_SIG = AUTH_SERVER_SCHEME + "://localhost:" + (AUTH_SERVER_SSL_REQUIRED ? AUTH_SERVER_PORT : 8080) + "/sales-post-sig/"; public static final String SAML_CLIENT_ID_SALES_POST_SIG = "http://localhost:8280/sales-post-sig/"; public static final String SAML_URL_SALES_POST_SIG = "http://localhost:8080/sales-post-sig/"; public static final String SAML_CLIENT_SALES_POST_SIG_PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANUbxrvEY3pkiQNt55zJLKBwN+zKmNQw08ThAmOKzwHfXoK+xlDSFxNMtTKJGkeUdnKzaTfESEcEfKYULUA41y/NnOlvjS0CEsc7Wq0Ce63TSSGMB2NHea4tV0aQz/MwLsbmz2IjAFWHA5CHL5WwacIf3UTOSNnhJUSvnkomjJAlAgMBAAECgYANpO2gb/5+g5lSIuNFYov86bJq8r2+ODIW1OE2Rljioc6HSHeiDRF1JuAjECwikRrUVTBTZbnK8jqY14neJsWAKBzGo+ToaQALsNZ9B91DxxL50K5oVOzw5shAS9TnRjN40+KIXFED4ydq4JRdoqb8+cN+N3i0+Cu7tdm+UaHTAQJBAOwFs3ZwqQEqmv9vmgmIFwFpJm1aIw25gEOf3Hy45GP4bL/j0FQgwcXYRbLE5bPqhw/liLKc1GQ97bVm6zs8SvUCQQDnJZA6TFRMiDjezinE1J4e0v4RupyDniVjbE5ArTK5/FRVkjw4Ny0AqZUEyIIqlTeZlCq45pCJy4a2hymDGVJxAj9gzfXNnmezEsZ//kYvoqHM8lPQhifaeTsigW7tuOf0GPCBw+6uksDnZM0xhZCxOoArBPoMSEbU1pGo1Y2lvhUCQF6E5sBgHAybm53Ich4Rz4LNRqWbSIstrR5F2I3sBRU2kInZXZSjQ1zE+7HUCB4/nFfJ1dp8NdiTCEg1Zw072pECQQDnxyQALmWhQbBTl0tq6CwYf9rZDwBzxuY+CXB8Ky1gOmXwan96KZvV4rK8MQQs6HIiYC/j+5lX3A3zlXTFldaz"; @@ -54,6 +54,11 @@ public abstract class AbstractSamlTest extends AbstractAuthTest { testRealms.add(loadRealm("/adapter-test/keycloak-saml/testsaml.json")); } + @Override + protected boolean modifyRealmForSSL() { + return true; + } + protected AuthnRequestType createLoginRequestDocument(String issuer, String assertionConsumerURL, String realmName) { return SamlClient.createLoginRequestDocument(issuer, assertionConsumerURL, getAuthServerSamlEndpoint(realmName)); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java index d2618383fe..774c0cb934 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java @@ -156,7 +156,7 @@ public class BasicSamlTest extends AbstractSamlTest { @Test public void testExplicitPortInDestination() throws Exception { - testWithOverriddenPort(Integer.valueOf(System.getProperty("auth.server.http.port")), Response.Status.OK, containsString("login")); + testWithOverriddenPort(Integer.valueOf(AUTH_SERVER_PORT), Response.Status.OK, containsString("login")); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ssl/TLSTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ssl/TLSTest.java new file mode 100644 index 0000000000..71506e81e0 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ssl/TLSTest.java @@ -0,0 +1,78 @@ +package org.keycloak.testsuite.ssl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; + +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.List; + +import org.jboss.arquillian.container.test.api.ContainerController; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.junit.Assume; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.keycloak.client.registration.Auth; +import org.keycloak.client.registration.ClientRegistration; +import org.keycloak.client.registration.ClientRegistrationException; +import org.keycloak.common.enums.SslRequired; +import org.keycloak.jose.jws.JWSInput; +import org.keycloak.jose.jws.JWSInputException; +import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation; +import org.keycloak.representations.AccessToken; +import org.keycloak.representations.JsonWebToken; +import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; +import org.keycloak.representations.idm.ClientInitialAccessPresentation; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; +import org.keycloak.testsuite.Assert; +import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.util.OAuthClient; +import org.wildfly.extras.creaper.core.online.OnlineManagementClient; +import org.wildfly.extras.creaper.core.online.operations.admin.Administration; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * This test checks if TLS can be explicitly switched off. + * + * Note, it should run only if TLS is enabled by default. + */ +public class TLSTest extends AbstractTestRealmKeycloakTest { + + public static final String AUTH_SERVER_ROOT_WITHOUT_TLS = "http://localhost:" + System.getProperty("auth.server.http.port", "8180") + "/auth"; + + @BeforeClass + public static void checkIfTLSIsTurnedOn() { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); + } + + @Override + protected boolean modifyRealmForSSL() { + return false; + } + + @Override + public void configureTestRealm(RealmRepresentation testRealm) { + testRealm.setSslRequired(SslRequired.NONE.toString()); + } + + @Test + public void testTurningTLSOn() throws Exception { + //given + oauth.baseUrl(AUTH_SERVER_ROOT_WITHOUT_TLS); + + //when + OIDCConfigurationRepresentation config = oauth.doWellKnownRequest("test"); + + //then + Assert.assertTrue(config.getAuthorizationEndpoint().startsWith(AUTH_SERVER_ROOT_WITHOUT_TLS)); + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java index 1ece435c51..988b2a7c58 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java @@ -5,7 +5,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.jboss.arquillian.container.test.api.ContainerController; import org.jboss.arquillian.test.api.ArquillianResource; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; +import org.keycloak.admin.client.Keycloak; import org.keycloak.client.registration.Auth; import org.keycloak.client.registration.ClientRegistration; import org.keycloak.client.registration.ClientRegistrationException; @@ -20,6 +22,7 @@ import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.util.AdminClientUtil; import org.keycloak.testsuite.util.OAuthClient; import org.wildfly.extras.creaper.core.online.OnlineManagementClient; import org.wildfly.extras.creaper.core.online.operations.admin.Administration; @@ -37,15 +40,9 @@ public class FixedHostnameTest extends AbstractKeycloakTest { @ArquillianResource protected ContainerController controller; - String authServerUrl; + private String authServerUrl; - String suiteScheme; - - @Before - public void before() throws URISyntaxException { - suiteScheme = suiteContext.getAuthServerInfo().getContextRoot().toURI().getScheme(); - authServerUrl = suiteContext.getAuthServerInfo().getContextRoot() + "/auth"; - } + private Keycloak testAdminClient; @Override public void addTestRealms(List testRealms) { @@ -63,21 +60,25 @@ public class FixedHostnameTest extends AbstractKeycloakTest { @Test public void fixedHostname() throws Exception { + authServerUrl = oauth.AUTH_SERVER_ROOT; + oauth.baseUrl(authServerUrl); + testAdminClient = AdminClientUtil.createAdminClient(suiteContext.isAdapterCompatTesting(), AuthServerTestEnricher.getAuthServerContextRoot()); + oauth.clientId("direct-grant"); try { - assertWellKnown("test", suiteScheme + "://localhost:8180"); + assertWellKnown("test", AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT); configureFixedHostname(-1, -1, false); - assertWellKnown("test", suiteScheme + "://keycloak.127.0.0.1.nip.io:8180"); - assertWellKnown("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io:8180"); + assertWellKnown("test", AUTH_SERVER_SCHEME + "://keycloak.127.0.0.1.nip.io:" + AUTH_SERVER_PORT); + assertWellKnown("hostname", AUTH_SERVER_SCHEME + "://custom-domain.127.0.0.1.nip.io:" + AUTH_SERVER_PORT); - assertTokenIssuer("test", suiteScheme + "://keycloak.127.0.0.1.nip.io:8180"); - assertTokenIssuer("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io:8180"); + assertTokenIssuer("test", AUTH_SERVER_SCHEME + "://keycloak.127.0.0.1.nip.io:" + AUTH_SERVER_PORT); + assertTokenIssuer("hostname", AUTH_SERVER_SCHEME + "://custom-domain.127.0.0.1.nip.io:" + AUTH_SERVER_PORT); - assertInitialAccessTokenFromMasterRealm("test", suiteScheme + "://keycloak.127.0.0.1.nip.io:8180"); - assertInitialAccessTokenFromMasterRealm("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io:8180"); + assertInitialAccessTokenFromMasterRealm("test", AUTH_SERVER_SCHEME + "://keycloak.127.0.0.1.nip.io:" + AUTH_SERVER_PORT); + assertInitialAccessTokenFromMasterRealm("hostname", AUTH_SERVER_SCHEME + "://custom-domain.127.0.0.1.nip.io:" + AUTH_SERVER_PORT); } finally { clearFixedHostname(); } @@ -86,23 +87,25 @@ public class FixedHostnameTest extends AbstractKeycloakTest { @Test public void fixedHttpPort() throws Exception { // Make sure request are always sent with http - authServerUrl = authServerUrl.replace("https://", "http://"); + authServerUrl = "http://localhost:8180/auth"; + oauth.baseUrl(authServerUrl); + testAdminClient = AdminClientUtil.createAdminClient(suiteContext.isAdapterCompatTesting(), "http://localhost:8180"); oauth.clientId("direct-grant"); try { - assertWellKnown("test", suiteScheme + "://localhost:8180"); + assertWellKnown("test", "http://localhost:8180"); configureFixedHostname(80, -1, false); - assertWellKnown("test", suiteScheme + "://keycloak.127.0.0.1.nip.io"); - assertWellKnown("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io"); + assertWellKnown("test", "http://keycloak.127.0.0.1.nip.io"); + assertWellKnown("hostname", "http://custom-domain.127.0.0.1.nip.io"); - assertTokenIssuer("test", suiteScheme + "://keycloak.127.0.0.1.nip.io"); - assertTokenIssuer("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io"); + assertTokenIssuer("test", "http://keycloak.127.0.0.1.nip.io"); + assertTokenIssuer("hostname", "http://custom-domain.127.0.0.1.nip.io"); - assertInitialAccessTokenFromMasterRealm("test", suiteScheme + "://keycloak.127.0.0.1.nip.io"); - assertInitialAccessTokenFromMasterRealm("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io"); + assertInitialAccessTokenFromMasterRealm("test", "http://keycloak.127.0.0.1.nip.io"); + assertInitialAccessTokenFromMasterRealm("hostname", "http://custom-domain.127.0.0.1.nip.io"); } finally { clearFixedHostname(); } @@ -111,12 +114,14 @@ public class FixedHostnameTest extends AbstractKeycloakTest { @Test public void fixedHostnameAlwaysHttpsHttpsPort() throws Exception { // Make sure request are always sent with http - authServerUrl = authServerUrl.replace("https://", "http://"); + authServerUrl = "http://localhost:8180/auth"; + oauth.baseUrl(authServerUrl); + testAdminClient = AdminClientUtil.createAdminClient(suiteContext.isAdapterCompatTesting(), "http://localhost:8180"); oauth.clientId("direct-grant"); try { - assertWellKnown("test", suiteScheme + "://localhost:8180"); + assertWellKnown("test", "http://localhost:8180"); configureFixedHostname(-1, 443, true); @@ -138,7 +143,7 @@ public class FixedHostnameTest extends AbstractKeycloakTest { rep.setCount(1); rep.setExpiration(10000); - ClientInitialAccessPresentation initialAccess = adminClient.realm(realm).clientInitialAccess().create(rep); + ClientInitialAccessPresentation initialAccess = testAdminClient.realm(realm).clientInitialAccess().create(rep); JsonWebToken token = new JWSInput(initialAccess.getToken()).readJsonContent(JsonWebToken.class); assertEquals(expectedBaseUrl + "/auth/realms/" + realm, token.getIssuer()); @@ -155,7 +160,6 @@ public class FixedHostnameTest extends AbstractKeycloakTest { } private void assertTokenIssuer(String realm, String expectedBaseUrl) throws Exception { - oauth.baseUrl(authServerUrl); oauth.realm(realm); OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password"); @@ -171,7 +175,6 @@ public class FixedHostnameTest extends AbstractKeycloakTest { } private void assertWellKnown(String realm, String expectedBaseUrl) { - oauth.baseUrl(authServerUrl); OIDCConfigurationRepresentation config = oauth.doWellKnownRequest(realm); assertEquals(expectedBaseUrl + "/auth/realms/" + realm + "/protocol/openid-connect/token", config.getTokenEndpoint()); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java index 0575317458..e2bb967856 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java @@ -61,8 +61,7 @@ public class MailAssert { assertTrue(errorMessage, messageContent.contains(content)); for (String string : messageContent.split("\n")) { - if (string.contains("http://")) { - + if (string.startsWith("http")) { // Ampersand escaped in the text version. Needs to be replaced to have correct URL string = string.replace("&", "&"); return string; diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant1-keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant1-keycloak-saml.xml index cd3ae8b96f..9fc9dcc317 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant1-keycloak-saml.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant1-keycloak-saml.xml @@ -31,6 +31,7 @@ responseBinding="POST" postBindingUrl="http://localhost:8080/auth/realms/tenant1/protocol/saml" redirectBindingUrl="http://localhost:8080/auth/realms/tenant1/protocol/saml"/> + diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant2-keycloak-saml.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant2-keycloak-saml.xml index 4058f4df0a..3dfe8933f1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant2-keycloak-saml.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/keycloak-saml/multi-tenant-saml/WEB-INF/tenant2-keycloak-saml.xml @@ -31,6 +31,7 @@ responseBinding="POST" postBindingUrl="http://localhost:8080/auth/realms/tenant2/protocol/saml" redirectBindingUrl="http://localhost:8080/auth/realms/tenant2/protocol/saml"/> + diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml index a158020adf..2f6b171840 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -103,6 +103,7 @@ 0.0.0.0 org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow ${auth.server.http.port} + ${auth.server.https.port} ${undertow.remote} @@ -204,7 +205,9 @@ org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow localhost ${auth.server.http.port} + ${auth.server.https.port} 1 + 1 node1 ${undertow.remote} { @@ -221,7 +224,9 @@ org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow localhost ${auth.server.http.port} + ${auth.server.https.port} 2 + 2 node2 ${undertow.remote} { @@ -239,6 +244,7 @@ org.keycloak.testsuite.arquillian.undertow.lb.SimpleUndertowLoadBalancerContainer localhost ${auth.server.http.port} + ${auth.server.https.port} node1=http://localhost:8181,node2=http://localhost:8182 @@ -345,7 +351,9 @@ org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow localhost ${auth.server.http.port} + ${auth.server.https.port} -78 + -78 ${undertow.remote} 0 { @@ -370,7 +378,9 @@ org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow localhost ${auth.server.http.port} + ${auth.server.https.port} -69 + -69 ${undertow.remote} 1 { @@ -394,7 +404,9 @@ org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow localhost ${auth.server.http.port} + ${auth.server.https.port} -68 + -68 ${undertow.remote} 1 { @@ -438,6 +450,7 @@ ${auth.server.crossdc01.management.port} -79 + -79 0 ${auth.server.jboss.startup.timeout} @@ -468,6 +481,7 @@ ${auth.server.crossdc02.management.port} -78 + -78 0 ${auth.server.jboss.startup.timeout} @@ -499,6 +513,7 @@ ${auth.server.crossdc11.management.port} -69 + -69 1 ${auth.server.jboss.startup.timeout} @@ -529,6 +544,7 @@ ${auth.server.crossdc12.management.port} -68 + -68 1 ${auth.server.jboss.startup.timeout} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/client-auth-test/testrealm-jwt-client-secret.json b/testsuite/integration-arquillian/tests/base/src/test/resources/client-auth-test/testrealm-jwt-client-secret.json index f102a96ec4..eb3f3d5978 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/client-auth-test/testrealm-jwt-client-secret.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/client-auth-test/testrealm-jwt-client-secret.json @@ -26,7 +26,8 @@ "enabled": true, "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/auth/*" + "http://localhost:8180/auth/realms/master/app/auth/*", + "https://localhost:8543/auth/realms/master/app/auth/*" ], "adminUrl": "http://localhost:8180/auth/realms/master/app/admin", "clientAuthenticatorType": "client-secret-jwt", diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/ldap/fed-provider-export.json b/testsuite/integration-arquillian/tests/base/src/test/resources/ldap/fed-provider-export.json index 06d5999bbf..d4e5f34997 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/ldap/fed-provider-export.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/ldap/fed-provider-export.json @@ -69,7 +69,8 @@ "enabled": true, "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/auth/*" + "http://localhost:8180/auth/realms/master/app/auth/*", + "https://localhost:8543/auth/realms/master/app/auth/*" ], "adminUrl": "http://localhost:8180/auth/realms/master/app/admin", "secret": "password" diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/org/keycloak/testsuite/broker/kc3731-broker-realm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/org/keycloak/testsuite/broker/kc3731-broker-realm.json index 76a68ad616..41d4d073ee 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/org/keycloak/testsuite/broker/kc3731-broker-realm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/org/keycloak/testsuite/broker/kc3731-broker-realm.json @@ -5,18 +5,18 @@ "sslRequired" : "external", "roles" : { "client" : { - "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth" : [ { + "${url.realm.consumer}/app/auth" : [ { "name" : "manager" } ] } }, "clients" : [ { - "clientId": "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth", + "clientId": "${url.realm.consumer}/app/auth", "enabled": true, "protocol": "saml", "fullScopeAllowed": true, "redirectUris": [ - "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth/*" + "${url.realm.consumer}/app/auth/*" ], "attributes": { "saml.authnstatement": "true", @@ -26,18 +26,18 @@ "saml.signature.algorithm": "RSA_SHA512", "saml.signing.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g==", "saml.signing.private.key": "MIICXQIBAAKBgQDb7kwJPkGdU34hicplwfp6/WmNcaLh94TSc7Jyr9Undp5pkyLgb0DE7EIE+6kSs4LsqCb8HDkB0nLD5DXbBJFd8n0WGoKstelvtg6FtVJMnwN7k7yZbfkPECWH9zF70VeOo9vbzrApNRnct8ZhH5fbflRB4JMA9L9R+LbURdoSKQIDAQABAoGBANtbZG9bruoSGp2s5zhzLzd4hczT6Jfk3o9hYjzNb5Z60ymN3Z1omXtQAdEiiNHkRdNxK+EM7TcKBfmoJqcaeTkW8cksVEAW23ip8W9/XsLqmbU2mRrJiKa+KQNDSHqJi1VGyimi4DDApcaqRZcaKDFXg2KDr/Qt5JFD/o9IIIPZAkEA+ZENdBIlpbUfkJh6Ln+bUTss/FZ1FsrcPZWu13rChRMrsmXsfzu9kZUWdUeQ2Dj5AoW2Q7L/cqdGXS7Mm5XhcwJBAOGZq9axJY5YhKrsksvYRLhQbStmGu5LG75suF+rc/44sFq+aQM7+oeRr4VY88Mvz7mk4esdfnk7ae+cCazqJvMCQQCx1L1cZw3yfRSn6S6u8XjQMjWE/WpjulujeoRiwPPY9WcesOgLZZtYIH8nRL6ehEJTnMnahbLmlPFbttxPRUanAkA11MtSIVcKzkhp2KV2ipZrPJWwI18NuVJXb+3WtjypTrGWFZVNNkSjkLnHIeCYlJIGhDd8OL9zAiBXEm6kmgLNAkBWAg0tK2hCjvzsaA505gWQb4X56uKWdb0IzN+fOLB3Qt7+fLqbVQNQoNGzqey6B4MoS1fUKAStqdGTFYPG/+9t", - "saml_assertion_consumer_url_post" : "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth", + "saml_assertion_consumer_url_post" : "${url.realm.consumer}/app/auth", "saml_idp_initiated_sso_url_name" : "sales" }, - "baseUrl": "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth", - "adminUrl": "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth" + "baseUrl": "${url.realm.consumer}/app/auth", + "adminUrl": "${url.realm.consumer}/app/auth" }, { - "clientId": "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth2", + "clientId": "${url.realm.consumer}/app/auth2", "enabled": true, "protocol": "saml", "fullScopeAllowed": true, "redirectUris": [ - "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth2/*" + "${url.realm.consumer}/app/auth2/*" ], "attributes": { "saml.authnstatement": "true", @@ -47,11 +47,11 @@ "saml.signature.algorithm": "RSA_SHA512", "saml.signing.certificate": "MIIB1DCCAT0CBgFJGVacCDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1lbmMvMB4XDTE0MTAxNjE0MjA0NloXDTI0MTAxNjE0MjIyNlowMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3QtZW5jLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2+5MCT5BnVN+IYnKZcH6ev1pjXGi4feE0nOycq/VJ3aeaZMi4G9AxOxCBPupErOC7Kgm/Bw5AdJyw+Q12wSRXfJ9FhqCrLXpb7YOhbVSTJ8De5O8mW35DxAlh/cxe9FXjqPb286wKTUZ3LfGYR+X235UQeCTAPS/Ufi21EXaEikCAwEAATANBgkqhkiG9w0BAQsFAAOBgQBMrfGD9QFfx5v7ld/OAto5rjkTe3R1Qei8XRXfcs83vLaqEzjEtTuLGrJEi55kXuJgBpVmQpnwCCkkjSy0JxbqLDdVi9arfWUxEGmOr01ZHycELhDNaQcFqVMPr5kRHIHgktT8hK2IgCvd3Fy9/JCgUgCPxKfhwecyEOKxUc857g==", "saml.signing.private.key": "MIICXQIBAAKBgQDb7kwJPkGdU34hicplwfp6/WmNcaLh94TSc7Jyr9Undp5pkyLgb0DE7EIE+6kSs4LsqCb8HDkB0nLD5DXbBJFd8n0WGoKstelvtg6FtVJMnwN7k7yZbfkPECWH9zF70VeOo9vbzrApNRnct8ZhH5fbflRB4JMA9L9R+LbURdoSKQIDAQABAoGBANtbZG9bruoSGp2s5zhzLzd4hczT6Jfk3o9hYjzNb5Z60ymN3Z1omXtQAdEiiNHkRdNxK+EM7TcKBfmoJqcaeTkW8cksVEAW23ip8W9/XsLqmbU2mRrJiKa+KQNDSHqJi1VGyimi4DDApcaqRZcaKDFXg2KDr/Qt5JFD/o9IIIPZAkEA+ZENdBIlpbUfkJh6Ln+bUTss/FZ1FsrcPZWu13rChRMrsmXsfzu9kZUWdUeQ2Dj5AoW2Q7L/cqdGXS7Mm5XhcwJBAOGZq9axJY5YhKrsksvYRLhQbStmGu5LG75suF+rc/44sFq+aQM7+oeRr4VY88Mvz7mk4esdfnk7ae+cCazqJvMCQQCx1L1cZw3yfRSn6S6u8XjQMjWE/WpjulujeoRiwPPY9WcesOgLZZtYIH8nRL6ehEJTnMnahbLmlPFbttxPRUanAkA11MtSIVcKzkhp2KV2ipZrPJWwI18NuVJXb+3WtjypTrGWFZVNNkSjkLnHIeCYlJIGhDd8OL9zAiBXEm6kmgLNAkBWAg0tK2hCjvzsaA505gWQb4X56uKWdb0IzN+fOLB3Qt7+fLqbVQNQoNGzqey6B4MoS1fUKAStqdGTFYPG/+9t", - "saml_assertion_consumer_url_post" : "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth2/saml", + "saml_assertion_consumer_url_post" : "${url.realm.consumer}/app/auth2/saml", "saml_idp_initiated_sso_url_name" : "sales2" }, - "baseUrl": "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth2", - "adminUrl": "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth2" + "baseUrl": "${url.realm.consumer}/app/auth2", + "adminUrl": "${url.realm.consumer}/app/auth2" } ], "identityProviders" : [ { "alias" : "saml-leaf", @@ -79,7 +79,7 @@ "identityProviderMapper" : "saml-role-idp-mapper", "config" : { "attribute.value" : "manager", - "role" : "http://localhost:8180/auth/realms/${name.realm.consumer}/app/auth.manager", + "role" : "${url.realm.consumer}/app/auth.manager", "attribute.name" : "Role" } } ] diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/testcomposite.json b/testsuite/integration-arquillian/tests/base/src/test/resources/testcomposite.json index e7819e6d81..6ffe87fd06 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/testcomposite.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/testcomposite.json @@ -93,7 +93,8 @@ "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/*" + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" ], "secret": "password" }, @@ -104,7 +105,8 @@ "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/*" + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" ], "secret": "password" }, @@ -115,7 +117,8 @@ "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/*" + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" ], "secret": "password" }, @@ -126,7 +129,8 @@ "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/*" + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" ], "secret": "password" } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm-duplicate-emails.json b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm-duplicate-emails.json index 560c1d297d..07d7207f4a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm-duplicate-emails.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm-duplicate-emails.json @@ -79,7 +79,8 @@ "enabled": true, "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/auth/*" + "http://localhost:8180/auth/realms/master/app/auth/*", + "https://localhost:8543/auth/realms/master/app/auth/*" ], "adminUrl": "http://localhost:8180/auth/realms/master/app/admin", "secret": "password" diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json index 81239fa2f1..150fd17474 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/testrealm.json @@ -142,7 +142,8 @@ "enabled": true, "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/auth/*" + "http://localhost:8180/auth/realms/master/app/auth/*", + "https://localhost:8543/auth/realms/master/app/auth/*" ], "adminUrl": "http://localhost:8180/auth/realms/master/app/admin", "secret": "password" @@ -154,7 +155,8 @@ "adminUrl": "http://localhost:8180/foo/bar", "baseUrl": "/baz", "redirectUris": [ - "http://localhost:8180/foo/bar/*" + "http://localhost:8180/foo/bar/*", + "https://localhost:8543/foo/bar/*" ], "secret": "password" }, @@ -163,7 +165,8 @@ "enabled": true, "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/*" + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" ], "secret": "password", "fullScopeAllowed": "false" @@ -175,7 +178,8 @@ "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", "redirectUris": [ - "http://localhost:8180/auth/realms/master/app/*" + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" ], "secret": "password" }, @@ -343,7 +347,8 @@ "enabled": true, "baseUrl": "http://localhost:8180/namedapp/base", "redirectUris": [ - "http://localhost:8180/namedapp/base/*" + "http://localhost:8180/namedapp/base/*", + "https://localhost:8543/namedapp/base/*" ], "adminUrl": "http://localhost:8180/namedapp/base/admin", "secret": "password" @@ -354,7 +359,8 @@ "enabled": true, "baseUrl": "http://localhost:8180/varnamedapp/base", "redirectUris": [ - "http://localhost:8180/varnamedapp/base/*" + "http://localhost:8180/varnamedapp/base/*", + "https://localhost:8543/varnamedapp/base/*" ], "adminUrl": "http://localhost:8180/varnamedapp/base/admin", "secret": "password" diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index 423e0d9fff..336a59fcc1 100755 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -63,8 +63,8 @@ 8543 10090 10099 - false - -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m + true + -Xms64m -Xmx512m serverConfig org.jboss.as.arquillian.container.managed.ManagedDeployableContainer ${jboss.home.dir}/standalone/configuration/keycloak.truststore diff --git a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/arquillian/DeploymentArchiveProcessorUtils.java b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/arquillian/DeploymentArchiveProcessorUtils.java index 0affad501e..1f4289e6b0 100644 --- a/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/arquillian/DeploymentArchiveProcessorUtils.java +++ b/testsuite/integration-arquillian/util/src/main/java/org/keycloak/testsuite/utils/arquillian/DeploymentArchiveProcessorUtils.java @@ -58,6 +58,7 @@ public class DeploymentArchiveProcessorUtils { public static final String JBOSS_DEPLOYMENT_XML_PATH = "/WEB-INF/jboss-deployment-structure.xml"; public static final String SAML_ADAPTER_CONFIG_PATH_TENANT1 = "/WEB-INF/classes/tenant1-keycloak-saml.xml"; public static final String SAML_ADAPTER_CONFIG_PATH_TENANT2 = "/WEB-INF/classes/tenant2-keycloak-saml.xml"; + public static final String TRUSTSTORE_PASSWORD = "secret"; /** * @return true iff archive's name equals run-on-server-classes.war @@ -195,6 +196,19 @@ public class DeploymentArchiveProcessorUtils { adapterConfig.setSslRequired("all"); } + if (AUTH_SERVER_SSL_REQUIRED) { + String trustStorePathInDeployment = "keycloak.truststore"; + if (adapterConfigPath.contains("WEB-INF")) { + // This is a Java adapter, we can use classpath + trustStorePathInDeployment = "classpath:keycloak.truststore"; + } + adapterConfig.setTruststore(trustStorePathInDeployment); + adapterConfig.setTruststorePassword(TRUSTSTORE_PASSWORD); + File truststorePath = new File(DeploymentArchiveProcessorUtils.class.getResource("/keystore/keycloak.truststore").getFile()); + ((WebArchive) archive).addAsResource(truststorePath); + log.debugf("Adding Truststore to the deployment, path %s, password %s, adapter path %s", truststorePath.getAbsolutePath(), TRUSTSTORE_PASSWORD, trustStorePathInDeployment); + } + archive.add(new StringAsset(JsonSerialization.writeValueAsPrettyString(adapterConfig)), adapterConfigPath); } catch (IOException ex) { @@ -208,20 +222,24 @@ public class DeploymentArchiveProcessorUtils { if (AUTH_SERVER_SSL_REQUIRED) { IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "8080", System.getProperty("auth.server.https.port")); IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "http", "https"); - IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "assertionConsumerServiceUrl", "8080", System.getProperty("app.server.https.port")); - IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "assertionConsumerServiceUrl", "http", "https"); IOUtil.modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "8080", System.getProperty("auth.server.https.port")); IOUtil.modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "http", "https"); IOUtil.modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "8080", System.getProperty("auth.server.https.port")); IOUtil.modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "http", "https"); - IOUtil.modifyDocElementAttribute(doc, "SP", "logoutPage", "8080", System.getProperty("app.server.https.port")); - IOUtil.modifyDocElementAttribute(doc, "SP", "logoutPage", "http", "https"); } else { IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "bindingUrl", "8080", System.getProperty("auth.server.http.port")); - IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "assertionConsumerServiceUrl", "8080", System.getProperty("app.server.http.port")); IOUtil.modifyDocElementAttribute(doc, "SingleLogoutService", "postBindingUrl", "8080", System.getProperty("auth.server.http.port")); IOUtil.modifyDocElementAttribute(doc, "SingleLogoutService", "redirectBindingUrl", "8080", System.getProperty("auth.server.http.port")); + } + + if (APP_SERVER_SSL_REQUIRED) { + IOUtil.modifyDocElementAttribute(doc, "SP", "logoutPage", "8080", System.getProperty("app.server.https.port")); + IOUtil.modifyDocElementAttribute(doc, "SP", "logoutPage", "http", "https"); + IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "assertionConsumerServiceUrl", "8080", System.getProperty("app.server.https.port")); + IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "assertionConsumerServiceUrl", "http", "https"); + } else { IOUtil.modifyDocElementAttribute(doc, "SP", "logoutPage", "8080", System.getProperty("app.server.http.port")); + IOUtil.modifyDocElementAttribute(doc, "SingleSignOnService", "assertionConsumerServiceUrl", "8080", System.getProperty("app.server.http.port")); } archive.add(new StringAsset(IOUtil.documentToString(doc)), adapterConfigPath); diff --git a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/ApplicationServlet.java b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/ApplicationServlet.java index 3e2f151af7..e115604297 100755 --- a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/ApplicationServlet.java +++ b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/ApplicationServlet.java @@ -46,7 +46,7 @@ public class ApplicationServlet extends HttpServlet { PrintWriter pw = resp.getWriter(); pw.printf("%s", title); - UriBuilder base = UriBuilder.fromUri("http://localhost:8081/auth"); + UriBuilder base = UriBuilder.fromUri("/auth"); pw.printf(LINK, RealmsResource.accountUrl(base).build("test"), "account", "account"); pw.print(""); diff --git a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/helper/adapter/SamlAdapterTestStrategy.java b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/helper/adapter/SamlAdapterTestStrategy.java index 6db964a94d..55aa991966 100755 --- a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/helper/adapter/SamlAdapterTestStrategy.java +++ b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/helper/adapter/SamlAdapterTestStrategy.java @@ -657,7 +657,7 @@ public class SamlAdapterTestStrategy extends ExternalResource { public static void uploadSP(String AUTH_SERVER_URL) { try { - Keycloak keycloak = Keycloak.getInstance(AUTH_SERVER_URL, "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID, null); + Keycloak keycloak = Keycloak.getInstance(AUTH_SERVER_URL, "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID, (String) null); RealmResource admin = keycloak.realm("demo"); admin.toRepresentation(); diff --git a/travis-run-tests.sh b/travis-run-tests.sh index 6d07a8e68e..b463bc6e0e 100755 --- a/travis-run-tests.sh +++ b/travis-run-tests.sh @@ -102,8 +102,4 @@ if [ $1 == "crossdc-adapter" ]; then mvn clean test -B -nsu -Pcache-server-infinispan,auth-servers-crossdc-jboss,auth-server-wildfly,app-server-wildfly -Dtest=org.keycloak.testsuite.adapter.**.crossdc.**.* 2>&1 | java -cp ../../../utils/target/classes org.keycloak.testsuite.LogTrimmer exit ${PIPESTATUS[0]} -fi - -if [ $1 == "ssl" ]; then - run-server-tests org.keycloak.testsuite.client.MutualTLSClientTest,org.keycloak.testsuite.hok.HoKTest "-Dauth.server.ssl.required -Dbrowser=phantomjs" fi \ No newline at end of file