keycloak-uncached

Details

diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenLoginModule.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenLoginModule.java
old mode 100644
new mode 100755
index d35564a..965f2b4
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenLoginModule.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenLoginModule.java
@@ -1,11 +1,8 @@
 package org.keycloak.adapters;
 
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.Serializable;
 import java.security.Principal;
-import java.security.PublicKey;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -23,10 +20,8 @@ import javax.security.auth.spi.LoginModule;
 import org.keycloak.KeycloakPrincipal;
 import org.keycloak.RSATokenVerifier;
 import org.keycloak.VerificationException;
-import org.keycloak.constants.GenericConstants;
 import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.adapters.config.AdapterConfig;
-import org.keycloak.util.PemUtils;
 
 /**
  * Login module, which allows to authenticate Keycloak access token in environments, which rely on JAAS
@@ -103,30 +98,7 @@ public class BearerTokenLoginModule implements LoginModule {
     }
 
     protected InputStream loadKeycloakConfigFile(String keycloakConfigFile) {
-        if (keycloakConfigFile.startsWith(GenericConstants.PROTOCOL_CLASSPATH)) {
-            String classPathLocation = keycloakConfigFile.replace(GenericConstants.PROTOCOL_CLASSPATH, "");
-            log.info("Loading config from classpath on location: " + classPathLocation);
-            // Try current class classloader first
-            InputStream is = getClass().getClassLoader().getResourceAsStream(classPathLocation);
-            if (is == null) {
-                is = Thread.currentThread().getContextClassLoader().getResourceAsStream(classPathLocation);
-            }
-
-            if (is != null) {
-                return is;
-            } else {
-                throw new RuntimeException("Unable to find config from classpath: " + keycloakConfigFile);
-            }
-        } else {
-            // Fallback to file
-            try {
-                log.info("Loading config from file: " + keycloakConfigFile);
-                return new FileInputStream(keycloakConfigFile);
-            } catch (FileNotFoundException fnfe) {
-                log.severe("Config not found on " + keycloakConfigFile);
-                throw new RuntimeException(fnfe);
-            }
-        }
+        return FindFile.findFile(keycloakConfigFile);
     }
 
     @Override
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/FindFile.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/FindFile.java
new file mode 100755
index 0000000..19d8f83
--- /dev/null
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/FindFile.java
@@ -0,0 +1,37 @@
+package org.keycloak.adapters;
+
+import org.keycloak.constants.GenericConstants;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class FindFile {
+    public static InputStream findFile(String keycloakConfigFile) {
+        if (keycloakConfigFile.startsWith(GenericConstants.PROTOCOL_CLASSPATH)) {
+            String classPathLocation = keycloakConfigFile.replace(GenericConstants.PROTOCOL_CLASSPATH, "");
+            // Try current class classloader first
+            InputStream is = FindFile.class.getClassLoader().getResourceAsStream(classPathLocation);
+            if (is == null) {
+                is = Thread.currentThread().getContextClassLoader().getResourceAsStream(classPathLocation);
+            }
+
+            if (is != null) {
+                return is;
+            } else {
+                throw new RuntimeException("Unable to find config from classpath: " + keycloakConfigFile);
+            }
+        } else {
+            // Fallback to file
+            try {
+                return new FileInputStream(keycloakConfigFile);
+            } catch (FileNotFoundException fnfe) {
+                throw new RuntimeException(fnfe);
+            }
+        }
+    }
+}
diff --git a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyConfig.java b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyConfig.java
new file mode 100755
index 0000000..66b7f52
--- /dev/null
+++ b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyConfig.java
@@ -0,0 +1,262 @@
+package org.keycloak.proxy;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.keycloak.representations.adapters.config.AdapterConfig;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class ProxyConfig {
+    @JsonProperty("bind-address")
+    protected String bindAddress = "localhost";
+    @JsonProperty("http-port")
+    protected Integer httpPort;
+    @JsonProperty("https-port")
+    protected Integer httpsPort;
+    @JsonProperty("keystore")
+    protected String keystore;
+    @JsonProperty("keystore-password")
+    protected String keystorePassword;
+    @JsonProperty("key-password")
+    protected String keyPassword;
+    @JsonProperty("buffer-size")
+    protected Integer bufferSize;
+    @JsonProperty("buffers-per-region")
+    protected Integer buffersPerRegion;
+    @JsonProperty("io-threads")
+    protected Integer ioThreads;
+    @JsonProperty("worker-threads")
+    protected Integer workerThreads;
+    @JsonProperty("direct-buffers")
+    protected Boolean directBuffers;
+    @JsonProperty("target-url")
+    protected String targetUrl;
+    @JsonProperty("applications")
+    protected List<Application> applications = new LinkedList<Application>();
+
+    public String getBindAddress() {
+        return bindAddress;
+    }
+
+    public void setBindAddress(String bindAddress) {
+        this.bindAddress = bindAddress;
+    }
+
+    public Integer getHttpPort() {
+        return httpPort;
+    }
+
+    public void setHttpPort(Integer httpPort) {
+        this.httpPort = httpPort;
+    }
+
+    public Integer getHttpsPort() {
+        return httpsPort;
+    }
+
+    public void setHttpsPort(Integer httpsPort) {
+        this.httpsPort = httpsPort;
+    }
+
+    public String getKeystore() {
+        return keystore;
+    }
+
+    public void setKeystore(String keystore) {
+        this.keystore = keystore;
+    }
+
+    public String getKeystorePassword() {
+        return keystorePassword;
+    }
+
+    public void setKeystorePassword(String keystorePassword) {
+        this.keystorePassword = keystorePassword;
+    }
+
+    public String getKeyPassword() {
+        return keyPassword;
+    }
+
+    public void setKeyPassword(String keyPassword) {
+        this.keyPassword = keyPassword;
+    }
+
+    public Integer getBufferSize() {
+        return bufferSize;
+    }
+
+    public void setBufferSize(Integer bufferSize) {
+        this.bufferSize = bufferSize;
+    }
+
+    public Integer getBuffersPerRegion() {
+        return buffersPerRegion;
+    }
+
+    public void setBuffersPerRegion(Integer buffersPerRegion) {
+        this.buffersPerRegion = buffersPerRegion;
+    }
+
+    public Integer getIoThreads() {
+        return ioThreads;
+    }
+
+    public void setIoThreads(Integer ioThreads) {
+        this.ioThreads = ioThreads;
+    }
+
+    public Integer getWorkerThreads() {
+        return workerThreads;
+    }
+
+    public void setWorkerThreads(Integer workerThreads) {
+        this.workerThreads = workerThreads;
+    }
+
+    public Boolean getDirectBuffers() {
+        return directBuffers;
+    }
+
+    public void setDirectBuffers(Boolean directBuffers) {
+        this.directBuffers = directBuffers;
+    }
+
+    public String getTargetUrl() {
+        return targetUrl;
+    }
+
+    public void setTargetUrl(String targetUrl) {
+        this.targetUrl = targetUrl;
+    }
+
+    public List<Application> getApplications() {
+        return applications;
+    }
+
+    public void setApplications(List<Application> applications) {
+        this.applications = applications;
+    }
+
+    public static class Application {
+        @JsonProperty("base-path")
+        protected String basePath;
+        @JsonProperty("adapter-config")
+        protected AdapterConfig adapterConfig;
+        @JsonProperty("error-page")
+        protected String errorPage;
+        @JsonProperty("constraints")
+        protected List<Constraint> constraints = new LinkedList<Constraint>();
+
+        public String getBasePath() {
+            return basePath;
+        }
+
+        public void setBasePath(String basePath) {
+            this.basePath = basePath;
+        }
+
+        public AdapterConfig getAdapterConfig() {
+            return adapterConfig;
+        }
+
+        public void setAdapterConfig(AdapterConfig adapterConfig) {
+            this.adapterConfig = adapterConfig;
+        }
+
+        public String getErrorPage() {
+            return errorPage;
+        }
+
+        public void setErrorPage(String errorPage) {
+            this.errorPage = errorPage;
+        }
+
+        public List<Constraint> getConstraints() {
+            return constraints;
+        }
+
+        public void setConstraints(List<Constraint> constraints) {
+            this.constraints = constraints;
+        }
+    }
+
+    public static class Constraint {
+        @JsonProperty("pattern")
+        protected String pattern;
+        @JsonProperty("roles-allowed")
+        protected Set<String> rolesAllowed = new HashSet<String>();
+        @JsonProperty("methods")
+        protected Set<String> methods = new HashSet<String>();
+        @JsonProperty("excluded-methods")
+        protected Set<String> excludedMethods = new HashSet<String>();
+        @JsonProperty("deny")
+        protected boolean deny;
+        @JsonProperty("permit")
+        protected boolean permit;
+        @JsonProperty("authenticate")
+        protected boolean authenticate;
+
+        public String getPattern() {
+            return pattern;
+        }
+
+        public void setPattern(String pattern) {
+            this.pattern = pattern;
+        }
+
+        public Set<String> getRolesAllowed() {
+            return rolesAllowed;
+        }
+
+        public void setRolesAllowed(Set<String> rolesAllowed) {
+            this.rolesAllowed = rolesAllowed;
+        }
+
+        public boolean isDeny() {
+            return deny;
+        }
+
+        public void setDeny(boolean deny) {
+            this.deny = deny;
+        }
+
+        public boolean isPermit() {
+            return permit;
+        }
+
+        public void setPermit(boolean permit) {
+            this.permit = permit;
+        }
+
+        public boolean isAuthenticate() {
+            return authenticate;
+        }
+
+        public void setAuthenticate(boolean authenticate) {
+            this.authenticate = authenticate;
+        }
+
+        public Set<String> getMethods() {
+            return methods;
+        }
+
+        public void setMethods(Set<String> methods) {
+            this.methods = methods;
+        }
+
+        public Set<String> getExcludedMethods() {
+            return excludedMethods;
+        }
+
+        public void setExcludedMethods(Set<String> excludedMethods) {
+            this.excludedMethods = excludedMethods;
+        }
+    }
+}
diff --git a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java
index 16b8778..3e03c3b 100755
--- a/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java
+++ b/proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyServerBuilder.java
@@ -20,7 +20,11 @@ import io.undertow.server.session.InMemorySessionManager;
 import io.undertow.server.session.SessionAttachmentHandler;
 import io.undertow.server.session.SessionCookieConfig;
 import io.undertow.server.session.SessionManager;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.jboss.logging.Logger;
 import org.keycloak.adapters.AdapterDeploymentContext;
+import org.keycloak.adapters.FindFile;
 import org.keycloak.adapters.KeycloakDeployment;
 import org.keycloak.adapters.KeycloakDeploymentBuilder;
 import org.keycloak.adapters.NodesRegistrationManagement;
@@ -30,13 +34,25 @@ import org.keycloak.adapters.undertow.UndertowPreAuthActionsHandler;
 import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
 import org.keycloak.enums.SslRequired;
 import org.keycloak.representations.adapters.config.AdapterConfig;
+import org.keycloak.util.CertificateUtils;
+import org.keycloak.util.PemUtils;
+import org.keycloak.util.SystemPropertiesJsonParserFactory;
 import org.xnio.Option;
 
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
+import java.io.IOException;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -47,6 +63,7 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class ProxyServerBuilder {
+    protected static Logger log = Logger.getLogger(ProxyServerBuilder.class);
     public static final HttpHandler NOT_FOUND = new HttpHandler() {
         @Override
         public void handleRequest(HttpServerExchange exchange) throws Exception {
@@ -148,6 +165,16 @@ public class ProxyServerBuilder {
                 return this;
             }
 
+            public ConstraintBuilder excludedMethods(Set<String> excludedMethods) {
+                this.excludedMethods = excludedMethods;
+                return this;
+            }
+
+            public ConstraintBuilder methods(Set<String> methods) {
+                this.methods = methods;
+                return this;
+            }
+
             public ConstraintBuilder method(String method) {
                 methods.add(method);
                 return this;
@@ -163,6 +190,10 @@ public class ProxyServerBuilder {
                 for (String role : roles) role(role);
                 return this;
             }
+            public ConstraintBuilder roles(Set<String> roles) {
+                for (String role : roles) role(role);
+                return this;
+            }
 
             public ConstraintBuilder role(String role) {
                 rolesAllowed.add(role);
@@ -272,11 +303,6 @@ public class ProxyServerBuilder {
         return this;
     }
 
-    public ProxyServerBuilder setHandler(HttpHandler handler) {
-        builder.setHandler(handler);
-        return this;
-    }
-
     public <T> ProxyServerBuilder setServerOption(Option<T> option, T value) {
         builder.setServerOption(option, value);
         return this;
@@ -291,4 +317,127 @@ public class ProxyServerBuilder {
         builder.setWorkerOption(option, value);
         return this;
     }
+
+    public static ProxyConfig loadConfig(InputStream is) {
+        ObjectMapper mapper = new ObjectMapper(new SystemPropertiesJsonParserFactory());
+        mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_DEFAULT);
+        ProxyConfig proxyConfig;
+        try {
+            proxyConfig = mapper.readValue(is, ProxyConfig.class);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return proxyConfig;
+    }
+    public static Undertow build(InputStream configStream) {
+        ProxyConfig config = loadConfig(configStream);
+        return build(config);
+
+    }
+
+    public static Undertow build(ProxyConfig config) {
+        ProxyServerBuilder builder = new ProxyServerBuilder();
+        if (config.getTargetUrl() == null) {
+            log.error("Must set Target URL");
+            return null;
+        }
+        builder.target(config.getTargetUrl());
+        if (config.getApplications() == null || config.getApplications().size() == 0) {
+            log.error("No applications defined");
+            return null;
+        }
+        initConnections(config, builder);
+        initOptions(config, builder);
+
+        for (ProxyConfig.Application application : config.getApplications()) {
+            ApplicationBuilder applicationBuilder = builder.application(application.getAdapterConfig())
+                    .base(application.getBasePath())
+                    .errorPage(application.getErrorPage());
+
+            if (application.getConstraints() != null) {
+                for (ProxyConfig.Constraint constraint : application.getConstraints()) {
+                    ApplicationBuilder.ConstraintBuilder constraintBuilder = applicationBuilder.constraint(constraint.getPattern());
+                    if (constraint.getRolesAllowed() != null) {
+                        constraintBuilder.roles(constraint.getRolesAllowed());
+                    }
+                    if (constraint.getMethods() != null) {
+                        constraintBuilder.methods(constraint.getMethods());
+                    }
+                    if (constraint.getExcludedMethods() != null) {
+                        constraintBuilder.excludedMethods(constraint.getExcludedMethods());
+                    }
+                    if (constraint.isDeny()) constraintBuilder.deny();
+                    if (constraint.isPermit()) constraintBuilder.permit();
+                    if (constraint.isAuthenticate()) constraintBuilder.authenticate();
+                    constraintBuilder.add();
+                }
+            }
+            applicationBuilder.add();
+        }
+        return builder.build();
+    }
+
+    public static void initOptions(ProxyConfig config, ProxyServerBuilder builder) {
+        if (config.getBufferSize() != null) builder.setBufferSize(config.getBufferSize());
+        if (config.getBuffersPerRegion() != null) builder.setBuffersPerRegion(config.getBuffersPerRegion());
+        if (config.getIoThreads() != null) builder.setIoThreads(config.getIoThreads());
+        if (config.getWorkerThreads() != null) builder.setWorkerThreads(config.getWorkerThreads());
+        if (config.getDirectBuffers() != null) builder.setDirectBuffers(config.getDirectBuffers());
+    }
+
+    public static void initConnections(ProxyConfig config, ProxyServerBuilder builder) {
+        if (config.getHttpPort() == null && config.getHttpsPort() == null) {
+            log.warn("You have not set up HTTP or HTTPS");
+        }
+        if (config.getHttpPort() != null) {
+            String bindAddress = "localhost";
+            if (config.getBindAddress() != null) bindAddress = config.getBindAddress();
+            builder.addHttpListener(config.getHttpPort(), bindAddress);
+        }
+        if (config.getHttpsPort() != null) {
+            String bindAddress = "localhost";
+            if (config.getBindAddress() != null) bindAddress = config.getBindAddress();
+            if (config.getKeystore() != null) {
+                InputStream is = FindFile.findFile(config.getKeystore());
+                SSLContext sslContext = null;
+                try {
+                    KeyStore keystore = KeyStore.getInstance("jks");
+                    keystore.load(is, config.getKeystorePassword().toCharArray());
+                    sslContext = SslUtil.createSSLContext(keystore, config.getKeyPassword(), null);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                builder.addHttpsListener(config.getHttpsPort().intValue(), bindAddress, sslContext);
+            } else {
+                log.warn("Generating temporary SSL cert");
+                KeyPair keyPair = null;
+                try {
+                    keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
+                } catch (NoSuchAlgorithmException e) {
+                    throw new RuntimeException(e);
+                }
+                X509Certificate certificate = null;
+                try {
+                    certificate = CertificateUtils.generateV1SelfSignedCertificate(keyPair, bindAddress);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+
+                try {
+                    KeyStore keyStore = KeyStore.getInstance("JKS");
+                    keyStore.load(null, null);
+                    PrivateKey privateKey = keyPair.getPrivate();
+
+
+                    Certificate[] chain =  {certificate};
+
+                    keyStore.setKeyEntry(bindAddress, privateKey, "password".toCharArray(), chain);
+                    SSLContext sslContext = SslUtil.createSSLContext(keyStore, "password", null);
+                    builder.addHttpsListener(config.getHttpsPort().intValue(), bindAddress, sslContext);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
 }
diff --git a/proxy/proxy-server/src/main/java/org/keycloak/proxy/SslUtil.java b/proxy/proxy-server/src/main/java/org/keycloak/proxy/SslUtil.java
new file mode 100755
index 0000000..8cc1bc1
--- /dev/null
+++ b/proxy/proxy-server/src/main/java/org/keycloak/proxy/SslUtil.java
@@ -0,0 +1,36 @@
+package org.keycloak.proxy;
+
+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 java.security.KeyStore;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class SslUtil {
+    public static SSLContext createSSLContext(final KeyStore keyStore, String password, final KeyStore trustStore) throws Exception {
+        KeyManager[] keyManagers;
+        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        keyManagerFactory.init(keyStore, password.toCharArray());
+        keyManagers = keyManagerFactory.getKeyManagers();
+
+        TrustManager[] trustManagers = null;
+        if (trustStore != null) {
+            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+            trustManagerFactory.init(trustStore);
+            trustManagers = trustManagerFactory.getTrustManagers();
+        }
+
+        SSLContext sslContext;
+        sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(keyManagers, trustManagers, null);
+
+        return sslContext;
+    }
+
+
+}
diff --git a/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java b/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java
index 511e02d..0c27c20 100755
--- a/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java
+++ b/testsuite/proxy/src/test/java/org/keycloak/testsuite/ProxyTest.java
@@ -83,7 +83,7 @@ public class ProxyTest {
     public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
         @Override
         protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
-            RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/tomcat-test/demorealm.json"), RealmRepresentation.class);
+            RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/demorealm.json"), RealmRepresentation.class);
             RealmModel realm = manager.importRealm(representation);
        }
     };
@@ -148,8 +148,9 @@ public class ProxyTest {
     @BeforeClass
     public static void initProxy() throws Exception {
         initTomcat();
+        InputStream is = ProxyTest.class.getResourceAsStream("/proxy-config.json");
+        /*
         ProxyServerBuilder builder = new ProxyServerBuilder().addHttpListener(8080, "localhost");
-        InputStream is = ProxyTest.class.getResourceAsStream("/keycloak.json");
         AdapterConfig config = KeycloakDeploymentBuilder.loadAdapterConfig(is);
 
         builder.target("http://localhost:8082")
@@ -161,7 +162,8 @@ public class ProxyTest {
                     .constraint("/users/permit").permit().add()
                     .constraint("/users/deny").deny().add()
                 .add();
-        proxyServer = builder.build();
+                */
+        proxyServer = ProxyServerBuilder.build(is);
         proxyServer.start();
 
     }
@@ -183,68 +185,74 @@ public class ProxyTest {
     public static final String LOGIN_URL = OpenIDConnectService.loginPageUrl(UriBuilder.fromUri("http://localhost:8081/auth")).build("demo").toString();
 
     @Test
-    public void testLoginSSOAndLogout() throws Exception {
-        driver.navigate().to("http://localhost:8080/customer-portal/users");
+    public void testHttp() throws Exception {
+        String baseUrl = "http://localhost:8080";
+        testit(baseUrl);
+
+
+    }
+
+    @Test
+    public void testHttps() throws Exception {
+        String baseUrl = "https://localhost:8443";
+        testit(baseUrl);
+
+
+    }
+
+    public void testit(String baseUrl) {
+        driver.navigate().to(baseUrl + "/customer-portal/users");
         System.out.println("Current url: " + driver.getCurrentUrl());
         Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
+        String loginPageSource = driver.getPageSource();
         loginPage.login("bburke@redhat.com", "password");
         System.out.println("Current url: " + driver.getCurrentUrl());
-        Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8080/customer-portal/users");
+        Assert.assertEquals(driver.getCurrentUrl(), baseUrl + "/customer-portal/users");
         String pageSource = driver.getPageSource();
         System.out.println(pageSource);
         Assert.assertTrue(pageSource.contains("customer-portal/users"));
         Assert.assertTrue(pageSource.contains("count:0"));
-        driver.navigate().to("http://localhost:8080/customer-portal/users");
-        Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8080/customer-portal/users");
+        driver.navigate().to(baseUrl + "/customer-portal/users");
+        Assert.assertEquals(driver.getCurrentUrl(), baseUrl + "/customer-portal/users");
         pageSource = driver.getPageSource();
         System.out.println(pageSource);
         Assert.assertTrue(pageSource.contains("customer-portal/users"));
         Assert.assertTrue(pageSource.contains("count:1")); // test http session
 
-        driver.navigate().to("http://localhost:8080/customer-portal/users/deny");
-        Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8080/customer-portal/users/deny");
+        driver.navigate().to(baseUrl + "/customer-portal/users/deny");
+        Assert.assertEquals(driver.getCurrentUrl(), baseUrl + "/customer-portal/users/deny");
         pageSource = driver.getPageSource();
         System.out.println(pageSource);
         Assert.assertTrue(pageSource.contains("access error"));
 
-        driver.navigate().to("http://localhost:8080/customer-portal/admins");
-        Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8080/customer-portal/admins");
+        driver.navigate().to(baseUrl + "/customer-portal/admins");
+        Assert.assertEquals(driver.getCurrentUrl(), baseUrl + "/customer-portal/admins");
         pageSource = driver.getPageSource();
         System.out.println(pageSource);
         Assert.assertTrue(pageSource.contains("access error"));
 
 
-
         // test logout
 
         String logoutUri = OpenIDConnectService.logoutUrl(UriBuilder.fromUri("http://localhost:8081/auth"))
-                .queryParam(OAuth2Constants.REDIRECT_URI, "http://localhost:8080/customer-portal/users").build("demo").toString();
+                .queryParam(OAuth2Constants.REDIRECT_URI, baseUrl + "/customer-portal/users").build("demo").toString();
         driver.navigate().to(logoutUri);
         Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
-        driver.navigate().to("http://localhost:8080/customer-portal/users");
+        driver.navigate().to(baseUrl + "/customer-portal/users");
         String currentUrl = driver.getCurrentUrl();
         Assert.assertTrue(currentUrl.startsWith(LOGIN_URL));
 
         // test unsecured page
-        driver.navigate().to("http://localhost:8080/customer-portal") ;
+        driver.navigate().to(baseUrl + "/customer-portal") ;
         pageSource = driver.getPageSource();
         System.out.println(pageSource);
         Assert.assertTrue(pageSource.contains("customer-portal"));
-        driver.navigate().to("http://localhost:8080/customer-portal/users/permit") ;
+        driver.navigate().to(baseUrl + "/customer-portal/users/permit") ;
         pageSource = driver.getPageSource();
         System.out.println(pageSource);
         Assert.assertTrue(pageSource.contains("customer-portal/users/permit"));
-
-
     }
 
-    @Test
-    @Ignore
-    public void runit() throws Exception {
-        Thread.sleep(10000000);
-    }
-
-
     private static String getBaseDirectory() {
         String dirPath = null;
         String relativeDirPath = "testsuite" + File.separator + "proxy" + File.separator + "target";
diff --git a/testsuite/proxy/src/test/resources/proxy-config.json b/testsuite/proxy/src/test/resources/proxy-config.json
new file mode 100755
index 0000000..f26d8e3
--- /dev/null
+++ b/testsuite/proxy/src/test/resources/proxy-config.json
@@ -0,0 +1,48 @@
+{
+    "bind-address": "localhost",
+    "http-port": "8080",
+    "https-port": "8443",
+    "target-url": "http://localhost:8082",
+    "applications": [
+        {
+            "base-path": "/customer-portal",
+            "error-page": "/error.html",
+            "adapter-config": {
+                "realm": "demo",
+                "resource": "customer-portal",
+                "realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+                "auth-server-url": "http://localhost:8081/auth",
+                "ssl-required" : "external",
+                "principal-attribute": "name",
+                "credentials": {
+                    "secret": "password"
+                }
+            }
+            ,
+            "constraints": [
+                {
+                    "pattern": "/users/*",
+                    "roles-allowed": [
+                        "user"
+                    ]
+                },
+                {
+                    "pattern": "/admins/*",
+                    "roles-allowed": [
+                        "admin"
+                    ]
+                },
+                {
+                    "pattern": "/users/permit",
+                    "permit": true
+                },
+                {
+                    "pattern": "/users/deny",
+                    "deny": true
+                }
+            ]
+        }
+    ]
+
+
+}
\ No newline at end of file