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=old
- TESTS=crossdc-server - TESTS=crossdc-server
- TESTS=crossdc-adapter - TESTS=crossdc-adapter
- TESTS=ssl
jdk: jdk:
- oraclejdk8 - oraclejdk8

View file

@ -282,6 +282,13 @@ public class KeycloakDeployment {
this.sslRequired = sslRequired; this.sslRequired = sslRequired;
} }
public boolean isSSLEnabled() {
if (SslRequired.NONE == sslRequired) {
return false;
}
return true;
}
public int getConfidentialPort() { public int getConfidentialPort() {
return confidentialPort; return confidentialPort;
} }

View file

@ -130,7 +130,7 @@ public class KeycloakDeploymentBuilder {
if (realmKeyPem == null && adapterConfig.isBearerOnly() && adapterConfig.getAuthServerUrl() == null) { 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"); 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)); deployment.setClient(new HttpClientBuilder().build(adapterConfig));
} }
if (adapterConfig.getAuthServerUrl() == null && (!deployment.isBearerOnly() || realmKeyPem == null)) { 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()); public static final ObjectMapper sysPropertiesAwareMapper = new ObjectMapper(new SystemPropertiesJsonParserFactory());
static { static {
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
prettyMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
prettyMapper.enable(SerializationFeature.INDENT_OUTPUT); prettyMapper.enable(SerializationFeature.INDENT_OUTPUT);
prettyMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 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.resource.ServerInfoResource;
import org.keycloak.admin.client.token.TokenManager; import org.keycloak.admin.client.token.TokenManager;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.net.URI; import java.net.URI;
@ -49,10 +51,10 @@ public class Keycloak implements AutoCloseable {
private final String authToken; private final String authToken;
private final ResteasyWebTarget target; private final ResteasyWebTarget target;
private final ResteasyClient client; private final ResteasyClient client;
Keycloak(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, String grantType, ResteasyClient resteasyClient, String authtoken) { 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); 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; authToken = authtoken;
tokenManager = authtoken == null ? new TokenManager(config, client) : null; 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); 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) { private static ResteasyClient newRestEasyClient(ResteasyJackson2Provider customJacksonProvider, SSLContext sslContext, boolean disableTrustManager) {
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) {
ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder() ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder()
.sslContext(sslContext) .sslContext(sslContext)
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.WILDCARD) .connectionPoolSize(10);
.connectionPoolSize(10);
if (disableTrustManager) {
// Disable PKIX path validation errors when running tests using SSL
clientBuilder.disableTrustManager().hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY);
}
if (customJacksonProvider != null) { if (customJacksonProvider != null) {
clientBuilder.register(customJacksonProvider, 100); 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) { 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) { 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) { 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() { 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)") @Option(name = "trustpass", description = "Truststore password (prompted for if not specified and --truststore is used)")
String trustPass; 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") @Option(name = "token", description = "Token to use for invocations. With this option set, every other authentication option is ignored")
String externalToken; String externalToken;
@ -178,6 +181,10 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
throw new RuntimeException("Failed to load truststore: " + truststore, e); throw new RuntimeException("Failed to load truststore: " + truststore, e);
} }
} }
if (insecure) {
HttpUtil.setSkipCertificateValidation();
}
} }
protected ConfigData ensureAuthInfo(ConfigData config, CommandInvocation commandInvocation) { 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.HttpPut;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 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.InputStreamEntity;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts; import org.apache.http.ssl.SSLContexts;
import org.keycloak.client.admin.cli.httpcomponents.HttpDelete; import org.keycloak.client.admin.cli.httpcomponents.HttpDelete;
import org.keycloak.client.admin.cli.operations.LocalSearch; import org.keycloak.client.admin.cli.operations.LocalSearch;
@ -53,6 +55,7 @@ import java.security.cert.CertificateException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.keycloak.common.util.ObjectUtil.capitalize; import static org.keycloak.common.util.ObjectUtil.capitalize;
@ -68,6 +71,7 @@ public class HttpUtil {
private static HttpClient httpClient; private static HttpClient httpClient;
private static SSLConnectionSocketFactory sslsf; private static SSLConnectionSocketFactory sslsf;
private static final AtomicBoolean tlsWarningEmitted = new AtomicBoolean();
public static InputStream doGet(String url, String acceptType, String authorization) { public static InputStream doGet(String url, String acceptType, String authorization) {
try { try {
@ -257,11 +261,29 @@ public class HttpUtil {
} }
SSLContext theContext = SSLContexts.custom() SSLContext theContext = SSLContexts.custom()
.useProtocol("TLS") .useProtocol("TLS")
.loadTrustMaterial(file, password == null ? null : password.toCharArray()) .loadTrustMaterial(file, password == null ? null : password.toCharArray(), TrustSelfSignedStrategy.INSTANCE)
.build(); .build();
sslsf = new SSLConnectionSocketFactory(theContext); 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) { public static String extractIdFromLocation(String location) {
int last = location.lastIndexOf("/"); int last = location.lastIndexOf("/");
if (last != -1) { if (last != -1) {

View file

@ -25,7 +25,6 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
static final String DEFAULT_CLIENT = "admin-cli"; static final String DEFAULT_CLIENT = "admin-cli";
@Option(name = "config", description = "Path to the config file (~/.keycloak/kcreg.config by default)", hasValue = true) @Option(name = "config", description = "Path to the config file (~/.keycloak/kcreg.config by default)", hasValue = true)
protected String config; 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) @Option(name = "trustpass", description = "Truststore password (prompted for if not specified and --truststore is used)", hasValue = true)
protected String trustPass; 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) @Option(shortName = 't', name = "token", description = "Initial / Registration access token to use)", hasValue = true)
protected String token; protected String token;
@ -90,6 +92,7 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
trustStore = parent.trustStore; trustStore = parent.trustStore;
trustPass = parent.trustPass; trustPass = parent.trustPass;
token = parent.token; token = parent.token;
insecure = parent.insecure;
} }
protected void applyDefaultOptionValues() { protected void applyDefaultOptionValues() {
@ -152,6 +155,10 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
throw new RuntimeException("Failed to load truststore: " + truststore, e); throw new RuntimeException("Failed to load truststore: " + truststore, e);
} }
} }
if (insecure) {
HttpUtil.setSkipCertificateValidation();
}
} }
protected ConfigData ensureAuthInfo(ConfigData config, CommandInvocation commandInvocation) { 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.HttpPut;
import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 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.ssl.SSLContexts;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
@ -46,6 +48,7 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a> * @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
@ -59,6 +62,7 @@ public class HttpUtil {
private static HttpClient httpClient; private static HttpClient httpClient;
private static SSLConnectionSocketFactory sslsf; private static SSLConnectionSocketFactory sslsf;
private static final AtomicBoolean tlsWarningEmitted = new AtomicBoolean();
public static InputStream doGet(String url, String acceptType, String authorization) { public static InputStream doGet(String url, String acceptType, String authorization) {
try { try {
@ -181,8 +185,26 @@ public class HttpUtil {
} }
SSLContext theContext = SSLContexts.custom() SSLContext theContext = SSLContexts.custom()
.useProtocol("TLS") .useProtocol("TLS")
.loadTrustMaterial(file, password == null ? null : password.toCharArray()) .loadTrustMaterial(file, password == null ? null : password.toCharArray(), TrustSelfSignedStrategy.INSTANCE)
.build(); .build();
sslsf = new SSLConnectionSocketFactory(theContext); 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

@ -41,6 +41,10 @@ and adapter are all in the same JVM and you can debug them easily. If it is not
-Dmaven.surefire.debug=true -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. 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 \ -Dbrowser=phantomjs \
"-Dtest=*.x509.*" "-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 \ mvn -f testsuite/integration-arquillian/pom.xml \
clean install \ clean install \
-Pauth-server-wildfly \ -Dauth.server.ssl.required=false
-Dauth.server.ssl.required \
-Dbrowser=phantomjs \
-Dtest=org.keycloak.testsuite.hok.HoKTest
## Run Mutual TLS for the Client tests 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.
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
## Cluster tests ## Cluster tests

View file

@ -3,8 +3,9 @@ embed-server --server-config=standalone.xml
/subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/:add( \ /subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/:add( \
realm=demo, \ realm=demo, \
resource=customer-portal-subsystem, \ 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, \ ssl-required=EXTERNAL, \
disable-trust-manager=true, \
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
) )
/subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/credential=secret/:add(value=password) /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( \ /subsystem=keycloak/secure-deployment=product-portal-subsystem.war/:add( \
realm=demo, \ realm=demo, \
resource=product-portal-subsystem, \ 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, \ ssl-required=EXTERNAL, \
disable-trust-manager=true, \
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
) )
/subsystem=keycloak/secure-deployment=product-portal-subsystem.war/credential=secret/:add(value=password) /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( \ /subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/:add( \
realm=demo, \ realm=demo, \
resource=customer-portal-subsystem, \ 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, \ ssl-required=EXTERNAL, \
disable-trust-manager=true, \
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
) )
/subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/credential=secret/:add(value=password) /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( \ /subsystem=keycloak/secure-deployment=product-portal-subsystem.war/:add( \
realm=demo, \ realm=demo, \
resource=product-portal-subsystem, \ 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, \ ssl-required=EXTERNAL, \
disable-trust-manager=true, \
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \ realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
) )
/subsystem=keycloak/secure-deployment=product-portal-subsystem.war/credential=secret/:add(value=password) /subsystem=keycloak/secure-deployment=product-portal-subsystem.war/credential=secret/:add(value=password)

View file

@ -33,6 +33,7 @@
<properties> <properties>
<js-adapter.version>${project.version}</js-adapter.version> <js-adapter.version>${project.version}</js-adapter.version>
<js-adapter.file.path>${project.basedir}/target/classes/javascript</js-adapter.file.path> <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> </properties>
<dependencies> <dependencies>
@ -68,6 +69,21 @@
</dependencies> </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> <build>
<pluginManagement> <pluginManagement>
<plugins> <plugins>

View file

@ -143,7 +143,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
} }
sb.append("<br>"); 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("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>"); sb.append("</body></html>");
@ -165,7 +165,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("<html><head><title>" + title + "</title></head><body>"); 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("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>"); sb.append("</body></html>");

View file

@ -137,7 +137,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide
} }
sb.append("<br>"); 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("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>"); sb.append("</body></html>");
@ -159,7 +159,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("<html><head><title>" + title + "</title></head><body>"); 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("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
sb.append("</body></html>"); sb.append("</body></html>");

View file

@ -1,7 +1,7 @@
{ {
"realm" : "test", "realm" : "test",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "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", "ssl-required" : "external",
"resource" : "js-console", "resource" : "js-console",
"public-client" : true "public-client" : true

View file

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

View file

@ -51,10 +51,19 @@ import org.keycloak.testsuite.utils.undertow.UndertowDeployerHelper;
import org.keycloak.testsuite.utils.undertow.UndertowWarClassLoader; import org.keycloak.testsuite.utils.undertow.UndertowWarClassLoader;
import org.keycloak.util.JsonSerialization; 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.DispatcherType;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; 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.Collection;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -180,12 +189,13 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
if (undertow == null) { if (undertow == null) {
undertow = new UndertowJaxrsServer(); undertow = new UndertowJaxrsServer();
} }
undertow.start(Undertow.builder() undertow.start(Undertow.builder()
.addHttpListener(configuration.getBindHttpPort(), configuration.getBindAddress()) .addHttpListener(configuration.getBindHttpPort(), configuration.getBindAddress())
.addHttpsListener(configuration.getBindHttpsPort(), configuration.getBindAddress(), TLSUtils.initializeTLS())
.setWorkerThreads(configuration.getWorkerThreads()) .setWorkerThreads(configuration.getWorkerThreads())
.setIoThreads(configuration.getWorkerThreads() / 8) .setIoThreads(configuration.getWorkerThreads() / 8)
); );
if (configuration.getRoute() != null) { if (configuration.getRoute() != null) {
log.info("Using route: " + configuration.getRoute()); 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()); log.infof("Auth server started in %dms on http://%s:%d/auth", (System.currentTimeMillis() - start), configuration.getBindAddress(), configuration.getBindHttpPort());
} }
protected void setupDevConfig() { protected void setupDevConfig() {
KeycloakSession session = sessionFactory.create(); KeycloakSession session = sessionFactory.create();
try { try {

View file

@ -28,6 +28,8 @@ import org.jboss.logging.Logger;
public class KeycloakOnUndertowConfiguration extends UndertowContainerConfiguration { 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); protected static final Logger log = Logger.getLogger(KeycloakOnUndertowConfiguration.class);
private int workerThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2) * 8; 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 Map<String, String> keycloakConfigPropertyOverridesMap;
private int bindHttpPortOffset = 0; private int bindHttpPortOffset = 0;
private int bindHttpsPortOffset = 0;
private int bindHttpsPort = DEFAULT_HTTPS_PORT;
public int getWorkerThreads() { public int getWorkerThreads() {
return workerThreads; return workerThreads;
@ -63,6 +67,22 @@ public class KeycloakOnUndertowConfiguration extends UndertowContainerConfigurat
this.bindHttpPortOffset = bindHttpPortOffset; 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() { public String getRoute() {
return route; 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.lang.reflect.Field;
import java.net.URI; import java.net.URI;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -41,6 +40,8 @@ import io.undertow.util.Headers;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.common.util.reflections.Reflections; import org.keycloak.common.util.reflections.Reflections;
import org.keycloak.services.managers.AuthenticationSessionManager; import org.keycloak.services.managers.AuthenticationSessionManager;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -56,19 +57,20 @@ public class SimpleUndertowLoadBalancer {
private static final Logger log = Logger.getLogger(SimpleUndertowLoadBalancer.class); 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 String host;
private final int port; private final int httpPort;
private final int httpsPort;
private final Map<String, URI> backendNodes; private final Map<String, URI> backendNodes;
private Undertow undertow; private Undertow undertow;
private LoadBalancingProxyClient lb; private LoadBalancingProxyClient lb;
public static void main(String[] args) throws Exception { 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(); lb.start();
Runtime.getRuntime().addShutdownHook(new Thread() { 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.host = host;
this.port = port; this.httpPort = httpPort;
this.httpsPort = httpsPort;
this.backendNodes = parseNodes(nodesString); this.backendNodes = parseNodes(nodesString);
log.infof("Keycloak nodes: %s", backendNodes); log.infof("Keycloak nodes: %s", backendNodes);
} }
@ -95,12 +98,13 @@ public class SimpleUndertowLoadBalancer {
HttpHandler proxyHandler = createHandler(); HttpHandler proxyHandler = createHandler();
undertow = Undertow.builder() undertow = Undertow.builder()
.addHttpListener(port, host) .addHttpListener(httpPort, host)
.addHttpsListener(httpsPort, host, TLSUtils.initializeTLS())
.setHandler(proxyHandler) .setHandler(proxyHandler)
.build(); .build();
undertow.start(); 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) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View file

@ -26,10 +26,14 @@ import org.jboss.logging.Logger;
*/ */
public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerConfiguration { 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); 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 bindHttpPortOffset = 0;
private int bindHttpsPortOffset = 0;
private int bindHttpsPort = DEFAULT_HTTPS_PORT;
public String getNodes() { public String getNodes() {
return nodes; return nodes;
@ -47,6 +51,22 @@ public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerCo
this.bindHttpPortOffset = bindHttpPortOffset; 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 @Override
public void validate() throws ConfigurationException { public void validate() throws ConfigurationException {
super.validate(); super.validate();
@ -57,10 +77,9 @@ public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerCo
throw new ConfigurationException(e); throw new ConfigurationException(e);
} }
int basePort = getBindHttpPort(); setBindHttpPort(getBindHttpPort() + bindHttpPortOffset);
int newPort = basePort + bindHttpPortOffset; setBindHttpsPort(getBindHttpsPort() + bindHttpsPortOffset);
setBindHttpPort(newPort); log.info("SimpleUndertowLoadBalancer will listen on ports: " + getBindHttpPort() + " " + getBindHttpsPort());
log.info("SimpleUndertowLoadBalancer will listen on port: " + newPort);
} }
} }

View file

@ -51,7 +51,7 @@ public class SimpleUndertowLoadBalancerContainer implements DeployableContainer<
@Override @Override
public void start() throws LifecycleException { 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(); this.container.start();
} }

View file

@ -18,11 +18,7 @@
var module = angular.module('product', []); var module = angular.module('product', []);
function getAuthServerUrl() { function getAuthServerUrl() {
var url = 'http://localhost-auth:8180'; var url = 'https://localhost-auth:8543';
if (window.location.href.indexOf("8643") > -1) {
url = url.replace("8180","8543");
url = url.replace("http","https");
}
return url; return url;
} }

View file

@ -3,6 +3,7 @@
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "http://localhost-auth:8180/auth", "auth-server-url" : "http://localhost-auth:8180/auth",
"ssl-required" : "external", "ssl-required" : "external",
"disable-trust-manager" : "true",
"resource" : "angular-cors-product", "resource" : "angular-cors-product",
"public-client" : true "public-client" : true
} }

View file

@ -5,6 +5,7 @@
"auth-server-url": "http://localhost-auth:8180/auth", "auth-server-url": "http://localhost-auth:8180/auth",
"bearer-only" : true, "bearer-only" : true,
"ssl-required": "external", "ssl-required": "external",
"disable-trust-manager" : "true",
"enable-cors": true, "enable-cors": true,
"cors-exposed-headers": "X-Custom1", "cors-exposed-headers": "X-Custom1",
"credentials": { "credentials": {

View file

@ -19,9 +19,16 @@
<%@ page import="org.keycloak.common.util.KeycloakUriBuilder" %> <%@ page import="org.keycloak.common.util.KeycloakUriBuilder" %>
<%@ page import="org.keycloak.constants.ServiceUrlConstants" %> <%@ 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> <html>
<body> <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> .queryParam("redirect_uri", "http://localhost:8080/hello-world-authz-service").build("hello-world-authz").toString()%>">Logout</a></h2>
<h3>Access Denied !</h3> <h3>Access Denied !</h3>

View file

@ -24,11 +24,16 @@
<% <%
KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext(); 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> <html>
<body> <body>
<h2>Welcome !</h2> <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> .queryParam("redirect_uri", "http://localhost:8080/hello-world-authz-service").build("hello-world-authz").toString()%>">Logout</a></h2>
<h3>Your permissions are:</h3> <h3>Your permissions are:</h3>

View file

@ -140,9 +140,9 @@
"consentRequired" : true, "consentRequired" : true,
"fullScopeAllowed" : true, "fullScopeAllowed" : true,
"redirectUris": [ "redirectUris": [
"/photoz-html5-client/*" "*"
], ],
"webOrigins": ["http://localhost:8280"] "webOrigins": ["*"]
}, },
{ {
"clientId": "photoz-restful-api", "clientId": "photoz-restful-api",
@ -150,9 +150,9 @@
"baseUrl": "/photoz-restful-api", "baseUrl": "/photoz-restful-api",
"authorizationServicesEnabled" : true, "authorizationServicesEnabled" : true,
"redirectUris": [ "redirectUris": [
"/photoz-restful-api/*" "*"
], ],
"webOrigins" : ["http://localhost:8280"], "webOrigins" : ["*"],
"clientAuthenticatorType": "client-jwt", "clientAuthenticatorType": "client-jwt",
"attributes" : { "attributes" : {
"jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==" "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(); int port = request.getServerPort();
String contextPath = request.getContextPath(); String contextPath = request.getContextPath();
String redirectUri = scheme + "://" + host + ":" + port + contextPath; 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> .queryParam("redirect_uri", redirectUri).build("servlet-authz").toString()%>">Sign Out</a></h2>

View file

@ -6,6 +6,12 @@
int port = request.getServerPort(); int port = request.getServerPort();
String contextPath = request.getContextPath(); String contextPath = request.getContextPath();
String redirectUri = scheme + "://" + host + ":" + port + contextPath; 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> .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() { private String getSamlRequest() {
if (System.getProperty("auth.server.ssl.required", "false").equals("true")) { 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"; return "jZJRT9swFIX%2FiuX31I5pSbCaSoVqWiXYIlp42Asyzu1qybGDr1PWfz83LQKJAZP8YNnf9T3nXE9RtbaT8z5u3S089YCR%2FGmtQzlcVLQPTnqFBqVTLaCMWq7mN9dSjLjsgo9ee0uPJZ%2FDChFCNN5RMn%2FZXnmHfQthBWFnNNzdXld0G2MnGbNeK7v1GGUpSs6g7azfAzBKFkmjcepQ%2Fy86T7RKdlgAZVtkDbSevShlB1eUfPNBw%2BC5ohtlEShZLiq6XDyMmxImGkRWCH6ejQvxmKnyoshEU54V%2FIJrzicJxjrZMTt4LUfsYekwKhcrKng%2ByfhZxs%2FXQsi08mJUTsa%2FKKlPQi6Na4z7%2FXlkj0cI5ff1us7qn6s1JfcQcHCeADoj04MhOXQPbwb3v6OYfZH2lL15%2F9Stkz%2FSi8tF7a3RezK31j9fpbBjSiOGHoZ4WxU%2F1pCP8uHENNlmQGXvsANtNgYaylIf9v5bzv4C";

View file

@ -271,6 +271,25 @@
</artifactItems> </artifactItems>
</configuration> </configuration>
</execution> </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> </executions>
</plugin> </plugin>
<plugin> <plugin>

View file

@ -39,9 +39,19 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.util.LogChecker; import org.keycloak.testsuite.util.LogChecker;
import org.keycloak.testsuite.util.OAuthClient; 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.ManagementClient;
import org.wildfly.extras.creaper.core.online.CliException;
import org.wildfly.extras.creaper.core.online.OnlineManagementClient; import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
import org.wildfly.extras.creaper.core.online.OnlineOptions; 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.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
@ -50,6 +60,7 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.ws.rs.NotFoundException; import javax.ws.rs.NotFoundException;
@ -72,6 +83,8 @@ public class AuthServerTestEnricher {
@Inject @Inject
private Event<StopContainer> stopContainerEvent; 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_DEFAULT = "auth-server-undertow";
public static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container"; 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); 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 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 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 = AUTH_SERVER_SSL_REQUIRED ? "https" : "http";
String scheme = sslRequired ? "https" : "http"; int port = AUTH_SERVER_SSL_REQUIRED ? httpsPort : httpPort;
int port = sslRequired ? httpsPort : httpPort;
return String.format("%s://%s:%s", scheme, host, port + clusterPortOffset); return String.format("%s://%s:%s", scheme, host, port + clusterPortOffset);
} }
@ -322,7 +334,56 @@ public class AuthServerTestEnricher {
testContextProducer.set(testContext); 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 // TODO workaround. Check if can be removed
OAuthClient.updateURLs(suiteContext.getAuthServerInfo().getContextRoot().toString()); OAuthClient.updateURLs(suiteContext.getAuthServerInfo().getContextRoot().toString());
OAuthClient oAuthClient = new OAuthClient(); 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.core.api.annotation.Observes;
import org.jboss.arquillian.test.spi.event.suite.After; 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.Before;
import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.Keycloak;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
import org.keycloak.testsuite.arquillian.annotation.InitialDcState; 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.auth.page.AuthRealm;
import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.crossdc.DC; 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.container.spi.event.StopSuiteContainers;
import org.jboss.arquillian.core.api.Event; import org.jboss.arquillian.core.api.Event;
import org.jboss.arquillian.test.spi.event.suite.AfterSuite; import org.jboss.arquillian.test.spi.event.suite.AfterSuite;
import org.wildfly.extras.creaper.core.ManagementClient;
import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
import org.wildfly.extras.creaper.core.online.OnlineOptions;
/** /**
* *
@ -154,7 +159,34 @@ public class CrossDCTestEnricher {
suspendPeriodicTasks(); 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) { public void afterTest(@Observes After event) {
if (!suiteContext.isAuthServerCrossDc()) return; if (!suiteContext.isAuthServerCrossDc()) return;
@ -196,7 +228,7 @@ public class CrossDCTestEnricher {
backendTestingClients.put(node, createTestingClientFor(node)); backendTestingClients.put(node, createTestingClientFor(node));
} }
} }
private static void removeRESTClientsForNode(ContainerInfo node) { private static void removeRESTClientsForNode(ContainerInfo node) {
if (backendAdminClients.containsKey(node)) { if (backendAdminClients.containsKey(node)) {
backendAdminClients.get(node).close(); backendAdminClients.get(node).close();
@ -219,15 +251,15 @@ public class CrossDCTestEnricher {
private static Keycloak createAdminClientFor(ContainerInfo node) { private static Keycloak createAdminClientFor(ContainerInfo node) {
log.info("--DC: Initializing admin client for " + node.getContextRoot() + "/auth"); 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) { private static KeycloakTestingClient createTestingClientFor(ContainerInfo node) {
log.info("--DC: Initializing testing client for " + node.getContextRoot() + "/auth"); log.info("--DC: Initializing testing client for " + node.getContextRoot() + "/auth");
return KeycloakTestingClient.getInstance(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. // Disable periodic tasks in cross-dc tests. It's needed to have some scenarios more stable.
private static void suspendPeriodicTasks() { private static void suspendPeriodicTasks() {
log.debug("--DC: suspendPeriodicTasks"); log.debug("--DC: suspendPeriodicTasks");
backendTestingClients.values().stream().forEach((KeycloakTestingClient testingClient) -> { backendTestingClients.values().stream().forEach((KeycloakTestingClient testingClient) -> {
@ -275,7 +307,7 @@ public class CrossDCTestEnricher {
containerController.get().stop(qualifier); containerController.get().stop(qualifier);
// Workaround for possible arquillian bug. Needs to cleanup dir manually // Workaround for possible arquillian bug. Needs to cleanup dir manually
String setupCleanServerBaseDir = getContainerProperty(getCacheServer(dc), "setupCleanServerBaseDir"); String setupCleanServerBaseDir = getContainerProperty(getCacheServer(dc), "setupCleanServerBaseDir");
String cleanServerBaseDir = getContainerProperty(getCacheServer(dc), "cleanServerBaseDir"); String cleanServerBaseDir = getContainerProperty(getCacheServer(dc), "cleanServerBaseDir");
@ -327,6 +359,7 @@ public class CrossDCTestEnricher {
if (! containerInfo.isStarted()) { if (! containerInfo.isStarted()) {
log.infof("--DC: Starting backend auth-server node: %s", containerInfo.getQualifier()); log.infof("--DC: Starting backend auth-server node: %s", containerInfo.getQualifier());
containerController.get().start(containerInfo.getQualifier()); containerController.get().start(containerInfo.getQualifier());
initializeTLS(containerInfo);
createRESTClientsForNode(containerInfo); createRESTClientsForNode(containerInfo);
} }
} }

View file

@ -17,6 +17,9 @@
package org.keycloak.testsuite.client; 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.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
@ -42,6 +45,10 @@ public class KeycloakTestingClient implements AutoCloseable {
} else { } else {
ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder(); ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder();
resteasyClientBuilder.connectionPoolSize(10); 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)); resteasyClientBuilder.httpEngine(AdminClientUtil.getCustomClientHttpEngine(resteasyClientBuilder, 10));
client = resteasyClientBuilder.build(); client = resteasyClientBuilder.build();
} }

View file

@ -28,6 +28,7 @@ import org.jboss.arquillian.drone.webdriver.spi.BrowserCapabilitiesRegistry;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.openqa.selenium.Capabilities; import org.openqa.selenium.Capabilities;
import org.openqa.selenium.phantomjs.PhantomJSDriverService; import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.Arrays; import java.util.Arrays;
@ -53,11 +54,17 @@ public class KeycloakWebDriverConfigurator {
updateCapabilityKeys("htmlUnit", webDriverCfg, capabilitiesToAdd); updateCapabilityKeys("htmlUnit", webDriverCfg, capabilitiesToAdd);
updateCapabilityKeys("appium", webDriverCfg, capabilitiesToAdd); updateCapabilityKeys("appium", webDriverCfg, capabilitiesToAdd);
configurePhantomJSDriver(webDriverCfg, capabilitiesToAdd); configurePhantomJSDriver(webDriverCfg, capabilitiesToAdd);
acceptAllSSLCerts(capabilitiesToAdd);
BrowserCapabilities browserCap = registryInstance.get().getEntryFor(webDriverCfg.getBrowser()); BrowserCapabilities browserCap = registryInstance.get().getEntryFor(webDriverCfg.getBrowser());
webDriverCfg.setBrowserInternal(new KcBrowserCapabilities(capabilitiesToAdd, browserCap)); 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) { private void configurePhantomJSDriver(WebDriverConfiguration webDriverCfg, DesiredCapabilities capabilitiesToAdd) {
if (!webDriverCfg.getBrowser().equals("phantomjs")) { if (!webDriverCfg.getBrowser().equals("phantomjs")) {
return; return;

View file

@ -21,6 +21,7 @@ import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.Assert; import org.junit.Assert;
import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.testsuite.arquillian.SuiteContext; import org.keycloak.testsuite.arquillian.SuiteContext;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
@ -38,6 +39,9 @@ public abstract class AbstractPage {
@ArquillianResource @ArquillianResource
protected WebDriver driver; protected WebDriver driver;
@ArquillianResource
protected OAuthClient oauth;
public void assertCurrent() { public void assertCurrent() {
String name = getClass().getSimpleName(); String name = getClass().getSimpleName();
Assert.assertTrue("Expected " + name + " but was " + driver.getTitle() + " (" + driver.getCurrentUrl() + ")", 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 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") @FindBy(id = "account")
private WebElement accountLink; private WebElement accountLink;
@Override @Override
public void open() { public void open() {
driver.navigate().to(baseUrl); driver.navigate().to(oauth.APP_AUTH_ROOT);
} }
@Override @Override
public boolean isCurrent() { public boolean isCurrent() {
return driver.getCurrentUrl().startsWith(baseUrl); return driver.getCurrentUrl().startsWith(oauth.APP_AUTH_ROOT);
} }
public RequestType getRequestType() { public RequestType getRequestType() {
@ -58,10 +55,9 @@ public class AppPage extends AbstractPage {
} }
public void logout() { public void logout() {
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(AUTH_SERVER_URL)) String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(oauth.AUTH_SERVER_ROOT))
.queryParam(OAuth2Constants.REDIRECT_URI,baseUrl).build("test").toString(); .queryParam(OAuth2Constants.REDIRECT_URI, oauth.APP_AUTH_ROOT).build("test").toString();
driver.navigate().to(logoutUri); driver.navigate().to(logoutUri);
} }
} }

View file

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

View file

@ -91,6 +91,7 @@ public class OAuthClient {
public static String SERVER_ROOT; public static String SERVER_ROOT;
public static String AUTH_SERVER_ROOT; public static String AUTH_SERVER_ROOT;
public static String APP_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")); private static final boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required"));
static { static {
@ -102,6 +103,7 @@ public class OAuthClient {
SERVER_ROOT = serverRoot; SERVER_ROOT = serverRoot;
AUTH_SERVER_ROOT = SERVER_ROOT + "/auth"; AUTH_SERVER_ROOT = SERVER_ROOT + "/auth";
APP_ROOT = AUTH_SERVER_ROOT + "/realms/master/app"; APP_ROOT = AUTH_SERVER_ROOT + "/realms/master/app";
APP_AUTH_ROOT = APP_ROOT + "/auth";
} }
private WebDriver driver; private WebDriver driver;
@ -659,7 +661,7 @@ public class OAuthClient {
public OIDCConfigurationRepresentation doWellKnownRequest(String realm) { public OIDCConfigurationRepresentation doWellKnownRequest(String realm) {
try (CloseableHttpClient client = HttpClientBuilder.create().build()) { 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) { } catch (IOException ex) {
throw new RuntimeException(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.admin.client.resource.UsersResource;
import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.resources.account.AccountFormService;
import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.KcArquillian; 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 org.wildfly.extras.creaper.core.online.operations.admin.Administration;
import javax.ws.rs.NotFoundException; 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.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.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
@ -79,6 +91,7 @@ import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -98,6 +111,8 @@ import static org.keycloak.testsuite.util.URLUtils.navigateToUri;
public abstract class AbstractKeycloakTest { public abstract class AbstractKeycloakTest {
protected static final boolean AUTH_SERVER_SSL_REQUIRED = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "false")); 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"; protected static final String ENGLISH_LOCALE_NAME = "English";
@ -145,13 +160,6 @@ public abstract class AbstractKeycloakTest {
private boolean resetTimeOffset; private boolean resetTimeOffset;
@BeforeClass
public static void setUpAuthServer() throws Exception {
if (AUTH_SERVER_SSL_REQUIRED) {
enableHTTPSForAuthServer();
}
}
@Before @Before
public void beforeAbstractKeycloakTest() throws Exception { public void beforeAbstractKeycloakTest() throws Exception {
adminClient = testContext.getAdminClient(); adminClient = testContext.getAdminClient();
@ -364,10 +372,66 @@ public abstract class AbstractKeycloakTest {
addTestRealms(); addTestRealms();
log.info("importing test realms"); log.info("importing test realms");
for (RealmRepresentation testRealm : testRealmReps) { 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); 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() { protected void removeAllRealmsDespiteMaster() {
// remove all realms (accidentally left by other tests) except for master // remove all realms (accidentally left by other tests) except for master
@ -536,28 +600,31 @@ public abstract class AbstractKeycloakTest {
return log; return log;
} }
private static void enableHTTPSForAuthServer() throws IOException, CommandFailedException, TimeoutException, InterruptedException, CliException, OperationException { protected String getAccountRedirectUrl(String realm) {
OnlineManagementClient client = AuthServerTestEnricher.getManagementClient(); return AccountFormService
Administration administration = new Administration(client); .loginRedirectUrl(UriBuilder.fromUri(oauth.AUTH_SERVER_ROOT))
Operations operations = new Operations(client); .build(realm)
.toString();
}
if(!operations.exists(Address.coreService("management").and("security-realm", "UndertowRealm"))) { protected String getAccountRedirectUrl() {
client.execute("/core-service=management/security-realm=UndertowRealm:add()"); return getAccountRedirectUrl("test");
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 static InputStream httpsAwareConfigurationStream(InputStream input) throws IOException {
if (!AUTH_SERVER_SSL_REQUIRED) {
return input;
} }
PipedInputStream in = new PipedInputStream();
client.apply(new RemoveUndertowListener.Builder(UndertowListenerType.HTTPS_LISTENER, "https") final PipedOutputStream out = new PipedOutputStream(in);
.forDefaultServer()); try (PrintWriter pw = new PrintWriter(out)) {
try (Scanner s = new Scanner(input)) {
administration.reloadIfRequired(); while (s.hasNextLine()) {
String lineWithReplaces = s.nextLine().replace("http://localhost:8180/auth", AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT + "/auth");
client.apply(new AddUndertowListener.HttpsBuilder("https", "default-server", "https") pw.println(lineWithReplaces);
.securityRealm("UndertowRealm") }
.verifyClient(SslVerifyClient.REQUESTED) }
.build()); }
return in;
administration.reloadIfRequired();
client.close();
} }
} }

View file

@ -53,7 +53,8 @@ public class AssertEvents implements TestRule {
public static final String DEFAULT_REALM = "test"; public static final String DEFAULT_REALM = "test";
public static final String DEFAULT_USERNAME = "test-user@localhost"; 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; private AbstractKeycloakTest context;
@ -100,7 +101,7 @@ public class AssertEvents implements TestRule {
//.detail(Details.USERNAME, DEFAULT_USERNAME) //.detail(Details.USERNAME, DEFAULT_USERNAME)
//.detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL) //.detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL)
//.detail(Details.AUTH_TYPE, AuthorizationEndpoint.CODE_AUTH_TYPE) //.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) .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED)
.session(isUUID()); .session(isUUID());
} }
@ -119,7 +120,7 @@ public class AssertEvents implements TestRule {
.detail(Details.CODE_ID, isCodeId()) .detail(Details.CODE_ID, isCodeId())
.detail(Details.USERNAME, DEFAULT_USERNAME) .detail(Details.USERNAME, DEFAULT_USERNAME)
.detail(Details.AUTH_METHOD, "form") .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()); .session(isUUID());
} }
@ -145,7 +146,7 @@ public class AssertEvents implements TestRule {
public ExpectedEvent expectLogout(String sessionId) { public ExpectedEvent expectLogout(String sessionId) {
return expect(EventType.LOGOUT).client((String) null) 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); .session(sessionId);
} }
@ -163,7 +164,7 @@ public class AssertEvents implements TestRule {
.detail(Details.USERNAME, username) .detail(Details.USERNAME, username)
.detail(Details.EMAIL, email) .detail(Details.EMAIL, email)
.detail(Details.REGISTER_METHOD, "form") .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) { 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.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.services.resources.account.AccountFormService; import org.keycloak.services.resources.account.AccountFormService;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.AssertEvents;
@ -70,7 +69,6 @@ import java.util.Collections;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import javax.ws.rs.core.UriBuilder;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; 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.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import javax.ws.rs.core.UriBuilder;
/** /**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a> * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc. * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
@ -135,11 +135,13 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
RealmBuilder.edit(testRealm) RealmBuilder.edit(testRealm)
.user(user2) .user(user2)
.user(realmAdmin); .user(realmAdmin);
}
private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth"); if (AUTH_SERVER_SSL_REQUIRED) {
private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString(); // Some scenarios here use redirections, so we need to fix the base url
public static String ACCOUNT_REDIRECT = AccountFormService.loginRedirectUrl(BASE.clone()).build("test").toString(); findTestApp(testRealm)
.setBaseUrl(String.format("%s://localhost:%s/auth/realms/master/app/auth", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT));
}
}
// Create second session // Create second session
@Drone @Drone
@ -203,12 +205,12 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
Assert.assertTrue(appPage.isCurrent()); 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()); Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication(); profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent()); 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"); driver.navigate().to(profilePage.getPath() + "?referrer=test-app");
Assert.assertTrue(profilePage.isCurrent()); Assert.assertTrue(profilePage.isCurrent());
@ -242,7 +244,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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 sessionId = event.getSessionId();
String userId = event.getUserId(); String userId = event.getUserId();
@ -288,7 +290,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
public void changePasswordWithBlankCurrentPassword() { public void changePasswordWithBlankCurrentPassword() {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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"); changePasswordPage.changePassword("", "new", "new");
Assert.assertEquals("Please specify password.", profilePage.getError()); Assert.assertEquals("Please specify password.", profilePage.getError());
@ -305,7 +307,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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"); changePasswordPage.changePassword("password", "1234", "1234");
Assert.assertEquals("Invalid password: minimum length 8.", profilePage.getError()); Assert.assertEquals("Invalid password: minimum length 8.", profilePage.getError());
@ -322,7 +324,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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"); changePasswordPage.changePassword("password", "invalidPassword1", "invalidPassword1");
Assert.assertEquals("Invalid password: must contain at least 2 numerical digits.", profilePage.getError()); Assert.assertEquals("Invalid password: must contain at least 2 numerical digits.", profilePage.getError());
@ -339,7 +341,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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"); changePasswordPage.changePassword("password", "iNVALIDPASSWORD", "iNVALIDPASSWORD");
Assert.assertEquals("Invalid password: must contain at least 2 lower case characters.", profilePage.getError()); 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(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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"); changePasswordPage.changePassword("password", "Invalidpassword", "Invalidpassword");
Assert.assertEquals("Invalid password: must contain at least 2 upper case characters.", profilePage.getError()); 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(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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*"); changePasswordPage.changePassword("password", "invalidPassword*", "invalidPassword*");
Assert.assertEquals("Invalid password: must contain at least 2 special characters.", profilePage.getError()); Assert.assertEquals("Invalid password: must contain at least 2 special characters.", profilePage.getError());
@ -392,7 +394,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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"); changePasswordPage.changePassword("password", "test-user@localhost", "test-user@localhost");
Assert.assertEquals("Invalid password: must not be equal to the username.", profilePage.getError()); Assert.assertEquals("Invalid password: must not be equal to the username.", profilePage.getError());
@ -410,7 +412,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("test-user@localhost", "password"); 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"); changePasswordPage.changePassword("password", "invalidPassword", "invalidPassword");
Assert.assertEquals("Invalid password: fails to match regex pattern(s).", profilePage.getError()); Assert.assertEquals("Invalid password: fails to match regex pattern(s).", profilePage.getError());
@ -456,7 +458,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("user-changePasswordWithPasswordHistoryPolicyThreePasswords", "password"); 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 assertChangePasswordFails ("password", "password"); // current: password
assertNumberOfStoredCredentials(1); assertNumberOfStoredCredentials(1);
@ -491,7 +493,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("user-changePasswordWithPasswordHistoryPolicyTwoPasswords", "password"); 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 assertChangePasswordFails ("password", "password"); // current: password
assertNumberOfStoredCredentials(1); assertNumberOfStoredCredentials(1);
@ -522,7 +524,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("user-changePasswordWithPasswordHistoryPolicyOnePwds", "password"); 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 assertChangePasswordFails ("password", "password"); // current: password
assertNumberOfStoredCredentials(1); assertNumberOfStoredCredentials(1);
@ -543,7 +545,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("user-changePasswordWithPasswordHistoryPolicyZeroPwdsInHistory", "password"); 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 assertChangePasswordFails ("password", "password"); // current: password
assertNumberOfStoredCredentials(1); assertNumberOfStoredCredentials(1);
@ -564,7 +566,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
changePasswordPage.open(); changePasswordPage.open();
loginPage.login("user-changePasswordWithPasswordHistoryPolicyExpiration", "password"); 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); assertNumberOfStoredCredentials(1);
assertChangePasswordSucceeds("password", "password2"); // current: password assertChangePasswordSucceeds("password", "password2"); // current: password
@ -597,7 +599,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
profilePage.open(); profilePage.open();
loginPage.login("test-user@localhost", "password"); 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.getUsername());
Assert.assertEquals("Tom", profilePage.getFirstName()); Assert.assertEquals("Tom", profilePage.getFirstName());
@ -736,7 +738,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
profilePage.open(); profilePage.open();
loginPage.login("test-user@localhost", "password"); 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.getUsername());
Assert.assertEquals("Tom", profilePage.getFirstName()); Assert.assertEquals("Tom", profilePage.getFirstName());
@ -845,7 +847,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
profilePage.open(); profilePage.open();
loginPage.login("test-user@localhost", "password"); 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.getUsername());
Assert.assertEquals("test-user@localhost", profilePage.getEmail()); Assert.assertEquals("test-user@localhost", profilePage.getEmail());
@ -883,7 +885,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
profilePage.open(); profilePage.open();
loginPage.login("test-user@localhost", "password"); 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.getUsername());
Assert.assertEquals("test-user@localhost", profilePage.getEmail()); Assert.assertEquals("test-user@localhost", profilePage.getEmail());
@ -899,7 +901,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
totpPage.open(); totpPage.open();
loginPage.login("test-user@localhost", "password"); 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()); Assert.assertTrue(totpPage.isCurrent());
@ -968,7 +970,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
UserRepresentation noAccessUser = this.findUser("test-user-no-access@localhost"); UserRepresentation noAccessUser = this.findUser("test-user-no-access@localhost");
events.expectLogin().client("account").user(noAccessUser.getId()) events.expectLogin().client("account").user(noAccessUser.getId())
.detail(Details.USERNAME, "test-user-no-access@localhost") .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.assertTrue("Expected errorPage but was " + driver.getTitle() + " (" + driver.getCurrentUrl() + "). Page source: " + driver.getPageSource(), errorPage.isCurrent());
Assert.assertEquals("No access", errorPage.getError()); Assert.assertEquals("No access", errorPage.getError());
@ -1126,7 +1128,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
applicationsPage.open(); applicationsPage.open();
loginPage.login("test-user@localhost", "password"); 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(); applicationsPage.assertCurrent();
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications(); Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
@ -1140,13 +1142,13 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
"Offline access" "Offline access"
)); ));
Assert.assertThat(accountEntry.getClientScopesGranted(), containsInAnyOrder("Full 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"); AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app");
Assert.assertEquals(6, testAppEntry.getRolesAvailable().size()); Assert.assertEquals(6, testAppEntry.getRolesAvailable().size());
Assert.assertTrue(testAppEntry.getRolesAvailable().contains("Offline access")); Assert.assertTrue(testAppEntry.getRolesAvailable().contains("Offline access"));
Assert.assertTrue(testAppEntry.getClientScopesGranted().contains("Full 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"); AccountApplicationsPage.AppEntry thirdPartyEntry = apps.get("third-party");
Assert.assertEquals(3, thirdPartyEntry.getRolesAvailable().size()); 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()); Assert.assertEquals("http://localhost:8180/foo/bar/baz", rootUrlClient.getHref());
AccountApplicationsPage.AppEntry authzApp = apps.get("test-app-authz"); 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"); AccountApplicationsPage.AppEntry namedApp = apps.get("My Named Test App");
Assert.assertEquals("http://localhost:8180/namedapp/base", namedApp.getHref()); Assert.assertEquals("http://localhost:8180/namedapp/base", namedApp.getHref());

View file

@ -352,7 +352,7 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest {
public void conditionalOTPRequestHeaderSkip() { public void conditionalOTPRequestHeaderSkip() {
//prepare config - request header skip, default to force //prepare config - request header skip, default to force
Map<String, String> config = new HashMap<>(); 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(SKIP_OTP_FOR_HTTP_HEADER, "Host: localhost:" + port);
config.put(DEFAULT_OTP_OUTCOME, FORCE); config.put(DEFAULT_OTP_OUTCOME, FORCE);
@ -368,7 +368,7 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest {
public void conditionalOTPRequestHeaderForce() { public void conditionalOTPRequestHeaderForce() {
//prepare config - equest header force, default to skip //prepare config - equest header force, default to skip
Map<String, String> config = new HashMap<>(); 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(FORCE_OTP_FOR_HTTP_HEADER, "Host: localhost:" + port);
config.put(DEFAULT_OTP_OUTCOME, SKIP); config.put(DEFAULT_OTP_OUTCOME, SKIP);

View file

@ -17,6 +17,8 @@
package org.keycloak.testsuite.account.custom; package org.keycloak.testsuite.account.custom;
import javax.ws.rs.core.UriBuilder;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Rule; import org.junit.Rule;
@ -25,6 +27,7 @@ import org.keycloak.events.Details;
import org.keycloak.events.EventType; import org.keycloak.events.EventType;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.resources.account.AccountFormService;
import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.account.AccountFormServiceTest; import org.keycloak.testsuite.account.AccountFormServiceTest;
@ -68,7 +71,7 @@ public class CustomThemeTest extends AbstractTestRealmKeycloakTest {
profilePage.open(); profilePage.open();
loginPage.login("test-user@localhost", "password"); 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("test-user@localhost", profilePage.getEmail());
Assert.assertEquals("", profilePage.getAttribute("street")); 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"); log.info("Setting redirect-uris in test realm '" + tr.getRealm() + "' as " + (isRelative() ? "" : "non-") + "relative");
modifyClientRedirectUris(tr, "http://localhost:8080", ""); 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", ""); modifyClientUrls(tr, "http://localhost:8080", "");
if (isRelative()) { if (isRelative()) {
modifyClientRedirectUris(tr, appServerContextRootPage.toString(), "");
modifyClientUrls(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) + "/"); modifySamlMasterURLs(tr, "/", "http://localhost:" + System.getProperty("auth.server.http.port", null) + "/");
modifySAMLClientsAttributes(tr, "8080", System.getProperty("auth.server.http.port", "8180")); modifySAMLClientsAttributes(tr, "8080", System.getProperty("auth.server.http.port", "8180"));
} else { } else {
modifyClientRedirectUris(tr, "^(/.*/\\*)", appServerContextRootPage.toString() + "$1");
modifyClientUrls(tr, "^(/.*)", appServerContextRootPage.toString() + "$1"); modifyClientUrls(tr, "^(/.*)", appServerContextRootPage.toString() + "$1");
modifyClientWebOrigins(tr, "8080", System.getProperty("app.server.http.port", null)); modifySamlMasterURLs(tr, "8080", AUTH_SERVER_PORT);
modifySamlMasterURLs(tr, "8080", System.getProperty("auth.server.http.port", null));
modifySAMLClientsAttributes(tr, "http://localhost:8080", appServerContextRootPage.toString()); modifySAMLClientsAttributes(tr, "http://localhost:8080", appServerContextRootPage.toString());
modifyClientJWKSUrl(tr, "^(/.*)", appServerContextRootPage.toString() + "$1"); modifyClientJWKSUrl(tr, "^(/.*)", appServerContextRootPage.toString() + "$1");
} }
if ("true".equals(System.getProperty("auth.server.ssl.required"))) { if (AUTH_SERVER_SSL_REQUIRED) {
tr.setSslRequired("all"); tr.setSslRequired("all");
} }
} }
@ -135,14 +143,17 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest {
return testContext.isRelativeAdapterTest(); 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) { if (realm.getClients() != null) {
for (ClientRepresentation client : realm.getClients()) { for (ClientRepresentation client : realm.getClients()) {
List<String> redirectUris = client.getRedirectUris(); List<String> redirectUris = client.getRedirectUris();
if (redirectUris != null) { if (redirectUris != null) {
List<String> newRedirectUris = new ArrayList<>(); List<String> newRedirectUris = new ArrayList<>();
for (String uri : redirectUris) { for (String uri : redirectUris) {
newRedirectUris.add(uri.replaceAll(regex, replacement)); for (String uriReplacement : replacement) {
newRedirectUris.add(uri.replaceAll(regex, uriReplacement));
}
} }
client.setRedirectUris(newRedirectUris); 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) { if (realm.getClients() != null) {
for (ClientRepresentation client : realm.getClients()) { for (ClientRepresentation client : realm.getClients()) {
List<String> webOrigins = client.getWebOrigins(); List<String> webOrigins = client.getWebOrigins();
if (webOrigins != null) { if (webOrigins != null) {
List<String> newWebOrigins = new ArrayList<>(); List<String> newWebOrigins = new ArrayList<>();
for (String uri : webOrigins) { for (String uri : webOrigins) {
newWebOrigins.add(uri.replaceAll(regex, replacement)); for (String originReplacement : replacement) {
newWebOrigins.add(uri.replaceAll(regex, originReplacement));
}
} }
client.setWebOrigins(newWebOrigins); 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.JavaArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert; import org.junit.Assert;
import org.keycloak.testsuite.utils.arquillian.DeploymentArchiveProcessorUtils;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.nio.file.Paths; 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"; EXAMPLES_WEB_XML = EXAMPLES_HOME + "/web.xml";
} }
protected static WebArchive exampleDeployment(String name) throws IOException { protected static WebArchive exampleDeployment(String name) {
return ShrinkWrap.createFromZipFile(WebArchive.class, return exampleDeployment(name, webArchive -> {});
new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war")) }
.addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML);
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 { 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(); URL webXML = Paths.get(EXAMPLES_WEB_XML).toUri().toURL();
String webXmlContent = IOUtils.toString(webXML.openStream(), "UTF-8") String webXmlContent = IOUtils.toString(webXML.openStream(), "UTF-8")
.replace("%CONTEXT_PATH%", contextPath); .replace("%CONTEXT_PATH%", contextPath);
@ -69,12 +96,12 @@ public abstract class AbstractExampleAdapterTest extends AbstractAdapterTest {
new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war")) new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war"))
.addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML) .addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML)
.add(new StringAsset(webXmlContent), "/WEB-INF/web.xml"); .add(new StringAsset(webXmlContent), "/WEB-INF/web.xml");
additionalResources.accept(webArchive);
modifyOIDCAdapterConfig(webArchive);
return 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.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
import org.keycloak.testsuite.util.WaitUtils; import org.keycloak.testsuite.util.WaitUtils;
import org.keycloak.testsuite.utils.arquillian.DeploymentArchiveProcessorUtils;
import org.keycloak.testsuite.utils.io.IOUtil; import org.keycloak.testsuite.utils.io.IOUtil;
import org.openqa.selenium.By; import org.openqa.selenium.By;
@ -51,9 +52,16 @@ public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest {
URL config2Url = AbstractServletsAdapterTest.class.getResource(webInfPath + config2); URL config2Url = AbstractServletsAdapterTest.class.getResource(webInfPath + config2);
Assert.assertNotNull("config2Url should be in " + webInfPath + config2, config2Url); Assert.assertNotNull("config2Url should be in " + webInfPath + config2, config2Url);
return servletDeployment servletDeployment
.add(new UrlAsset(config1Url), "/WEB-INF/classes/" + config1) .add(new UrlAsset(config1Url), "/WEB-INF/classes/" + config1)
.add(new UrlAsset(config2Url), "/WEB-INF/classes/" + config2); .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) { 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.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest; 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(); protected UserRepresentation jdoeUser = UserBuilder.create().username("jdoe").password("jdoe").build();
@BeforeClass
public static void checkIfTLSIsTurnedOn() {
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
}
@Before @Before
public void setDefaultValues() { public void setDefaultValues() {
jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME); jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME);

View file

@ -44,7 +44,7 @@ public class PhotozExampleLazyLoadPathsAdapterTest extends AbstractPhotozExample
@Deployment(name = RESOURCE_SERVER_ID, managed = false, testable = false) @Deployment(name = RESOURCE_SERVER_ID, managed = false, testable = false)
public static WebArchive deploymentResourceServer() throws IOException { public static WebArchive deploymentResourceServer() throws IOException {
return exampleDeployment(RESOURCE_SERVER_ID) return exampleDeployment(RESOURCE_SERVER_ID,
.addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/photoz/keycloak-lazy-load-path-authz-service.json"), "keycloak.json"); 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; 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)
@AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY_DEPRECATED) @AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY_DEPRECATED)
@ -88,7 +95,7 @@ public class CorsExampleAdapterTest extends AbstractExampleAdapterTest {
@JavascriptBrowser @JavascriptBrowser
private Account jsDriverTestRealmAccount; private Account jsDriverTestRealmAccount;
@Deployment(name = AngularCorsProductTestApp.DEPLOYMENT_NAME) @Deployment(name = AngularCorsProductTestApp.DEPLOYMENT_NAME, managed = false)
protected static WebArchive angularCorsProductExample() throws IOException { protected static WebArchive angularCorsProductExample() throws IOException {
return exampleDeployment(AngularCorsProductTestApp.CLIENT_ID); return exampleDeployment(AngularCorsProductTestApp.CLIENT_ID);
} }
@ -108,11 +115,13 @@ public class CorsExampleAdapterTest extends AbstractExampleAdapterTest {
public void onBefore() { public void onBefore() {
Assume.assumeFalse(System.getProperty("os.name").startsWith("Windows")); Assume.assumeFalse(System.getProperty("os.name").startsWith("Windows"));
deployer.deploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME); deployer.deploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME);
deployer.deploy(AngularCorsProductTestApp.DEPLOYMENT_NAME);
} }
@After @After
public void onAfter() { public void onAfter() {
deployer.undeploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME); deployer.undeploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME);
deployer.undeploy(AngularCorsProductTestApp.DEPLOYMENT_NAME);
} }
static{ static{

View file

@ -17,10 +17,19 @@
package org.keycloak.testsuite.adapter.jaas; 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.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.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Scanner;
import java.util.Set; import java.util.Set;
import javax.security.auth.Subject; 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.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.jaas.AbstractKeycloakLoginModule; import org.keycloak.adapters.jaas.AbstractKeycloakLoginModule;
@ -55,11 +67,50 @@ import org.keycloak.testsuite.utils.io.IOUtil;
*/ */
public class LoginModulesTest extends AbstractKeycloakTest { 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 @Override
public void addTestRealms(List<RealmRepresentation> testRealms) { public void addTestRealms(List<RealmRepresentation> testRealms) {
testRealms.add(IOUtil.loadRealm("/adapter-test/demorealm.json")); 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 @Before
public void generateAudienceClientScope() { public void generateAudienceClientScope() {
if (ApiUtil.findClientScopeByName(adminClient.realm("demo"), "customer-db-audience-required") != null) { if (ApiUtil.findClientScopeByName(adminClient.realm("demo"), "customer-db-audience-required") != null) {
@ -76,6 +127,10 @@ public class LoginModulesTest extends AbstractKeycloakTest {
@Test @Test
public void testDirectAccessGrantLoginModuleLoginFailed() throws Exception { public void testDirectAccessGrantLoginModuleLoginFailed() throws Exception {
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
LoginContext loginContext = new LoginContext("does-not-matter", null, LoginContext loginContext = new LoginContext("does-not-matter", null,
createJaasCallbackHandler("bburke@redhat.com", "bad-password"), createJaasCallbackHandler("bburke@redhat.com", "bad-password"),
createJaasConfigurationForDirectGrant(null)); createJaasConfigurationForDirectGrant(null));
@ -91,6 +146,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
@Test @Test
public void testDirectAccessGrantLoginModuleLoginSuccess() throws Exception { public void testDirectAccessGrantLoginModuleLoginSuccess() throws Exception {
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
oauth.realm("demo"); oauth.realm("demo");
LoginContext loginContext = directGrantLogin(null); LoginContext loginContext = directGrantLogin(null);
@ -113,6 +169,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
@Test @Test
public void testBearerLoginFailedLogin() throws Exception { public void testBearerLoginFailedLogin() throws Exception {
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
oauth.realm("demo"); oauth.realm("demo");
LoginContext directGrantCtx = directGrantLogin(null); LoginContext directGrantCtx = directGrantLogin(null);
@ -137,6 +194,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
@Test @Test
public void testBearerLoginSuccess() throws Exception { public void testBearerLoginSuccess() throws Exception {
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
oauth.realm("demo"); oauth.realm("demo");
LoginContext directGrantCtx = directGrantLogin("customer-db-audience-required"); LoginContext directGrantCtx = directGrantLogin("customer-db-audience-required");
@ -213,7 +271,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
@Override @Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name) { public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
Map<String, Object> options = new HashMap<>(); 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) { if (scope != null) {
options.put(DirectAccessGrantsLoginModule.SCOPE_OPTION, scope); options.put(DirectAccessGrantsLoginModule.SCOPE_OPTION, scope);
} }
@ -231,7 +289,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
@Override @Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name) { public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
Map<String, Object> options = new HashMap<>(); 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); AppConfigurationEntry LMConfiguration = new AppConfigurationEntry(BearerTokenLoginModule.class.getName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
return new AppConfigurationEntry[] { LMConfiguration }; return new AppConfigurationEntry[] { LMConfiguration };

View file

@ -112,7 +112,7 @@ public abstract class AbstractJavascriptTest extends AbstractAuthTest {
.client( .client(
ClientBuilder.create() ClientBuilder.create()
.clientId(CLIENT_ID) .clientId(CLIENT_ID)
.redirectUris(JAVASCRIPT_URL + "/*", JAVASCRIPT_ENCODED_SPACE_URL + "/*") .redirectUris(oauth.SERVER_ROOT + JAVASCRIPT_URL + "/*", oauth.SERVER_ROOT + JAVASCRIPT_ENCODED_SPACE_URL + "/*")
.publicClient() .publicClient()
) )
.accessTokenLifespan(30 + TOKEN_LIFESPAN_LEEWAY) .accessTokenLifespan(30 + TOKEN_LIFESPAN_LEEWAY)

View file

@ -94,6 +94,10 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
jsDriver.manage().deleteAllCookies(); jsDriver.manage().deleteAllCookies();
setStandardFlowForClient(); setStandardFlowForClient();
//tests cleanup
oauth.setDriver(driver);
setTimeOffset(0);
} }
protected JSObjectBuilder defaultArguments() { protected JSObjectBuilder defaultArguments() {
@ -175,44 +179,46 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
ClientResource clientResource = ApiUtil.findClientResourceByClientId(adminClient.realm(REALM_NAME), CLIENT_ID); ClientResource clientResource = ApiUtil.findClientResourceByClientId(adminClient.realm(REALM_NAME), CLIENT_ID);
ClientRepresentation client = clientResource.toRepresentation(); ClientRepresentation client = clientResource.toRepresentation();
client.setConsentRequired(true); try {
clientResource.update(client); client.setConsentRequired(true);
clientResource.update(client);
testExecutor.init(defaultArguments(), this::assertInitNotAuth) testExecutor.init(defaultArguments(), this::assertInitNotAuth)
.login(this::assertOnLoginPage) .login(this::assertOnLoginPage)
.loginForm(testUser, (driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1)) .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 // 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() EventRepresentation loginEvent = events.expectLogin()
.client(CLIENT_ID) .client(CLIENT_ID)
.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED)
.detail(Details.REDIRECT_URI, testAppUrl) .detail(Details.REDIRECT_URI, testAppUrl)
.detail(Details.USERNAME, testUser.getUsername()) .detail(Details.USERNAME, testUser.getUsername())
.assertEvent(); .assertEvent();
String codeId = loginEvent.getDetails().get(Details.CODE_ID); String codeId = loginEvent.getDetails().get(Details.CODE_ID);
testExecutor.init(defaultArguments(), this::assertSuccessfullyLoggedIn); testExecutor.init(defaultArguments(), this::assertSuccessfullyLoggedIn);
applicationsPage.navigateTo(); applicationsPage.navigateTo();
events.expectCodeToToken(codeId, loginEvent.getSessionId()).client(CLIENT_ID).assertEvent(); events.expectCodeToToken(codeId, loginEvent.getSessionId()).client(CLIENT_ID).assertEvent();
applicationsPage.revokeGrantForApplication(CLIENT_ID); applicationsPage.revokeGrantForApplication(CLIENT_ID);
events.expect(EventType.REVOKE_GRANT) events.expect(EventType.REVOKE_GRANT)
.client("account") .client("account")
.detail(Details.REVOKED_CLIENT, CLIENT_ID) .detail(Details.REVOKED_CLIENT, CLIENT_ID)
.assertEvent(); .assertEvent();
jsDriver.navigate().to(testAppUrl); jsDriver.navigate().to(testAppUrl);
testExecutor.configure() // need to configure because we refreshed page testExecutor.configure() // need to configure because we refreshed page
.init(defaultArguments(), this::assertInitNotAuth) .init(defaultArguments(), this::assertInitNotAuth)
.login((driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1))); .login((driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1)));
} finally {
// Clean // Clean
client.setConsentRequired(false); client.setConsentRequired(false);
clientResource.update(client); clientResource.update(client);
}
} }
@Test @Test
@ -268,18 +274,20 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
public void implicitFlowOnTokenExpireTest() { public void implicitFlowOnTokenExpireTest() {
RealmRepresentation realm = adminClient.realms().realm(REALM_NAME).toRepresentation(); RealmRepresentation realm = adminClient.realms().realm(REALM_NAME).toRepresentation();
Integer storeAccesTokenLifespan = realm.getAccessTokenLifespanForImplicitFlow(); Integer storeAccesTokenLifespan = realm.getAccessTokenLifespanForImplicitFlow();
realm.setAccessTokenLifespanForImplicitFlow(5); try {
adminClient.realms().realm(REALM_NAME).update(realm); realm.setAccessTokenLifespanForImplicitFlow(5);
adminClient.realms().realm(REALM_NAME).update(realm);
setImplicitFlowForClient(); setImplicitFlowForClient();
testExecutor.logInAndInit(defaultArguments().implicitFlow(), testUser, this::assertSuccessfullyLoggedIn) testExecutor.logInAndInit(defaultArguments().implicitFlow(), testUser, this::assertSuccessfullyLoggedIn)
.addTimeSkew(-5); // Move in time instead of wait .addTimeSkew(-5); // Move in time instead of wait
waitUntilElement(eventsArea).text().contains("Access token expired"); waitUntilElement(eventsArea).text().contains("Access token expired");
} finally {
// Get to origin state // Get to origin state
realm.setAccessTokenLifespanForImplicitFlow(storeAccesTokenLifespan); realm.setAccessTokenLifespanForImplicitFlow(storeAccesTokenLifespan);
adminClient.realms().realm(REALM_NAME).update(realm); adminClient.realms().realm(REALM_NAME).update(realm);
}
} }
@Test @Test
@ -350,8 +358,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
.sendXMLHttpRequest(request, assertResponseStatus(401)) .sendXMLHttpRequest(request, assertResponseStatus(401))
.refreshToken(5, assertEventsContains("Auth Refresh Success")) .refreshToken(5, assertEventsContains("Auth Refresh Success"))
.sendXMLHttpRequest(request, assertResponseStatus(200)); .sendXMLHttpRequest(request, assertResponseStatus(200));
setTimeOffset(0);
} }
@Test @Test
@ -418,27 +424,28 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
// it looks like phantomjs double encode %20 => %25%20 // it looks like phantomjs double encode %20 => %25%20
Assume.assumeTrue("This test doesn't work with phantomjs", !"phantomjs".equals(System.getProperty("js.browser"))); 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() JSObjectBuilder configuration = JSObjectBuilder.create()
.add("url", authServerContextRootPage + "/auth") .add("url", authServerContextRootPage + "/auth")
.add("realm", SPACE_REALM_NAME) .add("realm", SPACE_REALM_NAME)
.add("clientId", CLIENT_ID); .add("clientId", CLIENT_ID);
testAppUrl = authServerContextRootPage + JAVASCRIPT_ENCODED_SPACE_URL + "/index.html"; testAppUrl = authServerContextRootPage + JAVASCRIPT_ENCODED_SPACE_URL + "/index.html";
jsDriver.navigate().to(testAppUrl); jsDriver.navigate().to(testAppUrl);
jsDriverTestRealmLoginPage.setAuthRealm(SPACE_REALM_NAME); jsDriverTestRealmLoginPage.setAuthRealm(SPACE_REALM_NAME);
testExecutor.configure(configuration) testExecutor.configure(configuration)
.init(defaultArguments(), this::assertInitNotAuth) .init(defaultArguments(), this::assertInitNotAuth)
.login(this::assertOnLoginPage) .login(this::assertOnLoginPage)
.loginForm(testUser, this::assertOnTestAppUrl) .loginForm(testUser, this::assertOnTestAppUrl)
.configure(configuration) .configure(configuration)
.init(defaultArguments(), this::assertSuccessfullyLoggedIn); .init(defaultArguments(), this::assertSuccessfullyLoggedIn);
} finally {
// Clean adminClient.realm(SPACE_REALM_NAME).update(RealmBuilder.edit(adminClient.realm(SPACE_REALM_NAME).toRepresentation()).name(REALM_NAME).build());
adminClient.realm(SPACE_REALM_NAME).update(RealmBuilder.edit(adminClient.realm(SPACE_REALM_NAME).toRepresentation()).name(REALM_NAME).build()); jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME);
jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME); }
} }
@Test @Test
@ -460,9 +467,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
.add("refreshToken", refreshToken) .add("refreshToken", refreshToken)
, this::assertSuccessfullyLoggedIn) , this::assertSuccessfullyLoggedIn)
.refreshToken(9999, assertEventsContains("Auth Refresh Success")); .refreshToken(9999, assertEventsContains("Auth Refresh Success"));
oauth.setDriver(driver);
} }
@Test @Test
@ -496,15 +500,12 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
both(greaterThan(-600L - TIME_SKEW_TOLERANCE)) both(greaterThan(-600L - TIME_SKEW_TOLERANCE))
.and(lessThan(-600L + TIME_SKEW_TOLERANCE)) .and(lessThan(-600L + TIME_SKEW_TOLERANCE))
))); )));
setTimeOffset(0);
oauth.setDriver(driver); // Clean
} }
@Test @Test
// KEYCLOAK-4503 // KEYCLOAK-4503
public void initializeWithRefreshToken() { public void initializeWithRefreshToken() {
oauth.setDriver(jsDriver); // Oauth need to login with jsDriver oauth.setDriver(jsDriver); // Oauth need to login with jsDriver
oauth.realm(REALM_NAME); oauth.realm(REALM_NAME);
@ -523,8 +524,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
assertInitNotAuth(driver1, output, events); assertInitNotAuth(driver1, output, events);
waitUntilElement(events).text().not().contains("Auth Success"); waitUntilElement(events).text().not().contains("Auth Success");
}); });
oauth.setDriver(driver); // Clean
} }
@Test @Test

View file

@ -31,7 +31,9 @@ import org.jboss.arquillian.graphene.page.Page;
import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.After; import org.junit.After;
import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest; import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; 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); return servletDeployment(CustomerDb.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class);
} }
@BeforeClass
public static void assumeTLSEnabled() {
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
}
@Before @Before
@Override @Override
public void startServer() { public void startServer() {

View file

@ -27,6 +27,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.testsuite.util.UserBuilder;
@ -61,7 +62,7 @@ public class CrossRealmPermissionsTest extends AbstractKeycloakTest {
.addPassword("password")); .addPassword("password"));
testRealms.add(builder.build()); 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 = RealmBuilder.create().name(REALM2_NAME).testMail();
builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants());
@ -73,7 +74,7 @@ public class CrossRealmPermissionsTest extends AbstractKeycloakTest {
testRealms.add(builder.build()); 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 @Test

View file

@ -48,6 +48,7 @@ import org.keycloak.services.resources.admin.permissions.GroupPermissionManageme
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.ProfileAssume;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.auth.page.AuthRealm;
import org.keycloak.testsuite.runonserver.RunOnServerDeployment; import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
import org.keycloak.testsuite.util.AdminClientUtil; import org.keycloak.testsuite.util.AdminClientUtil;
@ -893,7 +894,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
Assert.assertNotNull(exchanged); Assert.assertNotNull(exchanged);
Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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")); 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", 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); 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()); Assert.assertEquals(0, result.size());
client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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); 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")))); Assert.assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("a"))));
client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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); 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()); Assert.assertEquals("Parsed export type", EntityDescriptorType.class, entBody.getClass());
EntityDescriptorType entity = (EntityDescriptorType) entBody; 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.assertNotNull("ChoiceType not null", entity.getChoiceType());
Assert.assertEquals("ChoiceType.size", 1, entity.getChoiceType().size()); Assert.assertEquals("ChoiceType.size", 1, entity.getChoiceType().size());
@ -667,7 +667,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
IndexedEndpointType endpoint = desc.getAssertionConsumerService().get(0); IndexedEndpointType endpoint = desc.getAssertionConsumerService().get(0);
Assert.assertEquals("AssertionConsumerService.Location", 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", Assert.assertEquals("AssertionConsumerService.Binding",
new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), endpoint.getBinding()); new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), endpoint.getBinding());
Assert.assertTrue("AssertionConsumerService.isDefault", endpoint.isIsDefault()); Assert.assertTrue("AssertionConsumerService.isDefault", endpoint.isIsDefault());
@ -679,7 +679,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
EndpointType sloEndpoint = desc.getSingleLogoutService().get(0); EndpointType sloEndpoint = desc.getSingleLogoutService().get(0);
Assert.assertEquals("SingleLogoutService.Location", 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", Assert.assertEquals("SingleLogoutService.Binding",
new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), sloEndpoint.getBinding()); 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.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.util.AdminClientUtil; import org.keycloak.testsuite.util.AdminClientUtil;
import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.CredentialBuilder; import org.keycloak.testsuite.util.CredentialBuilder;
@ -194,31 +195,31 @@ public class PermissionsTest extends AbstractKeycloakTest {
clients.put(AdminRoles.REALM_ADMIN, clients.put(AdminRoles.REALM_ADMIN,
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client",
"secret")); "secret", TLSUtils.initializeTLS()));
clients.put("none", 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", 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) { 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-admin", adminClient);
clients.put("master-none", clients.put("master-none",
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-none", "password", 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) { for (String role : AdminRoles.ALL_REALM_ROLES) {
clients.put("master-" + role, clients.put("master-" + role,
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-" + role, "password", 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 { 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 @Rule
public AssertEvents events = new AssertEvents(this); public AssertEvents events = new AssertEvents(this);
@ -71,7 +68,7 @@ public class UserTotpTest extends AbstractTestRealmKeycloakTest {
totpPage.open(); totpPage.open();
loginPage.login("test-user@localhost", "password"); 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()); Assert.assertTrue(totpPage.isCurrent());

View file

@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Arrays; import java.util.Arrays;
@ -102,7 +103,7 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest {
.directAccessGrants()) .directAccessGrants())
.client(ClientBuilder.create().clientId("public-client-test") .client(ClientBuilder.create().clientId("public-client-test")
.publicClient() .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()) .directAccessGrants())
.build()); .build());
} }
@ -347,7 +348,11 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest {
} }
private InputStream getAdapterConfiguration(String fileName) { 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) { 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 javax.ws.rs.core.HttpHeaders;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Arrays; 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.ScopePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation; import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.ProfileAssume;
import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.RealmBuilder;
@ -116,7 +116,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest {
.directAccessGrants()) .directAccessGrants())
.client(ClientBuilder.create().clientId("public-client-test") .client(ClientBuilder.create().clientId("public-client-test")
.publicClient() .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()) .directAccessGrants())
.build()); .build());
} }
@ -486,7 +486,11 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest {
} }
private InputStream getAdapterConfiguration(String fileName) { 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) { 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.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -68,7 +70,7 @@ public abstract class AbstractConcurrencyTest extends AbstractTestRealmKeycloakT
ThreadLocal<Keycloak> keycloaks = new ThreadLocal<Keycloak>() { ThreadLocal<Keycloak> keycloaks = new ThreadLocal<Keycloak>() {
@Override @Override
protected Keycloak initialValue() { 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.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import org.apache.http.NameValuePair; import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity; 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.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URLEncodedUtils; 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.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy; import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.junit.Assert; import org.junit.Assert;
@ -89,8 +94,8 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
ClientRepresentation client = ClientBuilder.create() ClientRepresentation client = ClientBuilder.create()
.clientId("client" + i) .clientId("client" + i)
.directAccessGrants() .directAccessGrants()
.redirectUris("http://localhost:8180/auth/realms/master/app/*") .redirectUris("*")
.addWebOrigin("http://localhost:8180") .addWebOrigin("*")
.secret("password") .secret("password")
.build(); .build();
@ -111,7 +116,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
AtomicReference<String> userSessionId = new AtomicReference<>(); AtomicReference<String> userSessionId = new AtomicReference<>();
LoginTask loginTask = null; 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( loginTask = new LoginTask(httpClient, userSessionId, 100, 1, false, Arrays.asList(
createHttpClientContextForUser(httpClient, "test-user@localhost", "password") 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 { protected HttpClientContext createHttpClientContextForUser(final CloseableHttpClient httpClient, String userName, String password) throws IOException {
final HttpClientContext context = HttpClientContext.create(); final HttpClientContext context = HttpClientContext.create();
CookieStore cookieStore = new BasicCookieStore(); CookieStore cookieStore = new BasicCookieStore();
@ -143,7 +157,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
AtomicReference<String> userSessionId = new AtomicReference<>(); AtomicReference<String> userSessionId = new AtomicReference<>();
LoginTask loginTask = null; 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( loginTask = new LoginTask(httpClient, userSessionId, 100, 1, true, Arrays.asList(
createHttpClientContextForUser(httpClient, "test-user@localhost", "password") createHttpClientContextForUser(httpClient, "test-user@localhost", "password")
)); ));
@ -166,7 +180,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
AtomicReference<String> userSessionId = new AtomicReference<>(); AtomicReference<String> userSessionId = new AtomicReference<>();
LoginTask loginTask = null; 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( loginTask = new LoginTask(httpClient, userSessionId, 100, 1, false, Arrays.asList(
createHttpClientContextForUser(httpClient, "test-user@localhost", "password"), createHttpClientContextForUser(httpClient, "test-user@localhost", "password"),
createHttpClientContextForUser(httpClient, "john-doh@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.Assert;
import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.AdminEventPaths;
import org.keycloak.testsuite.util.AssertAdminEvents; import org.keycloak.testsuite.util.AssertAdminEvents;
import org.keycloak.testsuite.util.ClientBuilder; 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) { 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", 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(); UserRepresentation rep = UserBuilder.create().id(appUserId).username("app-user").email("foo@email.org").build();
keycloak.realm("test").users().get(appUserId).update(rep); 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.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.AdminEventPaths;
import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.RoleBuilder; import org.keycloak.testsuite.util.RoleBuilder;
@ -540,7 +541,7 @@ public class GroupTest extends AbstractGroupTest {
createUser(realmName, userName, "pwd"); createUser(realmName, userName, "pwd");
try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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.expect(ClientErrorException.class);
expectedException.expectMessage(String.valueOf(Response.Status.FORBIDDEN.getStatusCode())); expectedException.expectMessage(String.valueOf(Response.Status.FORBIDDEN.getStatusCode()));
@ -569,7 +570,7 @@ public class GroupTest extends AbstractGroupTest {
mappings.realmLevel().add(Collections.singletonList(adminRole)); mappings.realmLevel().add(Collections.singletonList(adminRole));
Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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 assertThat(userClient.realms().findAll(), // Any admin operation will do
not(empty())); not(empty()));
@ -601,7 +602,7 @@ public class GroupTest extends AbstractGroupTest {
realm.users().get(userId).joinGroup(groupId); realm.users().get(userId).joinGroup(groupId);
} }
try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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 assertThat(userClient.realms().findAll(), // Any admin operation will do
not(empty())); not(empty()));
@ -636,7 +637,7 @@ public class GroupTest extends AbstractGroupTest {
mappings.realmLevel().add(Collections.singletonList(adminRole)); mappings.realmLevel().add(Collections.singletonList(adminRole));
} }
try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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 assertThat(userClient.realms().findAll(), // Any admin operation will do
not(empty())); not(empty()));

View file

@ -48,6 +48,7 @@ import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.AbstractAdminTest; import org.keycloak.testsuite.admin.AbstractAdminTest;
import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.auth.page.AuthRealm;
import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.runonserver.RunOnServerDeployment; import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
@ -271,7 +272,7 @@ public class RealmTest extends AbstractAdminTest {
public void loginAfterRemoveRealm() { public void loginAfterRemoveRealm() {
realm.remove(); 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(); client.serverInfo().getInfo();
} }
@ -662,7 +663,7 @@ public class RealmTest extends AbstractAdminTest {
GlobalRequestResult globalRequestResult = realm.pushRevocation(); GlobalRequestResult globalRequestResult = realm.pushRevocation();
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM); 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()); assertNull(globalRequestResult.getFailedRequests());
PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore(); PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore();
@ -684,8 +685,8 @@ public class RealmTest extends AbstractAdminTest {
GlobalRequestResult globalRequestResult = realm.pushRevocation(); GlobalRequestResult globalRequestResult = realm.pushRevocation();
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM); 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"));
assertThat(globalRequestResult.getFailedRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/saml-app/saml")); assertThat(globalRequestResult.getFailedRequests(), Matchers.containsInAnyOrder(oauth.AUTH_SERVER_ROOT + "/realms/master/saml-app/saml"));
PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore(); PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore();
assertEquals(time, adminPushNotBefore.getNotBefore()); assertEquals(time, adminPushNotBefore.getNotBefore());
@ -709,7 +710,7 @@ public class RealmTest extends AbstractAdminTest {
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all", globalRequestResult, ResourceType.REALM); assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all", globalRequestResult, ResourceType.REALM);
assertEquals(1, globalRequestResult.getSuccessRequests().size()); 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()); assertNull(globalRequestResult.getFailedRequests());
assertNotNull(testingClient.testApp().getAdminLogoutAction()); assertNotNull(testingClient.testApp().getAdminLogoutAction());

View file

@ -75,7 +75,7 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
.directAccessGrants() .directAccessGrants()
.serviceAccountsEnabled(true)) .serviceAccountsEnabled(true))
.client(ClientBuilder.create().clientId("test-app") .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()) .publicClient())
.build()); .build());
} }
@ -165,7 +165,11 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
} }
protected AuthzClient getAuthzClient() { 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) { 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.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import java.io.IOException;
import java.util.List; import java.util.List;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
@ -208,6 +209,10 @@ public class AuthorizationAPITest extends AbstractAuthzTest {
} }
private AuthzClient getAuthzClient(String configFile) { 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()) .directAccessGrants())
.client(ClientBuilder.create().clientId(PUBLIC_TEST_CLIENT) .client(ClientBuilder.create().clientId(PUBLIC_TEST_CLIENT)
.secret("secret") .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()) .publicClient())
.build()); .build());
} }
@ -1374,7 +1374,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
if (authzClient == null) { if (authzClient == null) {
Configuration configuration; Configuration configuration;
try { 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) { } catch (IOException e) {
throw new RuntimeException("Failed to read configuration", e); throw new RuntimeException("Failed to read configuration", e);
} }

View file

@ -451,6 +451,10 @@ public class PermissionClaimTest extends AbstractAuthzTest {
} }
private AuthzClient getAuthzClient() { 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) .fullScopeEnabled(true)
.protocol(SamlProtocol.LOGIN_PROTOCOL) .protocol(SamlProtocol.LOGIN_PROTOCOL)
.baseUrl("http://localhost:8080/sales-post") .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_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE)
.attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE) .attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE)
.build(), .build(),
@ -163,7 +164,8 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
.fullScopeEnabled(true) .fullScopeEnabled(true)
.protocol(SamlProtocol.LOGIN_PROTOCOL) .protocol(SamlProtocol.LOGIN_PROTOCOL)
.baseUrl("http://localhost:8080/sales-post") .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_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE)
.attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE) .attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE)
.build(), .build(),

View file

@ -138,7 +138,7 @@ public class KcSamlBrokerTest extends AbstractBrokerTest {
// KEYCLOAK-6106 // KEYCLOAK-6106
@Test @Test
public void loginClientWithDotsInName() throws Exception { 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); Document doc = SAML2Request.convert(loginRep);

View file

@ -1,6 +1,5 @@
package org.keycloak.testsuite.broker; package org.keycloak.testsuite.broker;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.broker.saml.SAMLIdentityProviderConfig; import org.keycloak.broker.saml.SAMLIdentityProviderConfig;
import org.keycloak.crypto.Algorithm; import org.keycloak.crypto.Algorithm;
import org.keycloak.dom.saml.v2.protocol.AuthnRequestType; import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
@ -210,7 +209,7 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
// KEYCLOAK-5581 // KEYCLOAK-5581
@Test @Test
public void loginUserAllNamespacesInTopElement() { 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; Document doc;
try { try {

View file

@ -1,9 +1,11 @@
package org.keycloak.testsuite.cli; package org.keycloak.testsuite.cli;
import org.junit.Assert; import org.junit.Assert;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.cli.exec.AbstractExec; import org.keycloak.testsuite.cli.exec.AbstractExec;
import java.io.File;
import java.util.List; import java.util.List;
/** /**
@ -11,6 +13,23 @@ import java.util.List;
*/ */
public abstract class AbstractCliTest extends AbstractKeycloakTest { 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) { public void assertExitCodeAndStdOutSize(AbstractExec exe, int exitCode, int stdOutLineCount) {
assertExitCodeAndStreamSizes(exe, exitCode, stdOutLineCount, -1); assertExitCodeAndStreamSizes(exe, exitCode, stdOutLineCount, -1);

View file

@ -17,6 +17,13 @@
package org.keycloak.testsuite.cli; 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.container.test.api.Deployment;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.spec.WebArchive;
@ -26,17 +33,22 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.UserResource; 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.authentication.requiredactions.TermsAndConditions;
import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.credential.CredentialModel; 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.DefaultAuthenticationFlows;
import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation; 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.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.actions.DummyRequiredActionFactory; import org.keycloak.testsuite.actions.DummyRequiredActionFactory;
import org.keycloak.testsuite.authentication.PushButtonAuthenticator;
import org.keycloak.testsuite.authentication.PushButtonAuthenticatorFactory; 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.pages.LoginPage;
import org.keycloak.testsuite.runonserver.RunOnServerDeployment; import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
import org.keycloak.testsuite.util.GreenMailRule; import org.keycloak.testsuite.util.GreenMailRule;
import org.keycloak.testsuite.util.MailUtils; import org.keycloak.testsuite.util.MailUtils;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.util.JsonSerialization;
import org.keycloak.utils.TotpUtils; import org.keycloak.utils.TotpUtils;
import org.openqa.selenium.By; 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 * Test that clients can override auth flows
* *
@ -111,7 +109,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
ClientModel kcinit = realm.addClient(KCINIT_CLIENT); ClientModel kcinit = realm.addClient(KCINIT_CLIENT);
kcinit.setEnabled(true); kcinit.setEnabled(true);
kcinit.addRedirectUri("http://localhost:*"); kcinit.addRedirectUri("*");
kcinit.setPublicClient(true); kcinit.setPublicClient(true);
kcinit.removeRole(realm.getRole(OAuth2Constants.OFFLINE_ACCESS)); kcinit.removeRole(realm.getRole(OAuth2Constants.OFFLINE_ACCESS));
@ -239,7 +237,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
.executeAsync(); .executeAsync();
exe.waitForStderr("Open browser and continue login? [y/n]"); exe.waitForStderr("Open browser and continue login? [y/n]");
exe.sendLine("y"); exe.sendLine("y");
exe.waitForStdout("http://"); exe.waitForStdout("http");
// the --fake-browser skips launching a browser and outputs url to stdout // the --fake-browser skips launching a browser and outputs url to stdout
String redirect = exe.stdoutString().trim(); String redirect = exe.stdoutString().trim();
@ -312,7 +310,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
exe.waitForStderr("Open browser and continue login? [y/n]"); exe.waitForStderr("Open browser and continue login? [y/n]");
exe.sendLine("y"); exe.sendLine("y");
exe.waitForStdout("http://"); exe.waitForStdout("http");
// the --fake-browser skips launching a browser and outputs url to stdout // the --fake-browser skips launching a browser and outputs url to stdout
String redirect = exe.stdoutString().trim(); String redirect = exe.stdoutString().trim();
@ -348,7 +346,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
//exe.waitForStderr("(y/n):"); //exe.waitForStderr("(y/n):");
//exe.sendLine("n"); //exe.sendLine("n");
exe.waitForStderr("Authentication server URL [http://localhost:8080/auth]:"); 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()); //System.out.println(exe.stderrString());
exe.waitForStderr("Name of realm [master]:"); exe.waitForStderr("Name of realm [master]:");
exe.sendLine("test"); exe.sendLine("test");

View file

@ -11,6 +11,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.cli.AbstractCliTest; import org.keycloak.testsuite.cli.AbstractCliTest;
import org.keycloak.testsuite.cli.KcAdmExec; import org.keycloak.testsuite.cli.KcAdmExec;
import org.keycloak.testsuite.cli.KcRegExec;
import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.testsuite.util.UserBuilder;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
@ -37,40 +38,14 @@ import static org.keycloak.testsuite.cli.KcAdmExec.execute;
*/ */
public abstract class AbstractAdmCliTest extends AbstractCliTest { public abstract class AbstractAdmCliTest extends AbstractCliTest {
protected String serverUrl = isAuthServerSSL() ?
"https://localhost:" + getAuthServerHttpsPort() + "/auth" :
"http://localhost:" + getAuthServerHttpPort() + "/auth";
static boolean runIntermittentlyFailingTests() { static boolean runIntermittentlyFailingTests() {
return "true".equals(System.getProperty("test.intermittent")); return "true".equals(System.getProperty("test.intermittent"));
} }
static boolean isAuthServerSSL() {
return "true".equals(System.getProperty("auth.server.ssl.required"));
}
static File getDefaultConfigFilePath() { static File getDefaultConfigFilePath() {
return new File(System.getProperty("user.home") + "/.keycloak/kcadm.config"); 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 @Override
public void addTestRealms(List<RealmRepresentation> testRealms) { 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); 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); assertExitCodeAndStreamSizes(exe, 0, 0, 1 - linecountOffset);
lastModified2 = configFile.exists() ? configFile.lastModified() : 0; 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 + KcAdmExec exe = KcAdmExec.execute("config credentials --server " + server + " --realm " + realm +
" --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath()); " --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath());
Assert.assertEquals("exitCode == 0", 0, exe.exitCode()); assertExitCodeAndStreamSizes(exe, 0, 0, 1);
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));
} }
} }

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. * 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. * 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.realm("master");
oauth.clientId("admin-cli"); oauth.clientId("admin-cli");
String token = oauth.doGrantAccessTokenRequest("", "admin", "admin").getAccessToken(); 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)); 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 // 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'"); System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'");
return; return;
} }
@ -51,7 +51,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest {
// perform authentication against server - asks for password, then for truststore password // perform authentication against server - asks for password, then for truststore password
exe = KcAdmExec.newBuilder() 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() + "'") " --config '" + configFile.getName() + "'")
.executeAsync(); .executeAsync();
@ -71,7 +71,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest {
// perform authentication against server - asks for password, then for truststore password // perform authentication against server - asks for password, then for truststore password
exe = KcAdmExec.newBuilder() 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() + "'") " --config '" + configFile.getName() + "'")
.executeAsync(); .executeAsync();

View file

@ -2,6 +2,7 @@ package org.keycloak.testsuite.cli.registration;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.ClientInitialAccessResource; import org.keycloak.admin.client.resource.ClientInitialAccessResource;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator; 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 { public abstract class AbstractRegCliTest extends AbstractCliTest {
protected String serverUrl = isAuthServerSSL() ?
"https://localhost:" + getAuthServerHttpsPort() + "/auth" :
"http://localhost:" + getAuthServerHttpPort() + "/auth";
@Before @Before
public void deleteDefaultConfig() { public void deleteDefaultConfig() {
getDefaultConfigFilePath().delete(); getDefaultConfigFilePath().delete();
@ -61,33 +57,10 @@ public abstract class AbstractRegCliTest extends AbstractCliTest {
return "true".equals(System.getProperty("test.intermittent")); 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() { static File getDefaultConfigFilePath() {
return new File(System.getProperty("user.home") + "/.keycloak/kcreg.config"); return new File(System.getProperty("user.home") + "/.keycloak/kcreg.config");
} }
@Override @Override
public void addTestRealms(List<RealmRepresentation> testRealms) { public void addTestRealms(List<RealmRepresentation> testRealms) {
RealmRepresentation realmRepresentation = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); RealmRepresentation realmRepresentation = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class);
@ -159,23 +132,13 @@ public abstract class AbstractRegCliTest extends AbstractCliTest {
.build(); .build();
realmRepresentation.getClients().add(regClient); realmRepresentation.getClients().add(regClient);
} }
void loginAsUser(File configFile, String server, String realm, String user, String password) { void loginAsUser(File configFile, String server, String realm, String user, String password) {
KcRegExec exe = execute("config credentials --server " + server + " --realm " + realm + KcRegExec exe = execute("config credentials --server " + server + " --realm " + realm +
" --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath()); " --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath());
Assert.assertEquals("exitCode == 0", 0, exe.exitCode()); assertExitCodeAndStreamSizes(exe, 0, 0, 1);
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));
} }
void assertFieldsEqualWithExclusions(ConfigData config1, ConfigData config2, String ... excluded) { 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.hamcrest.Matchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ClientResource;
@ -32,6 +34,11 @@ import static org.keycloak.testsuite.cli.KcRegExec.execute;
*/ */
public class KcRegCreateTest extends AbstractRegCliTest { public class KcRegCreateTest extends AbstractRegCliTest {
@Before
public void assumeTLSEnabled() {
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
}
@Test @Test
public void testCreateWithRealmOverride() throws IOException { public void testCreateWithRealmOverride() throws IOException {
@ -41,15 +48,15 @@ public class KcRegCreateTest extends AbstractRegCliTest {
// authenticate as a regular user against one realm // authenticate as a regular user against one realm
KcRegExec exe = execute("config credentials -x --config '" + configFile.getName() + 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 // use initial token of another realm with server, and realm override
String token = issueInitialAccessToken("test"); 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"; final String realm = "test";
KcRegExec exe = execute("config initial-token -x --config '" + configFile.getName() + 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); assertExitCodeAndStreamSizes(exe, 0, 0, 0);
// check that current server, realm, and initial token are saved in the file // check that current server, realm, and initial token are saved in the file
ConfigData config = handler.loadConfig(); 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 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 // create configuration from file using stdin redirect ... output an object
String content = "{\n" + String content = "{\n" +
@ -96,9 +103,9 @@ public class KcRegCreateTest extends AbstractRegCliTest {
try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) { 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); ClientRepresentation client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
Assert.assertNotNull("id", client.getId()); Assert.assertNotNull("id", client.getId());
@ -119,12 +126,12 @@ public class KcRegCreateTest extends AbstractRegCliTest {
Assert.assertNull("mappers are null", client.getProtocolMappers()); Assert.assertNull("mappers are null", client.getProtocolMappers());
// create configuration from file as a template and override clientId and other attributes ... output an object // 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 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 '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"); " -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); ClientRepresentation client2 = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
Assert.assertNotNull("id", client2.getId()); Assert.assertNotNull("id", client2.getId());
@ -152,16 +159,16 @@ public class KcRegCreateTest extends AbstractRegCliTest {
} }
// simple create, output an id // 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)); Assert.assertEquals("only clientId returned", "my_client3", exe.stdoutLines().get(0));
// simple create, default output // 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); assertExitCodeAndStreamSizes(exe, 0, 0, 3);
Assert.assertEquals("only clientId returned", "Registered new client with client_id 'my_client4'", exe.stderrLines().get(0)); 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))) { 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" + " -s 'redirect_uris=[\"http://localhost:8980/myapp5/*\"]' -s client_uri=http://localhost:8980/myapp5" +
" -o -f - < '" + tmpFile.getName() + "'"); " -o -f - < '" + tmpFile.getName() + "'");
assertExitCodeAndStdErrSize(exe, 0, 0); assertExitCodeAndStdErrSize(exe, 0, 2);
OIDCClientRepresentation client = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class); 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"); 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()); 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); ClientRepresentation client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
Assert.assertNotNull("id", client.getId()); Assert.assertNotNull("id", client.getId());
@ -219,7 +226,7 @@ public class KcRegCreateTest extends AbstractRegCliTest {
// delete initial token // 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); assertExitCodeAndStreamSizes(exe, 0, 0, 0);
config = handler.loadConfig(); config = handler.loadConfig();
@ -234,12 +241,12 @@ public class KcRegCreateTest extends AbstractRegCliTest {
try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) { try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) {
KcRegExec exe = execute("config credentials -x --config '" + configFile.getName() + 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);
String token = issueInitialAccessToken("test"); String token = issueInitialAccessToken("test");
exe = execute("create --config '" + configFile.getName() + "' --server " + serverUrl + " --realm test -s clientId=authz-client -s authorizationServicesEnabled=true -t " + token); 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, 1); assertExitCodeAndStreamSizes(exe, 0, 0, 3);
RealmResource realm = adminClient.realm("test"); RealmResource realm = adminClient.realm("test");
ClientsResource clients = realm.clients(); ClientsResource clients = realm.clients();
@ -271,11 +278,11 @@ public class KcRegCreateTest extends AbstractRegCliTest {
try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) { 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" + " -s 'redirect_uris=[\"http://localhost:8980/myapp5/*\"]' -s client_uri=http://localhost:8980/myapp5" +
" -o -f - < '" + tmpFile.getName() + "'"); " -o -f - < '" + tmpFile.getName() + "'");
assertExitCodeAndStdErrSize(exe, 0, 0); assertExitCodeAndStdErrSize(exe, 0, 2);
OIDCClientRepresentation oidcClient = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class); OIDCClientRepresentation oidcClient = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class);

View file

@ -1,6 +1,7 @@
package org.keycloak.testsuite.cli.registration; package org.keycloak.testsuite.cli.registration;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test; import org.junit.Test;
import org.keycloak.client.registration.cli.config.ConfigData; import org.keycloak.client.registration.cli.config.ConfigData;
import org.keycloak.client.registration.cli.config.FileConfigHandler; import org.keycloak.client.registration.cli.config.FileConfigHandler;
@ -571,24 +572,25 @@ public class KcRegTest extends AbstractRegCliTest {
} }
@Test @Test
public void testCreateDeleteWithInitialAndRegistrationTokens() throws IOException { public void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption() throws IOException {
/* /*
* Test create using initial client token, and subsequent delete using registration access token. * 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. * A config file is used to save registration access token for newly created client.
*/ */
testCreateDeleteWithInitialAndRegistrationTokens(true); testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption(true);
} }
@Test @Test
public void testCreateDeleteWithInitialAndRegistrationTokensNoConfig() throws IOException { public void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOptionNoConfig() throws IOException {
/* /*
* Test create using initial client token, and subsequent delete using registration access token. * 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. * 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 // prepare for loading a config file
// only used when useConfig is true // only used when useConfig is true
@ -601,7 +603,7 @@ public class KcRegTest extends AbstractRegCliTest {
final String realm = "master"; final String realm = "master";
KcRegExec exe = execute("create " + (useConfig ? ("--config '" + configFile.getAbsolutePath()) + "'" : "--no-config") 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()); Assert.assertEquals("exitCode == 0", 0, exe.exitCode());
@ -615,15 +617,15 @@ public class KcRegTest extends AbstractRegCliTest {
if (useConfig) { if (useConfig) {
ConfigData config = handler.loadConfig(); ConfigData config = handler.loadConfig();
Assert.assertEquals("Registration Access Token in config file", client.getRegistrationAccessToken(), 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 { } else {
Assert.assertFalse("There should be no config file", configFile.isFile()); Assert.assertFalse("There should be no config file", configFile.isFile());
} }
exe = execute("delete test-client2 " + (useConfig ? ("--config '" + configFile.getAbsolutePath()) + "'" : "--no-config") 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)); 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 // 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'"); System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'");
return; return;
} }
@ -51,7 +51,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest {
// perform authentication against server - asks for password, then for truststore password // perform authentication against server - asks for password, then for truststore password
exe = KcRegExec.newBuilder() 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() + "'") " --config '" + configFile.getName() + "'")
.executeAsync(); .executeAsync();
@ -71,7 +71,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest {
// perform authentication against server - asks for password, then for truststore password // perform authentication against server - asks for password, then for truststore password
exe = KcRegExec.newBuilder() 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() + "'") " --config '" + configFile.getName() + "'")
.executeAsync(); .executeAsync();

View file

@ -9,6 +9,7 @@ import org.keycloak.models.Constants;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.arquillian.ContainerInfo; import org.keycloak.testsuite.arquillian.ContainerInfo;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.util.ContainerAssume; import org.keycloak.testsuite.util.ContainerAssume;
@ -118,7 +119,7 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest {
protected Keycloak createAdminClientFor(ContainerInfo node) { protected Keycloak createAdminClientFor(ContainerInfo node) {
log.info("Initializing admin client for " + node.getContextRoot() + "/auth"); log.info("Initializing admin client for " + node.getContextRoot() + "/auth");
return Keycloak.getInstance(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) { protected KeycloakTestingClient createTestingClientFor(ContainerInfo node) {

View file

@ -94,7 +94,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
.name("REALM_COMPOSITE_1_APPLICATION") .name("REALM_COMPOSITE_1_APPLICATION")
.fullScopeEnabled(Boolean.FALSE) .fullScopeEnabled(Boolean.FALSE)
// addScopeMapping(realmComposite1) // 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") .baseUrl("http://localhost:8180/auth/realms/master/app/auth")
.adminUrl("http://localhost:8180/auth/realms/master/app/logout") .adminUrl("http://localhost:8180/auth/realms/master/app/logout")
.secret("password"); .secret("password");
@ -105,7 +105,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
.name("REALM_ROLE_1_APPLICATION") .name("REALM_ROLE_1_APPLICATION")
.fullScopeEnabled(Boolean.FALSE) .fullScopeEnabled(Boolean.FALSE)
// addScopeMapping(realmRole1) // 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") .baseUrl("http://localhost:8180/auth/realms/master/app/auth")
.adminUrl("http://localhost:8180/auth/realms/master/app/logout") .adminUrl("http://localhost:8180/auth/realms/master/app/logout")
.secret("password"); .secret("password");
@ -115,7 +115,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
.clientId("APP_ROLE_APPLICATION") .clientId("APP_ROLE_APPLICATION")
.name("APP_ROLE_APPLICATION") .name("APP_ROLE_APPLICATION")
.fullScopeEnabled(Boolean.FALSE) .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") .baseUrl("http://localhost:8180/auth/realms/master/app/auth")
.adminUrl("http://localhost:8180/auth/realms/master/app/logout") .adminUrl("http://localhost:8180/auth/realms/master/app/logout")
.defaultRoles("APP_ROLE_1", "APP_ROLE_2") .defaultRoles("APP_ROLE_1", "APP_ROLE_2")
@ -139,7 +139,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
.fullScopeEnabled(Boolean.FALSE) .fullScopeEnabled(Boolean.FALSE)
//.scopeMapping(appRole2) //.scopeMapping(appRole2)
.defaultRoles("APP_COMPOSITE_ROLE") .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") .baseUrl("http://localhost:8180/auth/realms/master/app/auth")
.adminUrl("http://localhost:8180/auth/realms/master/app/logout") .adminUrl("http://localhost:8180/auth/realms/master/app/logout")
.secret("password"); .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.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient; 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.junit.Test;
import org.keycloak.testsuite.arquillian.annotation.InitialDcState; import org.keycloak.testsuite.arquillian.annotation.InitialDcState;
@ -75,7 +73,7 @@ public class ConcurrentLoginCrossDCTest extends ConcurrentLoginTest {
AtomicReference<String> userSessionId = new AtomicReference<>(); AtomicReference<String> userSessionId = new AtomicReference<>();
LoginTask loginTask = null; 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( loginTask = new LoginTask(httpClient, userSessionId, LOGIN_TASK_DELAY_MS, LOGIN_TASK_RETRIES, false, Arrays.asList(
createHttpClientContextForUser(httpClient, "test-user@localhost", "password") createHttpClientContextForUser(httpClient, "test-user@localhost", "password")
)); ));

View file

@ -92,8 +92,9 @@ public class SessionExpirationCrossDCTest extends AbstractAdminCrossDCTest {
ClientRepresentation client = ClientBuilder.create() ClientRepresentation client = ClientBuilder.create()
.clientId("test-app") .clientId("test-app")
.directAccessGrants() .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("http://localhost:8180")
.addWebOrigin("https://localhost:8543")
.secret("password") .secret("password")
.build(); .build();

View file

@ -88,6 +88,8 @@ public class ChallengeFlowTest extends AbstractTestRealmKeycloakTest {
@Before @Before
public void setupFlows() { public void setupFlows() {
SerializableApplicationData serializedApplicationData = new SerializableApplicationData(oauth.APP_AUTH_ROOT, oauth.APP_ROOT + "/admin", oauth.APP_AUTH_ROOT + "/*");
testingClient.server().run(session -> { testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test"); RealmModel realm = session.realms().getRealmByName("test");
@ -116,10 +118,10 @@ public class ChallengeFlowTest extends AbstractTestRealmKeycloakTest {
client = realm.addClient(TEST_APP_FLOW); client = realm.addClient(TEST_APP_FLOW);
client.setSecret("password"); client.setSecret("password");
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
client.setEnabled(true); 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.addRedirectUri("urn:ietf:wg:oauth:2.0:oob");
client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId()); client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId());
client.setPublicClient(false); client.setPublicClient(false);

View file

@ -17,7 +17,6 @@
package org.keycloak.testsuite.forms; package org.keycloak.testsuite.forms;
import org.apache.http.client.utils.URLEncodedUtils;
import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import org.jboss.shrinkwrap.api.spec.WebArchive; 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.HttpHeaders;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.nio.charset.Charset;
import java.util.List; import java.util.List;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -99,9 +97,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
.addPackages(true, "org.keycloak.testsuite"); .addPackages(true, "org.keycloak.testsuite");
} }
@Before @Before
public void setupFlows() { public void setupFlows() {
SerializableApplicationData serializedApplicationData = new SerializableApplicationData(oauth.APP_AUTH_ROOT, oauth.APP_ROOT + "/admin", oauth.APP_AUTH_ROOT + "/*");
testingClient.server().run(session -> { testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test"); RealmModel realm = session.realms().getRealmByName("test");
@ -113,8 +112,6 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
client = session.realms().getClientByClientId("test-app", realm); client = session.realms().getClientByClientId("test-app", realm);
client.setDirectAccessGrantsEnabled(true); client.setDirectAccessGrantsEnabled(true);
// Parent flow // Parent flow
AuthenticationFlowModel browser = new AuthenticationFlowModel(); AuthenticationFlowModel browser = new AuthenticationFlowModel();
browser.setAlias("parent-flow"); browser.setAlias("parent-flow");
@ -163,10 +160,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
client = realm.addClient(TEST_APP_FLOW); client = realm.addClient(TEST_APP_FLOW);
client.setSecret("password"); client.setSecret("password");
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
client.setEnabled(true); 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.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId());
client.setPublicClient(false); client.setPublicClient(false);
@ -206,10 +203,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
client = realm.addClient(TEST_APP_DIRECT_OVERRIDE); client = realm.addClient(TEST_APP_DIRECT_OVERRIDE);
client.setSecret("password"); client.setSecret("password");
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
client.setEnabled(true); client.setEnabled(true);
client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*"); client.addRedirectUri(serializedApplicationData.applicationRedirectUrl);
client.setPublicClient(false); client.setPublicClient(false);
client.setDirectAccessGrantsEnabled(true); client.setDirectAccessGrantsEnabled(true);
client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId()); client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId());
@ -218,10 +215,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
client = realm.addClient(TEST_APP_HTTP_CHALLENGE); client = realm.addClient(TEST_APP_HTTP_CHALLENGE);
client.setSecret("password"); client.setSecret("password");
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth"); client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin"); client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
client.setEnabled(true); client.setEnabled(true);
client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*"); client.addRedirectUri(serializedApplicationData.applicationRedirectUrl);
client.setPublicClient(true); client.setPublicClient(true);
client.setDirectAccessGrantsEnabled(true); client.setDirectAccessGrantsEnabled(true);
client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.DIRECT_GRANT_BINDING, realm.getFlowByAlias("http challenge").getId()); 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.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE);
form.param(OAuth2Constants.CLIENT_ID, TEST_APP_HTTP_CHALLENGE); 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)); form.param(OAuth2Constants.CODE, location.substring(location.indexOf(OAuth2Constants.CODE) + OAuth2Constants.CODE.length() + 1));
// exchange code to token // exchange code to token

View file

@ -73,7 +73,7 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
String sessionId = events.expectLogin().assertEvent().getSessionId(); 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(); String logoutUrl = oauth.getLogoutUrl().redirectUri(redirectUri).build();
driver.navigate().to(logoutUrl); driver.navigate().to(logoutUrl);
@ -130,8 +130,8 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
events.expectLogin().session(sessionId).removeDetail(Details.USERNAME).assertEvent(); events.expectLogin().session(sessionId).removeDetail(Details.USERNAME).assertEvent();
// Logout session 1 by redirect // Logout session 1 by redirect
driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build()); driver.navigate().to(oauth.getLogoutUrl().redirectUri(oauth.APP_AUTH_ROOT).build());
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent(); events.expectLogout(sessionId).detail(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT).assertEvent();
// Check session 1 not logged-in // Check session 1 not logged-in
oauth.openLoginForm(); oauth.openLoginForm();
@ -147,8 +147,8 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
events.expectLogin().session(sessionId3).removeDetail(Details.USERNAME).assertEvent(); events.expectLogin().session(sessionId3).removeDetail(Details.USERNAME).assertEvent();
// Logout session 3 by redirect // Logout session 3 by redirect
driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build()); driver.navigate().to(oauth.getLogoutUrl().redirectUri(oauth.APP_AUTH_ROOT).build());
events.expectLogout(sessionId3).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent(); events.expectLogout(sessionId3).detail(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT).assertEvent();
} }
//KEYCLOAK-2741 //KEYCLOAK-2741

View file

@ -60,6 +60,11 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
public void configureTestRealm(RealmRepresentation testRealm) { public void configureTestRealm(RealmRepresentation testRealm) {
} }
@Override
protected boolean modifyRealmForSSL() {
return true;
}
@Before @Before
public void setup() { public void setup() {
UserRepresentation user = UserBuilder.create() UserRepresentation user = UserBuilder.create()
@ -269,15 +274,16 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
// KEYCLOAK-5797 // KEYCLOAK-5797
@Test @Test
public void loginWithDifferentClients() throws Exception { public void loginWithDifferentClients() throws Exception {
// Open tab1 and start login here String redirectUri = String.format("%s://localhost:%s/foo/bar/baz", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT);
oauth.openLoginForm(); // Open tab1 and start login here
loginPage.assertCurrent(); oauth.openLoginForm();
loginPage.login("login-test", "bad-password"); loginPage.assertCurrent();
String tab1Url = driver.getCurrentUrl(); loginPage.login("login-test", "bad-password");
String tab1Url = driver.getCurrentUrl();
// Go to tab2 and start login with different client "root-url-client" // Go to tab2 and start login with different client "root-url-client"
oauth.clientId("root-url-client"); oauth.clientId("root-url-client");
oauth.redirectUri("http://localhost:8180/foo/bar/baz"); oauth.redirectUri(redirectUri);
oauth.openLoginForm(); oauth.openLoginForm();
loginPage.assertCurrent(); loginPage.assertCurrent();
String tab2Url = driver.getCurrentUrl(); 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 // Go back to tab2 and finish login here. Should be on the root-url-client page
driver.navigate().to(tab2Url); driver.navigate().to(tab2Url);
String currentUrl = driver.getCurrentUrl(); String currentUrl = driver.getCurrentUrl();
Assert.assertThat(currentUrl, Matchers.startsWith("http://localhost:8180/foo/bar/baz")); Assert.assertThat(currentUrl, Matchers.startsWith(redirectUri));
} }
// KEYCLOAK-5938 // KEYCLOAK-5938
@Test @Test
public void loginWithSameClientDifferentStatesLoginInTab1() throws Exception { 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 // Open tab1 and start login here
oauth.stateParamHardcoded("state1"); oauth.stateParamHardcoded("state1");
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix1"); oauth.redirectUri(redirectUri1);
oauth.openLoginForm(); oauth.openLoginForm();
loginPage.assertCurrent(); loginPage.assertCurrent();
loginPage.login("login-test", "bad-password"); 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" // Go to tab2 and start login with different client "root-url-client"
oauth.stateParamHardcoded("state2"); oauth.stateParamHardcoded("state2");
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix2"); oauth.redirectUri(redirectUri2);
oauth.openLoginForm(); oauth.openLoginForm();
loginPage.assertCurrent(); loginPage.assertCurrent();
String tab2Url = driver.getCurrentUrl(); 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 // Assert I am redirected to the appPage in tab1 and have state corresponding to tab1
appPage.assertCurrent(); appPage.assertCurrent();
String currentUrl = driver.getCurrentUrl(); 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")); Assert.assertTrue(currentUrl.contains("state1"));
} }
@ -333,9 +341,11 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
// KEYCLOAK-5938 // KEYCLOAK-5938
@Test @Test
public void loginWithSameClientDifferentStatesLoginInTab2() throws Exception { 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 // Open tab1 and start login here
oauth.stateParamHardcoded("state1"); oauth.stateParamHardcoded("state1");
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix1"); oauth.redirectUri(redirectUri1);
oauth.openLoginForm(); oauth.openLoginForm();
loginPage.assertCurrent(); loginPage.assertCurrent();
loginPage.login("login-test", "bad-password"); 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" // Go to tab2 and start login with different client "root-url-client"
oauth.stateParamHardcoded("state2"); oauth.stateParamHardcoded("state2");
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix2"); oauth.redirectUri(redirectUri2);
oauth.openLoginForm(); oauth.openLoginForm();
loginPage.assertCurrent(); loginPage.assertCurrent();
String tab2Url = driver.getCurrentUrl(); 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 // Assert I am redirected to the appPage in tab2 and have state corresponding to tab2
appPage.assertCurrent(); appPage.assertCurrent();
String currentUrl = driver.getCurrentUrl(); 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")); 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); Response response = executeGrantAccessTokenRequest(grantTarget);
assertEquals(403, response.getStatus()); assertEquals(AUTH_SERVER_SSL_REQUIRED ? 200 : 403, response.getStatus());
response.close(); response.close();
{ {
@ -932,7 +932,7 @@ public class AccessTokenTest extends AbstractKeycloakTest {
adminClient.realm("test").clients().create(ClientBuilder.create() adminClient.realm("test").clients().create(ClientBuilder.create()
.clientId("sample-public-client") .clientId("sample-public-client")
.authenticatorType("client-secret") .authenticatorType("client-secret")
.redirectUris("http://localhost:8180/auth/realms/master/app/*") .redirectUris(oauth.getRedirectUri() + "/*")
.publicClient() .publicClient()
.build()); .build());

View file

@ -88,9 +88,9 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest {
String title = PageUtils.getPageTitle(driver); String title = PageUtils.getPageTitle(driver);
Assert.assertEquals("Success code", title); 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); 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() String logoutUrl = oauth.getLogoutUrl()
.idTokenHint(idTokenString) .idTokenHint(idTokenString)
.postLogoutRedirectUri(AppPage.baseUrl) .postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build(); .build();
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); 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() String logoutUrl = oauth.getLogoutUrl()
.idTokenHint(idTokenString) .idTokenHint(idTokenString)
.postLogoutRedirectUri(AppPage.baseUrl) .postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build(); .build();
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); 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 // Logout should succeed with user already logged out, see KEYCLOAK-3399
String logoutUrl = oauth.getLogoutUrl() String logoutUrl = oauth.getLogoutUrl()
.idTokenHint(idTokenString) .idTokenHint(idTokenString)
.postLogoutRedirectUri(AppPage.baseUrl) .postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build(); .build();
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); 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() String logoutUrl = oauth.getLogoutUrl()
.idTokenHint(idTokenString) .idTokenHint(idTokenString)
.postLogoutRedirectUri(AppPage.baseUrl) .postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build(); .build();
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build(); try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) { CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND)); 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; package org.keycloak.testsuite.oauth;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
@ -76,7 +79,8 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest {
ClientRepresentation client = new ClientRepresentation(); ClientRepresentation client = new ClientRepresentation();
client.setClientId("more-uris-client"); client.setClientId("more-uris-client");
client.setEnabled(true); 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"); client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth");
testRealm.getClients().add(client); testRealm.getClients().add(client);
@ -85,6 +89,15 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest {
.filter(cl -> cl.getClientId().equals("test-app")) .filter(cl -> cl.getClientId().equals("test-app"))
.findFirst().get(); .findFirst().get();
testApp.setImplicitFlowEnabled(true); 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 @Before
@ -93,7 +106,7 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest {
/* /*
* Configure the default client ID. Seems like OAuthClient is keeping the state of clientID * 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 * 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() * @see AccessTokenTest#testAuthorizationNegotiateHeaderIgnored()
*/ */
oauth.init(driver); oauth.init(driver);

View file

@ -144,7 +144,7 @@ public class OAuthRedirectUriTest extends AbstractKeycloakTest {
realm.client(installedApp7); realm.client(installedApp7);
ClientBuilder installedApp8 = ClientBuilder.create().id("test-fragment").name("test-fragment") ClientBuilder installedApp8 = ClientBuilder.create().id("test-fragment").name("test-fragment")
.redirectUris("http://localhost/*") .redirectUris("http://localhost/*", "https://localhost:8543/*")
.secret("password"); .secret("password");
realm.client(installedApp8); realm.client(installedApp8);

View file

@ -89,12 +89,6 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
@Rule @Rule
public AssertEvents events = new AssertEvents(this); public AssertEvents events = new AssertEvents(this);
@Override
public void beforeAbstractKeycloakTest() throws Exception {
super.beforeAbstractKeycloakTest();
}
@Before @Before
public void clientConfiguration() { public void clientConfiguration() {
ClientManager.realm(adminClient.realm("test")).clientId("test-app").directAccessGrant(true); 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.assertThat(accessToken.getAudience(), arrayContainingInAnyOrder( "app", "account"));
// Assert allowed origins // Assert allowed origins
String expectedOrigin = UriUtils.getOrigin(oauth.getRedirectUri()); Assert.assertNames(accessToken.getAllowedOrigins(), "http://localhost:8180", "https://localhost:8543");
Assert.assertNames(accessToken.getAllowedOrigins(), expectedOrigin);
oauth.openLogout(); oauth.openLogout();
} }

View file

@ -51,6 +51,7 @@ import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.account.AccountFormServiceTest; import org.keycloak.testsuite.account.AccountFormServiceTest;
import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.auth.page.AuthRealm;
import org.keycloak.testsuite.pages.AccountApplicationsPage; import org.keycloak.testsuite.pages.AccountApplicationsPage;
import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.LoginPage;
@ -514,7 +515,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
// Use accessToken to admin REST request // Use accessToken to admin REST request
try (Keycloak offlineTokenAdmin = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", 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(); RealmRepresentation testRealm = offlineTokenAdmin.realm("test").toRepresentation();
Assert.assertNotNull(testRealm); Assert.assertNotNull(testRealm);
} }
@ -560,7 +561,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
// Go to account mgmt applications page // Go to account mgmt applications page
applicationsPage.open(); applicationsPage.open();
loginPage.login("test-user@localhost", "password"); 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()); assertTrue(applicationsPage.isCurrent());
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications(); Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
assertTrue(apps.containsKey("offline-client-2")); assertTrue(apps.containsKey("offline-client-2"));

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