Merge pull request #868 from patriot1burke/master

proxy config
This commit is contained in:
Bill Burke 2014-11-21 18:53:23 -05:00
commit a6f231abbf
8 changed files with 605 additions and 92 deletions

View file

@ -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

View file

@ -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);
}
}
}
}

View file

@ -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;
}
}
}

View file

@ -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);
}
}
}
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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"
}

View file

@ -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
}
]
}
]
}