From bc6e7c249bff9d660638fe979336ee36f94bf004 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Fri, 21 Nov 2014 18:44:39 -0500 Subject: [PATCH] proxy config 2 --- .../adapters/BearerTokenLoginModule.java | 30 +- .../java/org/keycloak/adapters/FindFile.java | 37 +++ .../java/org/keycloak/proxy/ProxyConfig.java | 262 ++++++++++++++++++ .../keycloak/proxy/ProxyServerBuilder.java | 159 ++++++++++- .../main/java/org/keycloak/proxy/SslUtil.java | 36 +++ .../org/keycloak/testsuite/ProxyTest.java | 122 ++++---- .../{tomcat-test => }/demorealm.json | 3 +- .../src/test/resources/proxy-config.json | 48 ++++ 8 files changed, 605 insertions(+), 92 deletions(-) mode change 100644 => 100755 integration/adapter-core/src/main/java/org/keycloak/adapters/BearerTokenLoginModule.java create mode 100755 integration/adapter-core/src/main/java/org/keycloak/adapters/FindFile.java create mode 100755 proxy/proxy-server/src/main/java/org/keycloak/proxy/ProxyConfig.java create mode 100755 proxy/proxy-server/src/main/java/org/keycloak/proxy/SslUtil.java rename testsuite/proxy/src/test/resources/{tomcat-test => }/demorealm.json (94%) create mode 100755 testsuite/proxy/src/test/resources/proxy-config.json 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 d35564a391..965f2b4a3e --- 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 0000000000..19d8f83df6 --- /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 Bill Burke + * @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 0000000000..66b7f520bf --- /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 Bill Burke + * @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 applications = new LinkedList(); + + 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 getApplications() { + return applications; + } + + public void setApplications(List 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 constraints = new LinkedList(); + + 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 getConstraints() { + return constraints; + } + + public void setConstraints(List constraints) { + this.constraints = constraints; + } + } + + public static class Constraint { + @JsonProperty("pattern") + protected String pattern; + @JsonProperty("roles-allowed") + protected Set rolesAllowed = new HashSet(); + @JsonProperty("methods") + protected Set methods = new HashSet(); + @JsonProperty("excluded-methods") + protected Set excludedMethods = new HashSet(); + @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 getRolesAllowed() { + return rolesAllowed; + } + + public void setRolesAllowed(Set 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 getMethods() { + return methods; + } + + public void setMethods(Set methods) { + this.methods = methods; + } + + public Set getExcludedMethods() { + return excludedMethods; + } + + public void setExcludedMethods(Set 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 16b8778d87..3e03c3b7a6 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 excludedMethods) { + this.excludedMethods = excludedMethods; + return this; + } + + public ConstraintBuilder methods(Set 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 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 ProxyServerBuilder setServerOption(Option 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 0000000000..8cc1bc1b44 --- /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 Bill Burke + * @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 511e02daef..0c27c20705 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,67 +185,73 @@ 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"); - System.out.println("Current url: " + driver.getCurrentUrl()); - Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL)); - loginPage.login("bburke@redhat.com", "password"); - System.out.println("Current url: " + driver.getCurrentUrl()); - Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8080/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"); - 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"); - 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"); - 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(); - driver.navigate().to(logoutUri); - Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL)); - driver.navigate().to("http://localhost:8080/customer-portal/users"); - String currentUrl = driver.getCurrentUrl(); - Assert.assertTrue(currentUrl.startsWith(LOGIN_URL)); - - // test unsecured page - driver.navigate().to("http://localhost:8080/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") ; - pageSource = driver.getPageSource(); - System.out.println(pageSource); - Assert.assertTrue(pageSource.contains("customer-portal/users/permit")); + public void testHttp() throws Exception { + String baseUrl = "http://localhost:8080"; + testit(baseUrl); } @Test - @Ignore - public void runit() throws Exception { - Thread.sleep(10000000); + 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(), 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(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(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(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, baseUrl + "/customer-portal/users").build("demo").toString(); + driver.navigate().to(logoutUri); + Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL)); + driver.navigate().to(baseUrl + "/customer-portal/users"); + String currentUrl = driver.getCurrentUrl(); + Assert.assertTrue(currentUrl.startsWith(LOGIN_URL)); + + // test unsecured page + driver.navigate().to(baseUrl + "/customer-portal") ; + pageSource = driver.getPageSource(); + System.out.println(pageSource); + Assert.assertTrue(pageSource.contains("customer-portal")); + driver.navigate().to(baseUrl + "/customer-portal/users/permit") ; + pageSource = driver.getPageSource(); + System.out.println(pageSource); + Assert.assertTrue(pageSource.contains("customer-portal/users/permit")); + } private static String getBaseDirectory() { String dirPath = null; diff --git a/testsuite/proxy/src/test/resources/tomcat-test/demorealm.json b/testsuite/proxy/src/test/resources/demorealm.json similarity index 94% rename from testsuite/proxy/src/test/resources/tomcat-test/demorealm.json rename to testsuite/proxy/src/test/resources/demorealm.json index 29de45cb9c..40104c95d3 100755 --- a/testsuite/proxy/src/test/resources/tomcat-test/demorealm.json +++ b/testsuite/proxy/src/test/resources/demorealm.json @@ -65,7 +65,8 @@ "adminUrl": "http://localhost:8080/customer-portal", "baseUrl": "http://localhost:8080/customer-portal", "redirectUris": [ - "http://localhost:8080/customer-portal/*" + "http://localhost:8080/customer-portal/*", + "https://localhost:8443/customer-portal/*" ], "secret": "password" } 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 0000000000..f26d8e341f --- /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