KEYCLOAK-8349 KEYCLOAK-8659 Use TLS for all tests in the suite

This commit is contained in:
Sebastian Laskawiec 2018-09-27 11:24:33 +02:00 committed by Pedro Igor
parent 885eec5ef2
commit ee41a0450f
121 changed files with 1342 additions and 598 deletions

View file

@ -17,7 +17,6 @@ env:
- TESTS=old
- TESTS=crossdc-server
- TESTS=crossdc-adapter
- TESTS=ssl
jdk:
- oraclejdk8

View file

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

View file

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

View file

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

View file

@ -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;
@ -52,7 +54,7 @@ public class Keycloak implements AutoCloseable {
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() {

View file

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

View file

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

View file

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

View file

@ -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 <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
@ -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);
}
}
}

View file

@ -42,6 +42,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

View file

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

View file

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

View file

@ -33,6 +33,7 @@
<properties>
<js-adapter.version>${project.version}</js-adapter.version>
<js-adapter.file.path>${project.basedir}/target/classes/javascript</js-adapter.file.path>
<js-adapter.auth-server-url>https://localhost:8543/auth</js-adapter.auth-server-url>
</properties>
<dependencies>
@ -68,6 +69,21 @@
</dependencies>
<profiles>
<profile>
<id>no-ssl</id>
<activation>
<property>
<name>auth.server.ssl.required</name>
<value>false</value>
</property>
</activation>
<properties>
<js-adapter.auth-server-url>http://localhost:8180/auth</js-adapter.auth-server-url>
</properties>
</profile>
</profiles>
<build>
<pluginManagement>
<plugins>

View file

@ -143,7 +143,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
}
sb.append("<br>");
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
UriBuilder base = UriBuilder.fromUri("/auth");
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>");
@ -165,7 +165,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
StringBuilder sb = new StringBuilder();
sb.append("<html><head><title>" + title + "</title></head><body>");
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
UriBuilder base = UriBuilder.fromUri("/auth");
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>");

View file

@ -137,7 +137,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide
}
sb.append("<br>");
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
UriBuilder base = UriBuilder.fromUri("/auth");
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>");
@ -159,7 +159,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide
StringBuilder sb = new StringBuilder();
sb.append("<html><head><title>" + title + "</title></head><body>");
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
UriBuilder base = UriBuilder.fromUri("/auth");
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>");

View file

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

View file

@ -28,8 +28,11 @@
<artifactId>integration-arquillian-servers-auth-server-undertow</artifactId>
<name>Auth Server - Undertow</name>
<dependencies>
<properties>
<common.resources>${basedir}/../jboss/common</common.resources>
</properties>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-testsuite-utils</artifactId>
@ -77,4 +80,15 @@
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>${common.resources}/keystore</directory>
</resource>
</resources>
</build>
</project>

View file

@ -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<KeycloakOnUnderto
if (undertow == null) {
undertow = new UndertowJaxrsServer();
}
undertow.start(Undertow.builder()
.addHttpListener(configuration.getBindHttpPort(), configuration.getBindAddress())
.addHttpsListener(configuration.getBindHttpsPort(), configuration.getBindAddress(), TLSUtils.initializeTLS())
.setWorkerThreads(configuration.getWorkerThreads())
.setIoThreads(configuration.getWorkerThreads() / 8)
);
if (configuration.getRoute() != null) {
log.info("Using route: " + configuration.getRoute());
}
@ -200,7 +210,6 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
log.infof("Auth server started in %dms on http://%s:%d/auth", (System.currentTimeMillis() - start), configuration.getBindAddress(), configuration.getBindHttpPort());
}
protected void setupDevConfig() {
KeycloakSession session = sessionFactory.create();
try {

View file

@ -28,6 +28,8 @@ import org.jboss.logging.Logger;
public class KeycloakOnUndertowConfiguration 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(KeycloakOnUndertowConfiguration.class);
private int workerThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2) * 8;
@ -38,6 +40,8 @@ public class KeycloakOnUndertowConfiguration extends UndertowContainerConfigurat
private Map<String, String> 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;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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": {

View file

@ -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";
%>
<html>
<body>
<h2><a href="<%= KeycloakUriBuilder.fromUri("/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
<h2><a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
.queryParam("redirect_uri", "http://localhost:8080/hello-world-authz-service").build("hello-world-authz").toString()%>">Logout</a></h2>
<h3>Access Denied !</h3>

View file

@ -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";
%>
<html>
<body>
<h2>Welcome !</h2>
<h2><a href="<%= KeycloakUriBuilder.fromUri("/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
<h2><a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
.queryParam("redirect_uri", "http://localhost:8080/hello-world-authz-service").build("hello-world-authz").toString()%>">Logout</a></h2>
<h3>Your permissions are:</h3>

View file

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

View file

@ -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";
%>
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri("http://localhost:8180/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
.queryParam("redirect_uri", redirectUri).build("servlet-authz").toString()%>">Sign Out</a></h2>

View file

@ -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";
%>
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri("http://localhost:8180/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
.queryParam("redirect_uri", redirectUri).build("servlet-policy-enforcer-authz").toString()%>">Sign Out</a></h2>

View file

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

View file

@ -271,6 +271,25 @@
</artifactItems>
</configuration>
</execution>
<execution>
<id>unpack-undertow-server</id>
<phase>generate-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>integration-arquillian-servers-auth-server-undertow</artifactId>
<version>${project.version}</version>
<type>jar</type>
<outputDirectory>${containers.home}/auth-server-undertow</outputDirectory>
</artifactItem>
</artifactItems>
<includes>*.jks,*.crt,*.truststore</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>

View file

@ -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<StopContainer> 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();

View file

@ -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;
/**
*
@ -155,6 +160,33 @@ 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;
@ -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) -> {
@ -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);
}
}

View file

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

View file

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

View file

@ -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() + ")",

View file

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

View file

@ -46,7 +46,7 @@ public class ApplicationServlet extends HttpServlet {
PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", 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("</body></html>");

View file

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

View file

@ -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<String, String> 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<String> redirectUrls = cr.getRedirectUris();
List<String> 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 <code>true</code> 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;
}
}

View file

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

View file

@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @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<String, AccountApplicationsPage.AppEntry> 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());

View file

@ -352,7 +352,7 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest {
public void conditionalOTPRequestHeaderSkip() {
//prepare config - request header skip, default to force
Map<String, String> 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<String, String> 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);

View file

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

View file

@ -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<String> redirectUris = client.getRedirectUris();
if (redirectUris != null) {
List<String> 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<String> webOrigins = client.getWebOrigins();
if (webOrigins != null) {
List<String> 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);
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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.
*
* <p>
* Note, for SSL this test disables TLS certificate verification. Since CORS uses different hostnames
* (localhost-auth for example), the Subject Name won't match.
* </p>
*
* @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{

View file

@ -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<RealmRepresentation> 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<String, Object> 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<String, Object> 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 };

View file

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

View file

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

View file

@ -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() {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<Keycloak> keycloaks = new ThreadLocal<Keycloak>() {
@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());
}
};

View file

@ -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<String> 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<String> 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<String> 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"),

View file

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

View file

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

View file

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

View file

@ -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<Permission> permissions, String expectedResource, String... expectedScopes) {

View file

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

View file

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

View file

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

View file

@ -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(),

View file

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

View file

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

View file

@ -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<RealmRepresentation> testRealms) {
for (RealmRepresentation tr : testRealms) {
tr.setSslRequired("external");
}
}
public void assertExitCodeAndStdOutSize(AbstractExec exe, int exitCode, int stdOutLineCount) {
assertExitCodeAndStreamSizes(exe, exitCode, stdOutLineCount, -1);

View file

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

View file

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

View file

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

View file

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

View file

@ -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<RealmRepresentation> 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<String> 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) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<String> 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")
));

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
assertTrue(apps.containsKey("offline-client-2"));

Some files were not shown because too many files have changed in this diff Show more