KEYCLOAK-8349 KEYCLOAK-8659 Use TLS for all tests in the suite
This commit is contained in:
parent
885eec5ef2
commit
ee41a0450f
121 changed files with 1342 additions and 598 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>");
|
||||||
|
|
|
@ -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>");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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": {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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=="
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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";
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() + ")",
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>");
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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{
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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")
|
||||||
));
|
));
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue