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=crossdc-server
|
||||
- TESTS=crossdc-adapter
|
||||
- TESTS=ssl
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
|
|
|
@ -282,6 +282,13 @@ public class KeycloakDeployment {
|
|||
this.sslRequired = sslRequired;
|
||||
}
|
||||
|
||||
public boolean isSSLEnabled() {
|
||||
if (SslRequired.NONE == sslRequired) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getConfidentialPort() {
|
||||
return confidentialPort;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ public class KeycloakDeploymentBuilder {
|
|||
if (realmKeyPem == null && adapterConfig.isBearerOnly() && adapterConfig.getAuthServerUrl() == null) {
|
||||
throw new IllegalArgumentException("For bearer auth, you must set the realm-public-key or auth-server-url");
|
||||
}
|
||||
if (realmKeyPem == null || !deployment.isBearerOnly() || deployment.isEnableBasicAuth() || deployment.isRegisterNodeAtStartup() || deployment.getRegisterNodePeriod() != -1) {
|
||||
if (realmKeyPem == null || !deployment.isBearerOnly() || deployment.isSSLEnabled() || deployment.isEnableBasicAuth() || deployment.isRegisterNodeAtStartup() || deployment.getRegisterNodePeriod() != -1) {
|
||||
deployment.setClient(new HttpClientBuilder().build(adapterConfig));
|
||||
}
|
||||
if (adapterConfig.getAuthServerUrl() == null && (!deployment.isBearerOnly() || realmKeyPem == null)) {
|
||||
|
|
|
@ -41,7 +41,9 @@ public class JsonSerialization {
|
|||
public static final ObjectMapper sysPropertiesAwareMapper = new ObjectMapper(new SystemPropertiesJsonParserFactory());
|
||||
|
||||
static {
|
||||
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
prettyMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
prettyMapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
prettyMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ import org.keycloak.admin.client.resource.RealmsResource;
|
|||
import org.keycloak.admin.client.resource.ServerInfoResource;
|
||||
import org.keycloak.admin.client.token.TokenManager;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
@ -52,7 +54,7 @@ public class Keycloak implements AutoCloseable {
|
|||
|
||||
Keycloak(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, String grantType, ResteasyClient resteasyClient, String authtoken) {
|
||||
config = new Config(serverUrl, realm, username, password, clientId, clientSecret, grantType);
|
||||
client = resteasyClient != null ? resteasyClient : new ResteasyClientBuilder().connectionPoolSize(10).build();
|
||||
client = resteasyClient != null ? resteasyClient : newRestEasyClient(null, null, false);
|
||||
authToken = authtoken;
|
||||
tokenManager = authtoken == null ? new TokenManager(config, client) : null;
|
||||
|
||||
|
@ -64,33 +66,53 @@ public class Keycloak implements AutoCloseable {
|
|||
return authToken != null ? new BearerAuthFilter(authToken) : new BearerAuthFilter(tokenManager);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext) {
|
||||
return getInstance(serverUrl, realm, username, password, clientId, clientSecret, sslContext, null);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext, ResteasyJackson2Provider customJacksonProvider) {
|
||||
private static ResteasyClient newRestEasyClient(ResteasyJackson2Provider customJacksonProvider, SSLContext sslContext, boolean disableTrustManager) {
|
||||
ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder()
|
||||
.sslContext(sslContext)
|
||||
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.WILDCARD)
|
||||
.connectionPoolSize(10);
|
||||
|
||||
if (disableTrustManager) {
|
||||
// Disable PKIX path validation errors when running tests using SSL
|
||||
clientBuilder.disableTrustManager().hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY);
|
||||
}
|
||||
|
||||
if (customJacksonProvider != null) {
|
||||
clientBuilder.register(customJacksonProvider, 100);
|
||||
}
|
||||
|
||||
return new Keycloak(serverUrl, realm, username, password, clientId, clientSecret, PASSWORD, clientBuilder.build(), null);
|
||||
return clientBuilder.build();
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext, ResteasyJackson2Provider customJacksonProvider, boolean disableTrustManager, String authToken) {
|
||||
return new Keycloak(serverUrl, realm, username, password, clientId, clientSecret, PASSWORD, newRestEasyClient(customJacksonProvider, sslContext, disableTrustManager), authToken);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret) {
|
||||
return new Keycloak(serverUrl, realm, username, password, clientId, clientSecret, PASSWORD, null, null);
|
||||
return getInstance(serverUrl, realm, username, password, clientId, clientSecret, null, null, false, null);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext) {
|
||||
return getInstance(serverUrl, realm, username, password, clientId, clientSecret, sslContext, null, false, null);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, String clientSecret, SSLContext sslContext, ResteasyJackson2Provider customJacksonProvider) {
|
||||
return getInstance(serverUrl, realm, username, password, clientId, clientSecret, sslContext, null, false, null);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId) {
|
||||
return new Keycloak(serverUrl, realm, username, password, clientId, null, PASSWORD, null, null);
|
||||
return getInstance(serverUrl, realm, username, password, clientId, null, null, null, false, null);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String username, String password, String clientId, SSLContext sslContext) {
|
||||
return getInstance(serverUrl, realm, username, password, clientId, null, sslContext, null, false, null);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String clientId, String authToken) {
|
||||
return new Keycloak(serverUrl, realm, null, null, clientId, null, PASSWORD, null, authToken);
|
||||
return getInstance(serverUrl, realm, null, null, clientId, null, null, null, false, authToken);
|
||||
}
|
||||
|
||||
public static Keycloak getInstance(String serverUrl, String realm, String clientId, String authToken, SSLContext sllSslContext) {
|
||||
return getInstance(serverUrl, realm, null, null, clientId, null, sllSslContext, null, false, authToken);
|
||||
}
|
||||
|
||||
public RealmsResource realms() {
|
||||
|
|
|
@ -89,6 +89,9 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
|
|||
@Option(name = "trustpass", description = "Truststore password (prompted for if not specified and --truststore is used)")
|
||||
String trustPass;
|
||||
|
||||
@Option(name = "insecure", description = "Turns off TLS validation", hasValue = false)
|
||||
boolean insecure;
|
||||
|
||||
@Option(name = "token", description = "Token to use for invocations. With this option set, every other authentication option is ignored")
|
||||
String externalToken;
|
||||
|
||||
|
@ -178,6 +181,10 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
|
|||
throw new RuntimeException("Failed to load truststore: " + truststore, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (insecure) {
|
||||
HttpUtil.setSkipCertificateValidation();
|
||||
}
|
||||
}
|
||||
|
||||
protected ConfigData ensureAuthInfo(ConfigData config, CommandInvocation commandInvocation) {
|
||||
|
|
|
@ -30,9 +30,11 @@ import org.apache.http.client.methods.HttpPost;
|
|||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.keycloak.client.admin.cli.httpcomponents.HttpDelete;
|
||||
import org.keycloak.client.admin.cli.operations.LocalSearch;
|
||||
|
@ -53,6 +55,7 @@ import java.security.cert.CertificateException;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.keycloak.common.util.ObjectUtil.capitalize;
|
||||
|
||||
|
@ -68,6 +71,7 @@ public class HttpUtil {
|
|||
|
||||
private static HttpClient httpClient;
|
||||
private static SSLConnectionSocketFactory sslsf;
|
||||
private static final AtomicBoolean tlsWarningEmitted = new AtomicBoolean();
|
||||
|
||||
public static InputStream doGet(String url, String acceptType, String authorization) {
|
||||
try {
|
||||
|
@ -257,11 +261,29 @@ public class HttpUtil {
|
|||
}
|
||||
SSLContext theContext = SSLContexts.custom()
|
||||
.useProtocol("TLS")
|
||||
.loadTrustMaterial(file, password == null ? null : password.toCharArray())
|
||||
.loadTrustMaterial(file, password == null ? null : password.toCharArray(), TrustSelfSignedStrategy.INSTANCE)
|
||||
.build();
|
||||
sslsf = new SSLConnectionSocketFactory(theContext);
|
||||
}
|
||||
|
||||
public static void setSkipCertificateValidation() {
|
||||
if (!tlsWarningEmitted.getAndSet(true)) {
|
||||
// Since this is a static util, it may happen that TLS is setup many times in one command
|
||||
// invocation (e.g. when a command requires logging in). However, we would like to
|
||||
// prevent this warning from appearing multiple times. That's why we need to guard it with a boolean.
|
||||
System.err.println("The server is configured to use TLS but there is no truststore specified.");
|
||||
System.err.println("The tool will skip certificate validation. This is highly discouraged for production use cases");
|
||||
}
|
||||
|
||||
SSLContextBuilder builder = new SSLContextBuilder();
|
||||
try {
|
||||
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
|
||||
sslsf = new SSLConnectionSocketFactory(builder.build());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed setting up TLS", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String extractIdFromLocation(String location) {
|
||||
int last = location.lastIndexOf("/");
|
||||
if (last != -1) {
|
||||
|
|
|
@ -25,7 +25,6 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
|
|||
|
||||
static final String DEFAULT_CLIENT = "admin-cli";
|
||||
|
||||
|
||||
@Option(name = "config", description = "Path to the config file (~/.keycloak/kcreg.config by default)", hasValue = true)
|
||||
protected String config;
|
||||
|
||||
|
@ -68,6 +67,9 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
|
|||
@Option(name = "trustpass", description = "Truststore password (prompted for if not specified and --truststore is used)", hasValue = true)
|
||||
protected String trustPass;
|
||||
|
||||
@Option(name = "insecure", description = "Turns off TLS validation", hasValue = false)
|
||||
protected boolean insecure;
|
||||
|
||||
@Option(shortName = 't', name = "token", description = "Initial / Registration access token to use)", hasValue = true)
|
||||
protected String token;
|
||||
|
||||
|
@ -90,6 +92,7 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
|
|||
trustStore = parent.trustStore;
|
||||
trustPass = parent.trustPass;
|
||||
token = parent.token;
|
||||
insecure = parent.insecure;
|
||||
}
|
||||
|
||||
protected void applyDefaultOptionValues() {
|
||||
|
@ -152,6 +155,10 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
|
|||
throw new RuntimeException("Failed to load truststore: " + truststore, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (insecure) {
|
||||
HttpUtil.setSkipCertificateValidation();
|
||||
}
|
||||
}
|
||||
|
||||
protected ConfigData ensureAuthInfo(ConfigData config, CommandInvocation commandInvocation) {
|
||||
|
|
|
@ -28,6 +28,8 @@ import org.apache.http.client.methods.HttpPost;
|
|||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
@ -46,6 +48,7 @@ import java.security.KeyStoreException;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
|
@ -59,6 +62,7 @@ public class HttpUtil {
|
|||
|
||||
private static HttpClient httpClient;
|
||||
private static SSLConnectionSocketFactory sslsf;
|
||||
private static final AtomicBoolean tlsWarningEmitted = new AtomicBoolean();
|
||||
|
||||
public static InputStream doGet(String url, String acceptType, String authorization) {
|
||||
try {
|
||||
|
@ -181,8 +185,26 @@ public class HttpUtil {
|
|||
}
|
||||
SSLContext theContext = SSLContexts.custom()
|
||||
.useProtocol("TLS")
|
||||
.loadTrustMaterial(file, password == null ? null : password.toCharArray())
|
||||
.loadTrustMaterial(file, password == null ? null : password.toCharArray(), TrustSelfSignedStrategy.INSTANCE)
|
||||
.build();
|
||||
sslsf = new SSLConnectionSocketFactory(theContext);
|
||||
}
|
||||
|
||||
public static void setSkipCertificateValidation() {
|
||||
if (!tlsWarningEmitted.getAndSet(true)) {
|
||||
// Since this is a static util, it may happen that TLS is setup many times in one command
|
||||
// invocation (e.g. when a command requires logging in). However, we would like to
|
||||
// prevent this warning from appearing multiple times. That's why we need to guard it with a boolean.
|
||||
System.err.println("The server is configured to use TLS but there is no truststore specified.");
|
||||
System.err.println("The tool will skip certificate validation. This is highly discouraged for production use cases");
|
||||
}
|
||||
|
||||
SSLContextBuilder builder = new SSLContextBuilder();
|
||||
try {
|
||||
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
|
||||
sslsf = new SSLConnectionSocketFactory(builder.build());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed setting up TLS", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ and adapter are all in the same JVM and you can debug them easily. If it is not
|
|||
|
||||
-Dmaven.surefire.debug=true
|
||||
|
||||
Or slightly longer version (that allows you to specify debugging port as well as wait till you attach the debugger):
|
||||
|
||||
-Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006 -Xnoagent -Djava.compiler=NONE"
|
||||
|
||||
|
||||
and you will be able to attach remote debugger to the test. Unfortunately server and adapter are running in different JVMs, so this won't help to debug those.
|
||||
|
||||
|
@ -486,27 +490,17 @@ To run the X.509 client certificate authentication tests:
|
|||
-Dbrowser=phantomjs \
|
||||
"-Dtest=*.x509.*"
|
||||
|
||||
## Run Mutual TLS Client Certificate Bound Access Tokens tests
|
||||
## Disabling TLS (SSL) in the tests
|
||||
|
||||
To run the Mutual TLS Client Certificate Bound Access Tokens tests:
|
||||
All tests are executed with TLS by default. In order to disable it, you need to switch the `auth.server.ssl.required` property off.
|
||||
Here's an example:
|
||||
|
||||
mvn -f testsuite/integration-arquillian/pom.xml \
|
||||
clean install \
|
||||
-Pauth-server-wildfly \
|
||||
-Dauth.server.ssl.required \
|
||||
-Dbrowser=phantomjs \
|
||||
-Dtest=org.keycloak.testsuite.hok.HoKTest
|
||||
-Dauth.server.ssl.required=false
|
||||
|
||||
## Run Mutual TLS for the Client tests
|
||||
|
||||
To run the Mutual TLS test for the client:
|
||||
|
||||
mvn -f testsuite/integration-arquillian/pom.xml \
|
||||
clean install \
|
||||
-Pauth-server-wildfly \
|
||||
-Dauth.server.ssl.required \
|
||||
-Dbrowser=phantomjs \
|
||||
-Dtest=org.keycloak.testsuite.client.MutualTLSClientTest
|
||||
NOTE: You can also do it ad-hoc from your IDE, however some tests (like AuthZ or JS Adapter tests) require rebuilt test applications.
|
||||
so please make sure you rebuild all `testsuite/integration-arquillian` child modules.
|
||||
|
||||
## Cluster tests
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ embed-server --server-config=standalone.xml
|
|||
/subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/:add( \
|
||||
realm=demo, \
|
||||
resource=customer-portal-subsystem, \
|
||||
auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \
|
||||
auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.https.port:8543}/auth, \
|
||||
ssl-required=EXTERNAL, \
|
||||
disable-trust-manager=true, \
|
||||
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
|
||||
)
|
||||
/subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/credential=secret/:add(value=password)
|
||||
|
@ -12,8 +13,9 @@ embed-server --server-config=standalone.xml
|
|||
/subsystem=keycloak/secure-deployment=product-portal-subsystem.war/:add( \
|
||||
realm=demo, \
|
||||
resource=product-portal-subsystem, \
|
||||
auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \
|
||||
auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.https.port:8543}/auth, \
|
||||
ssl-required=EXTERNAL, \
|
||||
disable-trust-manager=true, \
|
||||
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
|
||||
)
|
||||
/subsystem=keycloak/secure-deployment=product-portal-subsystem.war/credential=secret/:add(value=password)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/:add( \
|
||||
realm=demo, \
|
||||
resource=customer-portal-subsystem, \
|
||||
auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \
|
||||
auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.http.port:8543}/auth, \
|
||||
ssl-required=EXTERNAL, \
|
||||
disable-trust-manager=true, \
|
||||
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
|
||||
)
|
||||
/subsystem=keycloak/secure-deployment=customer-portal-subsystem.war/credential=secret/:add(value=password)
|
||||
|
@ -10,8 +11,9 @@
|
|||
/subsystem=keycloak/secure-deployment=product-portal-subsystem.war/:add( \
|
||||
realm=demo, \
|
||||
resource=product-portal-subsystem, \
|
||||
auth-server-url=${auth.server.actual.protocol:http}://localhost:${auth.server.actual.http.port:8180}/auth, \
|
||||
auth-server-url=${auth.server.actual.protocol:https}://localhost:${auth.server.actual.https.port:8543}/auth, \
|
||||
ssl-required=EXTERNAL, \
|
||||
disable-trust-manager=true, \
|
||||
realm-public-key=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB \
|
||||
)
|
||||
/subsystem=keycloak/secure-deployment=product-portal-subsystem.war/credential=secret/:add(value=password)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<properties>
|
||||
<js-adapter.version>${project.version}</js-adapter.version>
|
||||
<js-adapter.file.path>${project.basedir}/target/classes/javascript</js-adapter.file.path>
|
||||
<js-adapter.auth-server-url>https://localhost:8543/auth</js-adapter.auth-server-url>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -68,6 +69,21 @@
|
|||
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>no-ssl</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>auth.server.ssl.required</name>
|
||||
<value>false</value>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<js-adapter.auth-server-url>http://localhost:8180/auth</js-adapter.auth-server-url>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
|
|
@ -143,7 +143,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
|
|||
}
|
||||
sb.append("<br>");
|
||||
|
||||
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
|
||||
UriBuilder base = UriBuilder.fromUri("/auth");
|
||||
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
|
||||
|
||||
sb.append("</body></html>");
|
||||
|
@ -165,7 +165,7 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
|
|||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html><head><title>" + title + "</title></head><body>");
|
||||
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
|
||||
UriBuilder base = UriBuilder.fromUri("/auth");
|
||||
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
|
||||
|
||||
sb.append("</body></html>");
|
||||
|
|
|
@ -137,7 +137,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide
|
|||
}
|
||||
sb.append("<br>");
|
||||
|
||||
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
|
||||
UriBuilder base = UriBuilder.fromUri("/auth");
|
||||
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
|
||||
|
||||
sb.append("</body></html>");
|
||||
|
@ -159,7 +159,7 @@ public class TestSamlApplicationResourceProvider implements RealmResourceProvide
|
|||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html><head><title>" + title + "</title></head><body>");
|
||||
UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
|
||||
UriBuilder base = UriBuilder.fromUri("/auth");
|
||||
sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
|
||||
|
||||
sb.append("</body></html>");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"realm" : "test",
|
||||
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"auth-server-url" : "http://localhost:8180/auth",
|
||||
"auth-server-url" : "${js-adapter.auth-server-url}",
|
||||
"ssl-required" : "external",
|
||||
"resource" : "js-console",
|
||||
"public-client" : true
|
||||
|
|
|
@ -28,8 +28,11 @@
|
|||
<artifactId>integration-arquillian-servers-auth-server-undertow</artifactId>
|
||||
<name>Auth Server - Undertow</name>
|
||||
|
||||
<dependencies>
|
||||
<properties>
|
||||
<common.resources>${basedir}/../jboss/common</common.resources>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-testsuite-utils</artifactId>
|
||||
|
@ -77,4 +80,15 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${common.resources}/keystore</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -51,10 +51,19 @@ import org.keycloak.testsuite.utils.undertow.UndertowDeployerHelper;
|
|||
import org.keycloak.testsuite.utils.undertow.UndertowWarClassLoader;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -180,12 +189,13 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
|||
if (undertow == null) {
|
||||
undertow = new UndertowJaxrsServer();
|
||||
}
|
||||
|
||||
undertow.start(Undertow.builder()
|
||||
.addHttpListener(configuration.getBindHttpPort(), configuration.getBindAddress())
|
||||
.addHttpsListener(configuration.getBindHttpsPort(), configuration.getBindAddress(), TLSUtils.initializeTLS())
|
||||
.setWorkerThreads(configuration.getWorkerThreads())
|
||||
.setIoThreads(configuration.getWorkerThreads() / 8)
|
||||
);
|
||||
|
||||
if (configuration.getRoute() != null) {
|
||||
log.info("Using route: " + configuration.getRoute());
|
||||
}
|
||||
|
@ -200,7 +210,6 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
|||
log.infof("Auth server started in %dms on http://%s:%d/auth", (System.currentTimeMillis() - start), configuration.getBindAddress(), configuration.getBindHttpPort());
|
||||
}
|
||||
|
||||
|
||||
protected void setupDevConfig() {
|
||||
KeycloakSession session = sessionFactory.create();
|
||||
try {
|
||||
|
|
|
@ -28,6 +28,8 @@ import org.jboss.logging.Logger;
|
|||
|
||||
public class KeycloakOnUndertowConfiguration extends UndertowContainerConfiguration {
|
||||
|
||||
public static final int DEFAULT_HTTPS_PORT = Integer.valueOf(System.getProperty("auth.server.https.port", "8543"));
|
||||
|
||||
protected static final Logger log = Logger.getLogger(KeycloakOnUndertowConfiguration.class);
|
||||
|
||||
private int workerThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2) * 8;
|
||||
|
@ -38,6 +40,8 @@ public class KeycloakOnUndertowConfiguration extends UndertowContainerConfigurat
|
|||
private Map<String, String> keycloakConfigPropertyOverridesMap;
|
||||
|
||||
private int bindHttpPortOffset = 0;
|
||||
private int bindHttpsPortOffset = 0;
|
||||
private int bindHttpsPort = DEFAULT_HTTPS_PORT;
|
||||
|
||||
public int getWorkerThreads() {
|
||||
return workerThreads;
|
||||
|
@ -63,6 +67,22 @@ public class KeycloakOnUndertowConfiguration extends UndertowContainerConfigurat
|
|||
this.bindHttpPortOffset = bindHttpPortOffset;
|
||||
}
|
||||
|
||||
public int getBindHttpsPortOffset() {
|
||||
return bindHttpsPortOffset;
|
||||
}
|
||||
|
||||
public void setBindHttpsPortOffset(int bindHttpsPortOffset) {
|
||||
this.bindHttpsPortOffset = bindHttpsPortOffset;
|
||||
}
|
||||
|
||||
public int getBindHttpsPort() {
|
||||
return this.bindHttpsPort;
|
||||
}
|
||||
|
||||
public void setBindHttpsPort(int bindHttpsPort) {
|
||||
this.bindHttpsPort = bindHttpsPort;
|
||||
}
|
||||
|
||||
public String getRoute() {
|
||||
return route;
|
||||
}
|
||||
|
|
|
@ -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.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -41,6 +40,8 @@ import io.undertow.util.Headers;
|
|||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.util.reflections.Reflections;
|
||||
import org.keycloak.services.managers.AuthenticationSessionManager;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
|
@ -56,19 +57,20 @@ public class SimpleUndertowLoadBalancer {
|
|||
|
||||
private static final Logger log = Logger.getLogger(SimpleUndertowLoadBalancer.class);
|
||||
|
||||
static final String DEFAULT_NODES = "node1=http://localhost:8181,node2=http://localhost:8182";
|
||||
static final String DEFAULT_NODES_HTTP = "node1=http://localhost:8181,node2=http://localhost:8182";
|
||||
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final int httpPort;
|
||||
private final int httpsPort;
|
||||
private final Map<String, URI> backendNodes;
|
||||
private Undertow undertow;
|
||||
private LoadBalancingProxyClient lb;
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String nodes = System.getProperty("keycloak.nodes", DEFAULT_NODES);
|
||||
String nodes = System.getProperty("keycloak.nodes", DEFAULT_NODES_HTTP);
|
||||
|
||||
SimpleUndertowLoadBalancer lb = new SimpleUndertowLoadBalancer("localhost", 8180, nodes);
|
||||
SimpleUndertowLoadBalancer lb = new SimpleUndertowLoadBalancer("localhost", 8180, 8543, nodes);
|
||||
lb.start();
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
|
@ -82,9 +84,10 @@ public class SimpleUndertowLoadBalancer {
|
|||
}
|
||||
|
||||
|
||||
public SimpleUndertowLoadBalancer(String host, int port, String nodesString) {
|
||||
public SimpleUndertowLoadBalancer(String host, int httpPort, int httpsPort, String nodesString) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.httpPort = httpPort;
|
||||
this.httpsPort = httpsPort;
|
||||
this.backendNodes = parseNodes(nodesString);
|
||||
log.infof("Keycloak nodes: %s", backendNodes);
|
||||
}
|
||||
|
@ -95,12 +98,13 @@ public class SimpleUndertowLoadBalancer {
|
|||
HttpHandler proxyHandler = createHandler();
|
||||
|
||||
undertow = Undertow.builder()
|
||||
.addHttpListener(port, host)
|
||||
.addHttpListener(httpPort, host)
|
||||
.addHttpsListener(httpsPort, host, TLSUtils.initializeTLS())
|
||||
.setHandler(proxyHandler)
|
||||
.build();
|
||||
undertow.start();
|
||||
|
||||
log.infof("#### Loadbalancer started and ready to serve requests on http://%s:%d ####", host, port);
|
||||
log.infof("#### Loadbalancer started and ready to serve requests on http://%s:%d, http://%s:%d ####", host, httpPort, host, httpsPort);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
@ -26,10 +26,14 @@ import org.jboss.logging.Logger;
|
|||
*/
|
||||
public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerConfiguration {
|
||||
|
||||
public static final int DEFAULT_HTTPS_PORT = Integer.valueOf(System.getProperty("auth.server.https.port", "8543"));
|
||||
|
||||
protected static final Logger log = Logger.getLogger(SimpleUndertowLoadBalancerConfiguration.class);
|
||||
|
||||
private String nodes = SimpleUndertowLoadBalancer.DEFAULT_NODES;
|
||||
private String nodes = SimpleUndertowLoadBalancer.DEFAULT_NODES_HTTP;
|
||||
private int bindHttpPortOffset = 0;
|
||||
private int bindHttpsPortOffset = 0;
|
||||
private int bindHttpsPort = DEFAULT_HTTPS_PORT;
|
||||
|
||||
public String getNodes() {
|
||||
return nodes;
|
||||
|
@ -47,6 +51,22 @@ public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerCo
|
|||
this.bindHttpPortOffset = bindHttpPortOffset;
|
||||
}
|
||||
|
||||
public int getBindHttpsPortOffset() {
|
||||
return bindHttpsPortOffset;
|
||||
}
|
||||
|
||||
public void setBindHttpsPortOffset(int bindHttpsPortOffset) {
|
||||
this.bindHttpsPortOffset = bindHttpsPortOffset;
|
||||
}
|
||||
|
||||
public int getBindHttpsPort() {
|
||||
return this.bindHttpsPort;
|
||||
}
|
||||
|
||||
public void setBindHttpsPort(int bindHttpsPort) {
|
||||
this.bindHttpsPort = bindHttpsPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() throws ConfigurationException {
|
||||
super.validate();
|
||||
|
@ -57,10 +77,9 @@ public class SimpleUndertowLoadBalancerConfiguration extends UndertowContainerCo
|
|||
throw new ConfigurationException(e);
|
||||
}
|
||||
|
||||
int basePort = getBindHttpPort();
|
||||
int newPort = basePort + bindHttpPortOffset;
|
||||
setBindHttpPort(newPort);
|
||||
log.info("SimpleUndertowLoadBalancer will listen on port: " + newPort);
|
||||
setBindHttpPort(getBindHttpPort() + bindHttpPortOffset);
|
||||
setBindHttpsPort(getBindHttpsPort() + bindHttpsPortOffset);
|
||||
log.info("SimpleUndertowLoadBalancer will listen on ports: " + getBindHttpPort() + " " + getBindHttpsPort());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class SimpleUndertowLoadBalancerContainer implements DeployableContainer<
|
|||
|
||||
@Override
|
||||
public void start() throws LifecycleException {
|
||||
this.container = new SimpleUndertowLoadBalancer(configuration.getBindAddress(), configuration.getBindHttpPort(), configuration.getNodes());
|
||||
this.container = new SimpleUndertowLoadBalancer(configuration.getBindAddress(), configuration.getBindHttpPort(), configuration.getBindHttpsPort(), configuration.getNodes());
|
||||
this.container.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,7 @@
|
|||
var module = angular.module('product', []);
|
||||
|
||||
function getAuthServerUrl() {
|
||||
var url = 'http://localhost-auth:8180';
|
||||
if (window.location.href.indexOf("8643") > -1) {
|
||||
url = url.replace("8180","8543");
|
||||
url = url.replace("http","https");
|
||||
}
|
||||
var url = 'https://localhost-auth:8543';
|
||||
|
||||
return url;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"auth-server-url" : "http://localhost-auth:8180/auth",
|
||||
"ssl-required" : "external",
|
||||
"disable-trust-manager" : "true",
|
||||
"resource" : "angular-cors-product",
|
||||
"public-client" : true
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
"auth-server-url": "http://localhost-auth:8180/auth",
|
||||
"bearer-only" : true,
|
||||
"ssl-required": "external",
|
||||
"disable-trust-manager" : "true",
|
||||
"enable-cors": true,
|
||||
"cors-exposed-headers": "X-Custom1",
|
||||
"credentials": {
|
||||
|
|
|
@ -19,9 +19,16 @@
|
|||
<%@ page import="org.keycloak.common.util.KeycloakUriBuilder" %>
|
||||
<%@ page import="org.keycloak.constants.ServiceUrlConstants" %>
|
||||
|
||||
<%
|
||||
boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true"));
|
||||
String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180");
|
||||
String authScheme = isTLSEnabled ? "https" : "http";
|
||||
String authUri = authScheme + "://localhost:" + authPort + "/auth";
|
||||
%>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<h2><a href="<%= KeycloakUriBuilder.fromUri("/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
<h2><a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
.queryParam("redirect_uri", "http://localhost:8080/hello-world-authz-service").build("hello-world-authz").toString()%>">Logout</a></h2>
|
||||
|
||||
<h3>Access Denied !</h3>
|
||||
|
|
|
@ -24,11 +24,16 @@
|
|||
<%
|
||||
KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();
|
||||
|
||||
boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true"));
|
||||
String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180");
|
||||
String authScheme = isTLSEnabled ? "https" : "http";
|
||||
String authUri = authScheme + "://localhost:" + authPort + "/auth";
|
||||
%>
|
||||
<html>
|
||||
<body>
|
||||
<h2>Welcome !</h2>
|
||||
<h2><a href="<%= KeycloakUriBuilder.fromUri("/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
<h2><a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
.queryParam("redirect_uri", "http://localhost:8080/hello-world-authz-service").build("hello-world-authz").toString()%>">Logout</a></h2>
|
||||
|
||||
<h3>Your permissions are:</h3>
|
||||
|
|
|
@ -140,9 +140,9 @@
|
|||
"consentRequired" : true,
|
||||
"fullScopeAllowed" : true,
|
||||
"redirectUris": [
|
||||
"/photoz-html5-client/*"
|
||||
"*"
|
||||
],
|
||||
"webOrigins": ["http://localhost:8280"]
|
||||
"webOrigins": ["*"]
|
||||
},
|
||||
{
|
||||
"clientId": "photoz-restful-api",
|
||||
|
@ -150,9 +150,9 @@
|
|||
"baseUrl": "/photoz-restful-api",
|
||||
"authorizationServicesEnabled" : true,
|
||||
"redirectUris": [
|
||||
"/photoz-restful-api/*"
|
||||
"*"
|
||||
],
|
||||
"webOrigins" : ["http://localhost:8280"],
|
||||
"webOrigins" : ["*"],
|
||||
"clientAuthenticatorType": "client-jwt",
|
||||
"attributes" : {
|
||||
"jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg=="
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
int port = request.getServerPort();
|
||||
String contextPath = request.getContextPath();
|
||||
String redirectUri = scheme + "://" + host + ":" + port + contextPath;
|
||||
|
||||
|
||||
boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true"));
|
||||
String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180");
|
||||
String authScheme = isTLSEnabled ? "https" : "http";
|
||||
String authUri = authScheme + "://localhost:" + authPort + "/auth";
|
||||
%>
|
||||
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri("http://localhost:8180/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
.queryParam("redirect_uri", redirectUri).build("servlet-authz").toString()%>">Sign Out</a></h2>
|
|
@ -6,6 +6,12 @@
|
|||
int port = request.getServerPort();
|
||||
String contextPath = request.getContextPath();
|
||||
String redirectUri = scheme + "://" + host + ":" + port + contextPath;
|
||||
|
||||
|
||||
boolean isTLSEnabled = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true"));
|
||||
String authPort = isTLSEnabled ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180");
|
||||
String authScheme = isTLSEnabled ? "https" : "http";
|
||||
String authUri = authScheme + "://localhost:" + authPort + "/auth";
|
||||
%>
|
||||
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri("http://localhost:8180/auth").path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
<h2>Click here <a href="<%= KeycloakUriBuilder.fromUri(authUri).path(ServiceUrlConstants.TOKEN_SERVICE_LOGOUT_PATH)
|
||||
.queryParam("redirect_uri", redirectUri).build("servlet-policy-enforcer-authz").toString()%>">Sign Out</a></h2>
|
|
@ -90,7 +90,7 @@ public class SamlSPFacade extends HttpServlet {
|
|||
*/
|
||||
private String getSamlRequest() {
|
||||
if (System.getProperty("auth.server.ssl.required", "false").equals("true")) {
|
||||
return "jVLbTgIxEP2Vpu9Ly3JZbFgSlBhJUDeAPvhianeQJt127XS9%2FL1lwWiiokkfms6ZOZfpGGVlajFtwtYu4akBDOS1MhZFW8hp461wEjUKKytAEZRYTS8XIu1wUXsXnHKG7luOgyUi%2BKCdpWT6cT1zFpsK%2FAr8s1Zws1zkdBtCjYIx45Q0W4dBjIb9HoOqNu4NgFEyiyK1lbsBP8IHES6jIeZBmgpZCZVjH1rZzhcl584raF3ndCMNAiXzWU7ns%2Ft%2BOYKBgjTJUj5M%2Bln6kMjRSZak5aiX8ROuOB9EMBbRkH6Gz3bEBuYWg7QhpynvDhLeS%2FhwnaYinm7WicLuKCkOQk61LbV9PB7awx6E4mK9LpLierWm5BY8ttYjgE7IeGdItOz%2By%2Br%2Bu4zJX3mP2ReCA10truLI%2BaxwRqs3MjXGvZzFtEOMI%2FgG2nwrGX4X0e102xddJpsWKhqLNSi90VBSFnnY9585eQc%3D";
|
||||
return "jVJLbxshEL5Xyn9A3Ndg%2FNgN8lpyYkW1lDYr2%2B2hl4qw4xiJhQ3Dus2%2FD17HSqqoaQUHBN%2FM9xhmqBrbykUX924Njx1gJL8b61D2DyXtgpNeoUHpVAMoo5abxZdbKQZctsFHr72lp5KPwQoRQjTeUbI4H6%2B9w66BsIFwMBq%2BrW9Luo%2BxlYxZr5Xde4yyEAVn0LTWPwEwSpZJo3HqWH9C45%2FwyXjEVPLDAijbIKuh8ewslR1tUXLjg4bedEl3yiJQslqWdLX8Oa4LmGgQWS74NBvn4j5TxWWeiboY5fySa84nCYxV8mMO8FqO2MHKYVQullTw4STjo4xPt0LItIf5IAn7QUn1IuTKuNq4h48zuz%2BBUH7ebqusuttsKfkOAXvrCUDnZHY0JHv28GZy%2FzuL%2BT%2FinrE3%2FV%2FYWvk1dVwtK2%2BNfiILa%2F2v6xR2TGnE0EEfb6Pi3zUMB8P%2BxtTZrofKzmEL2uwM1JQlHvb%2BX84vPh3XMw%3D%3D";
|
||||
}
|
||||
|
||||
return "jZJRT9swFIX%2FiuX31I5pSbCaSoVqWiXYIlp42Asyzu1qybGDr1PWfz83LQKJAZP8YNnf9T3nXE9RtbaT8z5u3S089YCR%2FGmtQzlcVLQPTnqFBqVTLaCMWq7mN9dSjLjsgo9ee0uPJZ%2FDChFCNN5RMn%2FZXnmHfQthBWFnNNzdXld0G2MnGbNeK7v1GGUpSs6g7azfAzBKFkmjcepQ%2Fy86T7RKdlgAZVtkDbSevShlB1eUfPNBw%2BC5ohtlEShZLiq6XDyMmxImGkRWCH6ejQvxmKnyoshEU54V%2FIJrzicJxjrZMTt4LUfsYekwKhcrKng%2ByfhZxs%2FXQsi08mJUTsa%2FKKlPQi6Na4z7%2FXlkj0cI5ff1us7qn6s1JfcQcHCeADoj04MhOXQPbwb3v6OYfZH2lL15%2F9Stkz%2FSi8tF7a3RezK31j9fpbBjSiOGHoZ4WxU%2F1pCP8uHENNlmQGXvsANtNgYaylIf9v5bzv4C";
|
||||
|
|
|
@ -271,6 +271,25 @@
|
|||
</artifactItems>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>unpack-undertow-server</id>
|
||||
<phase>generate-test-resources</phase>
|
||||
<goals>
|
||||
<goal>unpack</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.keycloak.testsuite</groupId>
|
||||
<artifactId>integration-arquillian-servers-auth-server-undertow</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>jar</type>
|
||||
<outputDirectory>${containers.home}/auth-server-undertow</outputDirectory>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
<includes>*.jks,*.crt,*.truststore</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
|
|
@ -39,9 +39,19 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
|||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.util.LogChecker;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.wildfly.extras.creaper.commands.undertow.AddUndertowListener;
|
||||
import org.wildfly.extras.creaper.commands.undertow.RemoveUndertowListener;
|
||||
import org.wildfly.extras.creaper.commands.undertow.SslVerifyClient;
|
||||
import org.wildfly.extras.creaper.commands.undertow.UndertowListenerType;
|
||||
import org.wildfly.extras.creaper.core.CommandFailedException;
|
||||
import org.wildfly.extras.creaper.core.ManagementClient;
|
||||
import org.wildfly.extras.creaper.core.online.CliException;
|
||||
import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
|
||||
import org.wildfly.extras.creaper.core.online.OnlineOptions;
|
||||
import org.wildfly.extras.creaper.core.online.operations.Address;
|
||||
import org.wildfly.extras.creaper.core.online.operations.OperationException;
|
||||
import org.wildfly.extras.creaper.core.online.operations.Operations;
|
||||
import org.wildfly.extras.creaper.core.online.operations.admin.Administration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
@ -50,6 +60,7 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
|
||||
|
@ -72,6 +83,8 @@ public class AuthServerTestEnricher {
|
|||
@Inject
|
||||
private Event<StopContainer> stopContainerEvent;
|
||||
|
||||
protected static final boolean AUTH_SERVER_SSL_REQUIRED = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "true"));
|
||||
|
||||
public static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow";
|
||||
public static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container";
|
||||
public static final String AUTH_SERVER_CONTAINER = System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT);
|
||||
|
@ -114,9 +127,8 @@ public class AuthServerTestEnricher {
|
|||
int httpPort = Integer.parseInt(System.getProperty("auth.server.http.port")); // property must be set
|
||||
int httpsPort = Integer.parseInt(System.getProperty("auth.server.https.port")); // property must be set
|
||||
|
||||
boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required"));
|
||||
String scheme = sslRequired ? "https" : "http";
|
||||
int port = sslRequired ? httpsPort : httpPort;
|
||||
String scheme = AUTH_SERVER_SSL_REQUIRED ? "https" : "http";
|
||||
int port = AUTH_SERVER_SSL_REQUIRED ? httpsPort : httpPort;
|
||||
|
||||
return String.format("%s://%s:%s", scheme, host, port + clusterPortOffset);
|
||||
}
|
||||
|
@ -322,7 +334,56 @@ public class AuthServerTestEnricher {
|
|||
testContextProducer.set(testContext);
|
||||
}
|
||||
|
||||
public void initializeOAuthClient(@Observes(precedence = 3) BeforeClass event) {
|
||||
public void initializeTLS(@Observes(precedence = 3) BeforeClass event) throws Exception {
|
||||
// TLS for Undertow is configured in KeycloakOnUndertow since it requires
|
||||
// SSLContext while initializing HTTPS handlers
|
||||
if (AUTH_SERVER_SSL_REQUIRED && isAuthServerJBossBased() && !suiteContext.isAuthServerCrossDc()) {
|
||||
log.info("\n\n### Setting up TLS ##\n\n");
|
||||
|
||||
try {
|
||||
OnlineManagementClient client = getManagementClient();
|
||||
enableTLS(client);
|
||||
client.close();
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to set up TLS. This may lead to unexpected behavior unless the test" +
|
||||
" sets it up manually", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void enableTLS(OnlineManagementClient client) throws Exception {
|
||||
Administration administration = new Administration(client);
|
||||
Operations operations = new Operations(client);
|
||||
|
||||
if(!operations.exists(Address.coreService("management").and("security-realm", "UndertowRealm"))) {
|
||||
client.execute("/core-service=management/security-realm=UndertowRealm:add()");
|
||||
client.execute("/core-service=management/security-realm=UndertowRealm/server-identity=ssl:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.jks");
|
||||
client.execute("/core-service=management/security-realm=UndertowRealm/authentication=truststore:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.truststore");
|
||||
|
||||
client.apply(new RemoveUndertowListener.Builder(UndertowListenerType.HTTPS_LISTENER, "https")
|
||||
.forDefaultServer());
|
||||
|
||||
administration.reloadIfRequired();
|
||||
|
||||
client.apply(new AddUndertowListener.HttpsBuilder("https", "default-server", "https")
|
||||
.securityRealm("UndertowRealm")
|
||||
.verifyClient(SslVerifyClient.REQUESTED)
|
||||
.build());
|
||||
|
||||
administration.reloadIfRequired();
|
||||
} else {
|
||||
log.info("## The Auth Server has already configured TLS. Skipping... ##");
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isAuthServerJBossBased() {
|
||||
return containerRegistry.get().getContainers().stream()
|
||||
.map(ContainerInfo::new)
|
||||
.filter(ci -> ci.isJBossBased())
|
||||
.findFirst().isPresent();
|
||||
}
|
||||
|
||||
public void initializeOAuthClient(@Observes(precedence = 4) BeforeClass event) {
|
||||
// TODO workaround. Check if can be removed
|
||||
OAuthClient.updateURLs(suiteContext.getAuthServerInfo().getContextRoot().toString());
|
||||
OAuthClient oAuthClient = new OAuthClient();
|
||||
|
|
|
@ -32,11 +32,13 @@ import org.jboss.arquillian.core.api.annotation.Inject;
|
|||
import org.jboss.arquillian.core.api.annotation.Observes;
|
||||
import org.jboss.arquillian.test.spi.event.suite.After;
|
||||
import org.jboss.arquillian.test.spi.event.suite.Before;
|
||||
import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
|
||||
import org.jboss.logging.Logger;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.testsuite.arquillian.annotation.InitialDcState;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.crossdc.DC;
|
||||
|
@ -49,6 +51,9 @@ import org.jboss.arquillian.container.spi.event.StopContainer;
|
|||
import org.jboss.arquillian.container.spi.event.StopSuiteContainers;
|
||||
import org.jboss.arquillian.core.api.Event;
|
||||
import org.jboss.arquillian.test.spi.event.suite.AfterSuite;
|
||||
import org.wildfly.extras.creaper.core.ManagementClient;
|
||||
import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
|
||||
import org.wildfly.extras.creaper.core.online.OnlineOptions;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -155,6 +160,33 @@ public class CrossDCTestEnricher {
|
|||
suspendPeriodicTasks();
|
||||
}
|
||||
|
||||
private static void initializeTLS(ContainerInfo containerInfo) {
|
||||
if (AuthServerTestEnricher.AUTH_SERVER_SSL_REQUIRED) {
|
||||
log.infof("\n\n### Setting up TLS for %s ##\n\n", containerInfo);
|
||||
try {
|
||||
OnlineManagementClient client = getManagementClient(containerInfo);
|
||||
AuthServerTestEnricher.enableTLS(client);
|
||||
client.close();
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to set up TLS. This may lead to unexpected behavior unless the test" +
|
||||
" sets it up manually", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static OnlineManagementClient getManagementClient(ContainerInfo containerInfo) {
|
||||
try {
|
||||
return ManagementClient.online(OnlineOptions
|
||||
.standalone()
|
||||
.hostAndPort("localhost", Integer.valueOf(containerInfo.getProperties().get("managementPort")))
|
||||
.build()
|
||||
);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void afterTest(@Observes After event) {
|
||||
if (!suiteContext.isAuthServerCrossDc()) return;
|
||||
|
||||
|
@ -219,15 +251,15 @@ public class CrossDCTestEnricher {
|
|||
|
||||
private static Keycloak createAdminClientFor(ContainerInfo node) {
|
||||
log.info("--DC: Initializing admin client for " + node.getContextRoot() + "/auth");
|
||||
return Keycloak.getInstance(node.getContextRoot() + "/auth", AuthRealm.MASTER, AuthRealm.ADMIN, AuthRealm.ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
||||
return Keycloak.getInstance(node.getContextRoot() + "/auth", AuthRealm.MASTER, AuthRealm.ADMIN, AuthRealm.ADMIN, Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS());
|
||||
}
|
||||
|
||||
private static KeycloakTestingClient createTestingClientFor(ContainerInfo node) {
|
||||
log.info("--DC: Initializing testing client for " + node.getContextRoot() + "/auth");
|
||||
return KeycloakTestingClient.getInstance(node.getContextRoot() + "/auth");
|
||||
}
|
||||
|
||||
// Disable periodic tasks in cross-dc tests. It's needed to have some scenarios more stable.
|
||||
|
||||
private static void suspendPeriodicTasks() {
|
||||
log.debug("--DC: suspendPeriodicTasks");
|
||||
backendTestingClients.values().stream().forEach((KeycloakTestingClient testingClient) -> {
|
||||
|
@ -327,6 +359,7 @@ public class CrossDCTestEnricher {
|
|||
if (! containerInfo.isStarted()) {
|
||||
log.infof("--DC: Starting backend auth-server node: %s", containerInfo.getQualifier());
|
||||
containerController.get().start(containerInfo.getQualifier());
|
||||
initializeTLS(containerInfo);
|
||||
createRESTClientsForNode(containerInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
package org.keycloak.testsuite.client;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
|
||||
|
@ -42,6 +45,10 @@ public class KeycloakTestingClient implements AutoCloseable {
|
|||
} else {
|
||||
ResteasyClientBuilder resteasyClientBuilder = new ResteasyClientBuilder();
|
||||
resteasyClientBuilder.connectionPoolSize(10);
|
||||
if (serverUrl.startsWith("https")) {
|
||||
// Disable PKIX path validation errors when running tests using SSL
|
||||
resteasyClientBuilder.disableTrustManager().hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY);
|
||||
}
|
||||
resteasyClientBuilder.httpEngine(AdminClientUtil.getCustomClientHttpEngine(resteasyClientBuilder, 10));
|
||||
client = resteasyClientBuilder.build();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.jboss.arquillian.drone.webdriver.spi.BrowserCapabilitiesRegistry;
|
|||
import org.jboss.logging.Logger;
|
||||
import org.openqa.selenium.Capabilities;
|
||||
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
|
||||
import org.openqa.selenium.remote.CapabilityType;
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -53,11 +54,17 @@ public class KeycloakWebDriverConfigurator {
|
|||
updateCapabilityKeys("htmlUnit", webDriverCfg, capabilitiesToAdd);
|
||||
updateCapabilityKeys("appium", webDriverCfg, capabilitiesToAdd);
|
||||
configurePhantomJSDriver(webDriverCfg, capabilitiesToAdd);
|
||||
acceptAllSSLCerts(capabilitiesToAdd);
|
||||
|
||||
BrowserCapabilities browserCap = registryInstance.get().getEntryFor(webDriverCfg.getBrowser());
|
||||
webDriverCfg.setBrowserInternal(new KcBrowserCapabilities(capabilitiesToAdd, browserCap));
|
||||
}
|
||||
|
||||
private void acceptAllSSLCerts(DesiredCapabilities capabilitiesToAdd) {
|
||||
capabilitiesToAdd.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
|
||||
capabilitiesToAdd.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS, true);
|
||||
}
|
||||
|
||||
private void configurePhantomJSDriver(WebDriverConfiguration webDriverCfg, DesiredCapabilities capabilitiesToAdd) {
|
||||
if (!webDriverCfg.getBrowser().equals("phantomjs")) {
|
||||
return;
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.jboss.arquillian.test.api.ArquillianResource;
|
|||
import org.junit.Assert;
|
||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||
import org.keycloak.testsuite.arquillian.SuiteContext;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
|
@ -38,6 +39,9 @@ public abstract class AbstractPage {
|
|||
@ArquillianResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@ArquillianResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
public void assertCurrent() {
|
||||
String name = getClass().getSimpleName();
|
||||
Assert.assertTrue("Expected " + name + " but was " + driver.getTitle() + " (" + driver.getCurrentUrl() + ")",
|
||||
|
|
|
@ -29,20 +29,17 @@ import javax.ws.rs.core.UriBuilder;
|
|||
*/
|
||||
public class AppPage extends AbstractPage {
|
||||
|
||||
public static final String AUTH_SERVER_URL = "http://localhost:8180/auth";
|
||||
public static final String baseUrl = "http://localhost:8180/auth/realms/master/app/auth";
|
||||
|
||||
@FindBy(id = "account")
|
||||
private WebElement accountLink;
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
driver.navigate().to(baseUrl);
|
||||
driver.navigate().to(oauth.APP_AUTH_ROOT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrent() {
|
||||
return driver.getCurrentUrl().startsWith(baseUrl);
|
||||
return driver.getCurrentUrl().startsWith(oauth.APP_AUTH_ROOT);
|
||||
}
|
||||
|
||||
public RequestType getRequestType() {
|
||||
|
@ -58,10 +55,9 @@ public class AppPage extends AbstractPage {
|
|||
}
|
||||
|
||||
public void logout() {
|
||||
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(AUTH_SERVER_URL))
|
||||
.queryParam(OAuth2Constants.REDIRECT_URI,baseUrl).build("test").toString();
|
||||
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(oauth.AUTH_SERVER_ROOT))
|
||||
.queryParam(OAuth2Constants.REDIRECT_URI, oauth.APP_AUTH_ROOT).build("test").toString();
|
||||
driver.navigate().to(logoutUri);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public class ApplicationServlet extends HttpServlet {
|
|||
|
||||
PrintWriter pw = resp.getWriter();
|
||||
pw.printf("<html><head><title>%s</title></head><body>", title);
|
||||
UriBuilder base = UriBuilder.fromUri("http://localhost:8081/auth");
|
||||
UriBuilder base = UriBuilder.fromUri("/auth");
|
||||
pw.printf(LINK, RealmsResource.accountUrl(base).build("test"), "account", "account");
|
||||
|
||||
pw.print("</body></html>");
|
||||
|
|
|
@ -91,6 +91,7 @@ public class OAuthClient {
|
|||
public static String SERVER_ROOT;
|
||||
public static String AUTH_SERVER_ROOT;
|
||||
public static String APP_ROOT;
|
||||
public static String APP_AUTH_ROOT;
|
||||
private static final boolean sslRequired = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required"));
|
||||
|
||||
static {
|
||||
|
@ -102,6 +103,7 @@ public class OAuthClient {
|
|||
SERVER_ROOT = serverRoot;
|
||||
AUTH_SERVER_ROOT = SERVER_ROOT + "/auth";
|
||||
APP_ROOT = AUTH_SERVER_ROOT + "/realms/master/app";
|
||||
APP_AUTH_ROOT = APP_ROOT + "/auth";
|
||||
}
|
||||
|
||||
private WebDriver driver;
|
||||
|
@ -659,7 +661,7 @@ public class OAuthClient {
|
|||
|
||||
public OIDCConfigurationRepresentation doWellKnownRequest(String realm) {
|
||||
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
||||
return SimpleHttp.doGet(AUTH_SERVER_ROOT + "/realms/" + realm + "/.well-known/openid-configuration", client).asJson(OIDCConfigurationRepresentation.class);
|
||||
return SimpleHttp.doGet(baseUrl + "/realms/" + realm + "/.well-known/openid-configuration", client).asJson(OIDCConfigurationRepresentation.class);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
|
|
@ -35,9 +35,11 @@ import org.keycloak.admin.client.resource.UserResource;
|
|||
import org.keycloak.admin.client.resource.UsersResource;
|
||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.resources.account.AccountFormService;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.KcArquillian;
|
||||
|
@ -70,7 +72,17 @@ import org.wildfly.extras.creaper.core.online.operations.Operations;
|
|||
import org.wildfly.extras.creaper.core.online.operations.admin.Administration;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -79,6 +91,7 @@ import java.util.Calendar;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -98,6 +111,8 @@ import static org.keycloak.testsuite.util.URLUtils.navigateToUri;
|
|||
public abstract class AbstractKeycloakTest {
|
||||
|
||||
protected static final boolean AUTH_SERVER_SSL_REQUIRED = Boolean.parseBoolean(System.getProperty("auth.server.ssl.required", "false"));
|
||||
protected static final String AUTH_SERVER_SCHEME = AUTH_SERVER_SSL_REQUIRED ? "https" : "http";
|
||||
protected static final String AUTH_SERVER_PORT = AUTH_SERVER_SSL_REQUIRED ? System.getProperty("auth.server.https.port", "8543") : System.getProperty("auth.server.http.port", "8180");
|
||||
|
||||
protected static final String ENGLISH_LOCALE_NAME = "English";
|
||||
|
||||
|
@ -145,13 +160,6 @@ public abstract class AbstractKeycloakTest {
|
|||
|
||||
private boolean resetTimeOffset;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpAuthServer() throws Exception {
|
||||
if (AUTH_SERVER_SSL_REQUIRED) {
|
||||
enableHTTPSForAuthServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void beforeAbstractKeycloakTest() throws Exception {
|
||||
adminClient = testContext.getAdminClient();
|
||||
|
@ -364,10 +372,66 @@ public abstract class AbstractKeycloakTest {
|
|||
addTestRealms();
|
||||
log.info("importing test realms");
|
||||
for (RealmRepresentation testRealm : testRealmReps) {
|
||||
if (modifyRealmForSSL()) {
|
||||
if (AUTH_SERVER_SSL_REQUIRED) {
|
||||
log.debugf("Modifying %s for SSL", testRealm.getId());
|
||||
for (ClientRepresentation cr : testRealm.getClients()) {
|
||||
modifyMainUrls(cr);
|
||||
modifyRedirectUrls(cr);
|
||||
modifySamlAttributes(cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
importRealm(testRealm);
|
||||
}
|
||||
}
|
||||
|
||||
private void modifySamlAttributes(ClientRepresentation cr) {
|
||||
if (cr.getProtocol() != null && cr.getProtocol().equals("saml")) {
|
||||
log.info("Modifying attributes of SAML client: " + cr.getClientId());
|
||||
for (Map.Entry<String, String> entry : cr.getAttributes().entrySet()) {
|
||||
cr.getAttributes().put(entry.getKey(), replaceHttpValuesWithHttps(entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void modifyRedirectUrls(ClientRepresentation cr) {
|
||||
if (cr.getRedirectUris() != null && cr.getRedirectUris().size() > 0) {
|
||||
List<String> redirectUrls = cr.getRedirectUris();
|
||||
List<String> fixedRedirectUrls = new ArrayList<>(redirectUrls.size());
|
||||
for (String url : redirectUrls) {
|
||||
fixedRedirectUrls.add(replaceHttpValuesWithHttps(url));
|
||||
}
|
||||
cr.setRedirectUris(fixedRedirectUrls);
|
||||
}
|
||||
}
|
||||
|
||||
private void modifyMainUrls(ClientRepresentation cr) {
|
||||
cr.setBaseUrl(replaceHttpValuesWithHttps(cr.getBaseUrl()));
|
||||
cr.setAdminUrl(replaceHttpValuesWithHttps(cr.getAdminUrl()));
|
||||
}
|
||||
|
||||
private String replaceHttpValuesWithHttps(String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
if ("".equals(input)) {
|
||||
return "";
|
||||
}
|
||||
return input
|
||||
.replace("http", "https")
|
||||
.replace("8080", "8543")
|
||||
.replace("8180", "8543");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Return <code>true</code> if you wish to automatically post-process realm and replace
|
||||
* all http values with https (and correct ports).
|
||||
*/
|
||||
protected boolean modifyRealmForSSL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected void removeAllRealmsDespiteMaster() {
|
||||
// remove all realms (accidentally left by other tests) except for master
|
||||
|
@ -536,28 +600,31 @@ public abstract class AbstractKeycloakTest {
|
|||
return log;
|
||||
}
|
||||
|
||||
private static void enableHTTPSForAuthServer() throws IOException, CommandFailedException, TimeoutException, InterruptedException, CliException, OperationException {
|
||||
OnlineManagementClient client = AuthServerTestEnricher.getManagementClient();
|
||||
Administration administration = new Administration(client);
|
||||
Operations operations = new Operations(client);
|
||||
|
||||
if(!operations.exists(Address.coreService("management").and("security-realm", "UndertowRealm"))) {
|
||||
client.execute("/core-service=management/security-realm=UndertowRealm:add()");
|
||||
client.execute("/core-service=management/security-realm=UndertowRealm/server-identity=ssl:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.jks");
|
||||
client.execute("/core-service=management/security-realm=UndertowRealm/authentication=truststore:add(keystore-relative-to=jboss.server.config.dir,keystore-password=secret,keystore-path=keycloak.truststore");
|
||||
protected String getAccountRedirectUrl(String realm) {
|
||||
return AccountFormService
|
||||
.loginRedirectUrl(UriBuilder.fromUri(oauth.AUTH_SERVER_ROOT))
|
||||
.build(realm)
|
||||
.toString();
|
||||
}
|
||||
|
||||
client.apply(new RemoveUndertowListener.Builder(UndertowListenerType.HTTPS_LISTENER, "https")
|
||||
.forDefaultServer());
|
||||
protected String getAccountRedirectUrl() {
|
||||
return getAccountRedirectUrl("test");
|
||||
}
|
||||
|
||||
administration.reloadIfRequired();
|
||||
|
||||
client.apply(new AddUndertowListener.HttpsBuilder("https", "default-server", "https")
|
||||
.securityRealm("UndertowRealm")
|
||||
.verifyClient(SslVerifyClient.REQUESTED)
|
||||
.build());
|
||||
|
||||
administration.reloadIfRequired();
|
||||
client.close();
|
||||
protected static InputStream httpsAwareConfigurationStream(InputStream input) throws IOException {
|
||||
if (!AUTH_SERVER_SSL_REQUIRED) {
|
||||
return input;
|
||||
}
|
||||
PipedInputStream in = new PipedInputStream();
|
||||
final PipedOutputStream out = new PipedOutputStream(in);
|
||||
try (PrintWriter pw = new PrintWriter(out)) {
|
||||
try (Scanner s = new Scanner(input)) {
|
||||
while (s.hasNextLine()) {
|
||||
String lineWithReplaces = s.nextLine().replace("http://localhost:8180/auth", AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT + "/auth");
|
||||
pw.println(lineWithReplaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,8 @@ public class AssertEvents implements TestRule {
|
|||
public static final String DEFAULT_REALM = "test";
|
||||
public static final String DEFAULT_USERNAME = "test-user@localhost";
|
||||
|
||||
String defaultRedirectUri = "http://localhost:8180/auth/realms/master/app/auth";
|
||||
public static final String DEFAULT_HTTP_REDIRECT_URI = "http://localhost:8180/auth/realms/master/app/auth";
|
||||
public static final String DEFAULT_HTTPS_REDIRECT_URI = "https://localhost:8543/auth/realms/master/app/auth";
|
||||
|
||||
private AbstractKeycloakTest context;
|
||||
|
||||
|
@ -100,7 +101,7 @@ public class AssertEvents implements TestRule {
|
|||
//.detail(Details.USERNAME, DEFAULT_USERNAME)
|
||||
//.detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL)
|
||||
//.detail(Details.AUTH_TYPE, AuthorizationEndpoint.CODE_AUTH_TYPE)
|
||||
.detail(Details.REDIRECT_URI, defaultRedirectUri)
|
||||
.detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI)))
|
||||
.detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED)
|
||||
.session(isUUID());
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ public class AssertEvents implements TestRule {
|
|||
.detail(Details.CODE_ID, isCodeId())
|
||||
.detail(Details.USERNAME, DEFAULT_USERNAME)
|
||||
.detail(Details.AUTH_METHOD, "form")
|
||||
.detail(Details.REDIRECT_URI, defaultRedirectUri)
|
||||
.detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI)))
|
||||
.session(isUUID());
|
||||
}
|
||||
|
||||
|
@ -145,7 +146,7 @@ public class AssertEvents implements TestRule {
|
|||
|
||||
public ExpectedEvent expectLogout(String sessionId) {
|
||||
return expect(EventType.LOGOUT).client((String) null)
|
||||
.detail(Details.REDIRECT_URI, defaultRedirectUri)
|
||||
.detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI)))
|
||||
.session(sessionId);
|
||||
}
|
||||
|
||||
|
@ -163,7 +164,7 @@ public class AssertEvents implements TestRule {
|
|||
.detail(Details.USERNAME, username)
|
||||
.detail(Details.EMAIL, email)
|
||||
.detail(Details.REGISTER_METHOD, "form")
|
||||
.detail(Details.REDIRECT_URI, defaultRedirectUri);
|
||||
.detail(Details.REDIRECT_URI, Matchers.anyOf(Matchers.equalTo(DEFAULT_HTTP_REDIRECT_URI), Matchers.equalTo(DEFAULT_HTTPS_REDIRECT_URI)));
|
||||
}
|
||||
|
||||
public ExpectedEvent expectAccount(EventType event) {
|
||||
|
|
|
@ -38,7 +38,6 @@ import org.keycloak.representations.idm.ClientRepresentation;
|
|||
import org.keycloak.representations.idm.EventRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.services.resources.account.AccountFormService;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
|
@ -70,7 +69,6 @@ import java.util.Collections;
|
|||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -85,6 +83,8 @@ import static org.junit.Assert.assertFalse;
|
|||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||
|
@ -135,11 +135,13 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
RealmBuilder.edit(testRealm)
|
||||
.user(user2)
|
||||
.user(realmAdmin);
|
||||
}
|
||||
|
||||
private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth");
|
||||
private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString();
|
||||
public static String ACCOUNT_REDIRECT = AccountFormService.loginRedirectUrl(BASE.clone()).build("test").toString();
|
||||
if (AUTH_SERVER_SSL_REQUIRED) {
|
||||
// Some scenarios here use redirections, so we need to fix the base url
|
||||
findTestApp(testRealm)
|
||||
.setBaseUrl(String.format("%s://localhost:%s/auth/realms/master/app/auth", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT));
|
||||
}
|
||||
}
|
||||
|
||||
// Create second session
|
||||
@Drone
|
||||
|
@ -203,12 +205,12 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
Assert.assertTrue(appPage.isCurrent());
|
||||
|
||||
driver.navigate().to(profilePage.getPath() + "?referrer=test-app&referrer_uri=http://localhost:8180/auth/realms/master/app/auth?test");
|
||||
driver.navigate().to(String.format("%s?referrer=test-app&referrer_uri=%s://localhost:%s/auth/realms/master/app/auth?test", profilePage.getPath(), AUTH_SERVER_SCHEME, AUTH_SERVER_PORT));
|
||||
Assert.assertTrue(profilePage.isCurrent());
|
||||
profilePage.backToApplication();
|
||||
|
||||
Assert.assertTrue(appPage.isCurrent());
|
||||
Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
|
||||
Assert.assertEquals(oauth.APP_AUTH_ROOT + "?test", driver.getCurrentUrl());
|
||||
|
||||
driver.navigate().to(profilePage.getPath() + "?referrer=test-app");
|
||||
Assert.assertTrue(profilePage.isCurrent());
|
||||
|
@ -242,7 +244,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
EventRepresentation event = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
EventRepresentation event = events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
String sessionId = event.getSessionId();
|
||||
String userId = event.getUserId();
|
||||
|
||||
|
@ -288,7 +290,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
public void changePasswordWithBlankCurrentPassword() {
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("", "new", "new");
|
||||
Assert.assertEquals("Please specify password.", profilePage.getError());
|
||||
|
@ -305,7 +307,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("password", "1234", "1234");
|
||||
Assert.assertEquals("Invalid password: minimum length 8.", profilePage.getError());
|
||||
|
@ -322,7 +324,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("password", "invalidPassword1", "invalidPassword1");
|
||||
Assert.assertEquals("Invalid password: must contain at least 2 numerical digits.", profilePage.getError());
|
||||
|
@ -339,7 +341,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("password", "iNVALIDPASSWORD", "iNVALIDPASSWORD");
|
||||
Assert.assertEquals("Invalid password: must contain at least 2 lower case characters.", profilePage.getError());
|
||||
|
@ -356,7 +358,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("password", "Invalidpassword", "Invalidpassword");
|
||||
Assert.assertEquals("Invalid password: must contain at least 2 upper case characters.", profilePage.getError());
|
||||
|
@ -374,7 +376,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("password", "invalidPassword*", "invalidPassword*");
|
||||
Assert.assertEquals("Invalid password: must contain at least 2 special characters.", profilePage.getError());
|
||||
|
@ -392,7 +394,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("password", "test-user@localhost", "test-user@localhost");
|
||||
Assert.assertEquals("Invalid password: must not be equal to the username.", profilePage.getError());
|
||||
|
@ -410,7 +412,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
changePasswordPage.changePassword("password", "invalidPassword", "invalidPassword");
|
||||
Assert.assertEquals("Invalid password: fails to match regex pattern(s).", profilePage.getError());
|
||||
|
@ -456,7 +458,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("user-changePasswordWithPasswordHistoryPolicyThreePasswords", "password");
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
assertChangePasswordFails ("password", "password"); // current: password
|
||||
assertNumberOfStoredCredentials(1);
|
||||
|
@ -491,7 +493,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("user-changePasswordWithPasswordHistoryPolicyTwoPasswords", "password");
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
assertChangePasswordFails ("password", "password"); // current: password
|
||||
assertNumberOfStoredCredentials(1);
|
||||
|
@ -522,7 +524,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("user-changePasswordWithPasswordHistoryPolicyOnePwds", "password");
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
assertChangePasswordFails ("password", "password"); // current: password
|
||||
assertNumberOfStoredCredentials(1);
|
||||
|
@ -543,7 +545,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("user-changePasswordWithPasswordHistoryPolicyZeroPwdsInHistory", "password");
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
assertChangePasswordFails ("password", "password"); // current: password
|
||||
assertNumberOfStoredCredentials(1);
|
||||
|
@ -564,7 +566,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
changePasswordPage.open();
|
||||
loginPage.login("user-changePasswordWithPasswordHistoryPolicyExpiration", "password");
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
|
||||
events.expectLogin().user(userId).client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=password").assertEvent();
|
||||
|
||||
assertNumberOfStoredCredentials(1);
|
||||
assertChangePasswordSucceeds("password", "password2"); // current: password
|
||||
|
@ -597,7 +599,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
profilePage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent();
|
||||
|
||||
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
|
||||
Assert.assertEquals("Tom", profilePage.getFirstName());
|
||||
|
@ -736,7 +738,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
profilePage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent();
|
||||
|
||||
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
|
||||
Assert.assertEquals("Tom", profilePage.getFirstName());
|
||||
|
@ -845,7 +847,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
profilePage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent();
|
||||
|
||||
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
|
||||
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
|
||||
|
@ -883,7 +885,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
profilePage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent();
|
||||
|
||||
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
|
||||
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
|
||||
|
@ -899,7 +901,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
totpPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=totp").assertEvent();
|
||||
|
||||
Assert.assertTrue(totpPage.isCurrent());
|
||||
|
||||
|
@ -968,7 +970,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
UserRepresentation noAccessUser = this.findUser("test-user-no-access@localhost");
|
||||
events.expectLogin().client("account").user(noAccessUser.getId())
|
||||
.detail(Details.USERNAME, "test-user-no-access@localhost")
|
||||
.detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
|
||||
.detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent();
|
||||
|
||||
Assert.assertTrue("Expected errorPage but was " + driver.getTitle() + " (" + driver.getCurrentUrl() + "). Page source: " + driver.getPageSource(), errorPage.isCurrent());
|
||||
Assert.assertEquals("No access", errorPage.getError());
|
||||
|
@ -1126,7 +1128,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
applicationsPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=applications").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=applications").assertEvent();
|
||||
applicationsPage.assertCurrent();
|
||||
|
||||
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
|
||||
|
@ -1140,13 +1142,13 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
"Offline access"
|
||||
));
|
||||
Assert.assertThat(accountEntry.getClientScopesGranted(), containsInAnyOrder("Full Access"));
|
||||
Assert.assertEquals("http://localhost:8180/auth/realms/test/account", accountEntry.getHref());
|
||||
Assert.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test/account", accountEntry.getHref());
|
||||
|
||||
AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app");
|
||||
Assert.assertEquals(6, testAppEntry.getRolesAvailable().size());
|
||||
Assert.assertTrue(testAppEntry.getRolesAvailable().contains("Offline access"));
|
||||
Assert.assertTrue(testAppEntry.getClientScopesGranted().contains("Full Access"));
|
||||
Assert.assertEquals("http://localhost:8180/auth/realms/master/app/auth", testAppEntry.getHref());
|
||||
Assert.assertEquals(oauth.APP_AUTH_ROOT, testAppEntry.getHref());
|
||||
|
||||
AccountApplicationsPage.AppEntry thirdPartyEntry = apps.get("third-party");
|
||||
Assert.assertEquals(3, thirdPartyEntry.getRolesAvailable().size());
|
||||
|
@ -1162,7 +1164,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
|
|||
Assert.assertEquals("http://localhost:8180/foo/bar/baz", rootUrlClient.getHref());
|
||||
|
||||
AccountApplicationsPage.AppEntry authzApp = apps.get("test-app-authz");
|
||||
Assert.assertEquals("http://localhost:8180/test-app-authz", authzApp.getHref());
|
||||
Assert.assertEquals(oauth.SERVER_ROOT + "/test-app-authz", authzApp.getHref());
|
||||
|
||||
AccountApplicationsPage.AppEntry namedApp = apps.get("My Named Test App");
|
||||
Assert.assertEquals("http://localhost:8180/namedapp/base", namedApp.getHref());
|
||||
|
|
|
@ -352,7 +352,7 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest {
|
|||
public void conditionalOTPRequestHeaderSkip() {
|
||||
//prepare config - request header skip, default to force
|
||||
Map<String, String> config = new HashMap<>();
|
||||
String port = System.getProperty("auth.server.http.port", "8180");
|
||||
String port = AUTH_SERVER_PORT;
|
||||
config.put(SKIP_OTP_FOR_HTTP_HEADER, "Host: localhost:" + port);
|
||||
config.put(DEFAULT_OTP_OUTCOME, FORCE);
|
||||
|
||||
|
@ -368,7 +368,7 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest {
|
|||
public void conditionalOTPRequestHeaderForce() {
|
||||
//prepare config - equest header force, default to skip
|
||||
Map<String, String> config = new HashMap<>();
|
||||
String port = System.getProperty("auth.server.http.port", "8180");
|
||||
String port = AUTH_SERVER_PORT;
|
||||
config.put(FORCE_OTP_FOR_HTTP_HEADER, "Host: localhost:" + port);
|
||||
config.put(DEFAULT_OTP_OUTCOME, SKIP);
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.keycloak.testsuite.account.custom;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
|
@ -25,6 +27,7 @@ import org.keycloak.events.Details;
|
|||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.resources.account.AccountFormService;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.account.AccountFormServiceTest;
|
||||
|
@ -68,7 +71,7 @@ public class CustomThemeTest extends AbstractTestRealmKeycloakTest {
|
|||
profilePage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, AccountFormServiceTest.ACCOUNT_REDIRECT).assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent();
|
||||
|
||||
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
|
||||
Assert.assertEquals("", profilePage.getAttribute("street"));
|
||||
|
|
|
@ -89,23 +89,31 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest {
|
|||
log.info("Setting redirect-uris in test realm '" + tr.getRealm() + "' as " + (isRelative() ? "" : "non-") + "relative");
|
||||
|
||||
modifyClientRedirectUris(tr, "http://localhost:8080", "");
|
||||
modifyClientRedirectUris(tr, "^(/.*/\\*)",
|
||||
"http://localhost:" + System.getProperty("app.server.http.port", "8280") + "$1",
|
||||
"http://localhost:" + System.getProperty("auth.server.http.port", "8180") + "$1",
|
||||
"https://localhost:" + System.getProperty("app.server.https.port", "8643") + "$1",
|
||||
"https://localhost:" + System.getProperty("auth.server.http.port", "8543") + "$1");
|
||||
|
||||
modifyClientWebOrigins(tr, "http://localhost:8080",
|
||||
"http://localhost:" + System.getProperty("app.server.http.port", "8280"),
|
||||
"http://localhost:" + System.getProperty("auth.server.http.port", "8180"),
|
||||
"https://localhost:" + System.getProperty("app.server.https.port", "8643"),
|
||||
"https://localhost:" + System.getProperty("auth.server.http.port", "8543"));
|
||||
|
||||
modifyClientUrls(tr, "http://localhost:8080", "");
|
||||
|
||||
if (isRelative()) {
|
||||
modifyClientRedirectUris(tr, appServerContextRootPage.toString(), "");
|
||||
modifyClientUrls(tr, appServerContextRootPage.toString(), "");
|
||||
modifyClientWebOrigins(tr, "8080", System.getProperty("auth.server.http.port", null));
|
||||
modifySamlMasterURLs(tr, "/", "http://localhost:" + System.getProperty("auth.server.http.port", null) + "/");
|
||||
modifySAMLClientsAttributes(tr, "8080", System.getProperty("auth.server.http.port", "8180"));
|
||||
} else {
|
||||
modifyClientRedirectUris(tr, "^(/.*/\\*)", appServerContextRootPage.toString() + "$1");
|
||||
modifyClientUrls(tr, "^(/.*)", appServerContextRootPage.toString() + "$1");
|
||||
modifyClientWebOrigins(tr, "8080", System.getProperty("app.server.http.port", null));
|
||||
modifySamlMasterURLs(tr, "8080", System.getProperty("auth.server.http.port", null));
|
||||
modifySamlMasterURLs(tr, "8080", AUTH_SERVER_PORT);
|
||||
modifySAMLClientsAttributes(tr, "http://localhost:8080", appServerContextRootPage.toString());
|
||||
modifyClientJWKSUrl(tr, "^(/.*)", appServerContextRootPage.toString() + "$1");
|
||||
}
|
||||
if ("true".equals(System.getProperty("auth.server.ssl.required"))) {
|
||||
if (AUTH_SERVER_SSL_REQUIRED) {
|
||||
tr.setSslRequired("all");
|
||||
}
|
||||
}
|
||||
|
@ -135,14 +143,17 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest {
|
|||
return testContext.isRelativeAdapterTest();
|
||||
}
|
||||
|
||||
protected void modifyClientRedirectUris(RealmRepresentation realm, String regex, String replacement) {
|
||||
protected void modifyClientRedirectUris(RealmRepresentation realm, String regex, String... replacement) {
|
||||
if (realm.getClients() != null) {
|
||||
for (ClientRepresentation client : realm.getClients()) {
|
||||
List<String> redirectUris = client.getRedirectUris();
|
||||
if (redirectUris != null) {
|
||||
List<String> newRedirectUris = new ArrayList<>();
|
||||
for (String uri : redirectUris) {
|
||||
newRedirectUris.add(uri.replaceAll(regex, replacement));
|
||||
for (String uriReplacement : replacement) {
|
||||
newRedirectUris.add(uri.replaceAll(regex, uriReplacement));
|
||||
}
|
||||
|
||||
}
|
||||
client.setRedirectUris(newRedirectUris);
|
||||
}
|
||||
|
@ -165,14 +176,16 @@ public abstract class AbstractAdapterTest extends AbstractAuthTest {
|
|||
}
|
||||
}
|
||||
|
||||
protected void modifyClientWebOrigins(RealmRepresentation realm, String regex, String replacement) {
|
||||
protected void modifyClientWebOrigins(RealmRepresentation realm, String regex, String... replacement) {
|
||||
if (realm.getClients() != null) {
|
||||
for (ClientRepresentation client : realm.getClients()) {
|
||||
List<String> webOrigins = client.getWebOrigins();
|
||||
if (webOrigins != null) {
|
||||
List<String> newWebOrigins = new ArrayList<>();
|
||||
for (String uri : webOrigins) {
|
||||
newWebOrigins.add(uri.replaceAll(regex, replacement));
|
||||
for (String originReplacement : replacement) {
|
||||
newWebOrigins.add(uri.replaceAll(regex, originReplacement));
|
||||
}
|
||||
}
|
||||
client.setWebOrigins(newWebOrigins);
|
||||
}
|
||||
|
|
|
@ -23,11 +23,14 @@ import org.jboss.shrinkwrap.api.asset.StringAsset;
|
|||
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Assert;
|
||||
import org.keycloak.testsuite.utils.arquillian.DeploymentArchiveProcessorUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -55,13 +58,37 @@ public abstract class AbstractExampleAdapterTest extends AbstractAdapterTest {
|
|||
EXAMPLES_WEB_XML = EXAMPLES_HOME + "/web.xml";
|
||||
}
|
||||
|
||||
protected static WebArchive exampleDeployment(String name) throws IOException {
|
||||
return ShrinkWrap.createFromZipFile(WebArchive.class,
|
||||
protected static WebArchive exampleDeployment(String name) {
|
||||
return exampleDeployment(name, webArchive -> {});
|
||||
}
|
||||
|
||||
protected static WebArchive exampleDeployment(String name, Consumer<WebArchive> additionalResources) {
|
||||
WebArchive webArchive = ShrinkWrap.createFromZipFile(WebArchive.class,
|
||||
new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war"))
|
||||
.addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML);
|
||||
|
||||
additionalResources.accept(webArchive);
|
||||
|
||||
modifyOIDCAdapterConfig(webArchive);
|
||||
|
||||
return webArchive;
|
||||
}
|
||||
|
||||
protected static void modifyOIDCAdapterConfig(WebArchive webArchive) {
|
||||
if (webArchive.contains(DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH)) {
|
||||
DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(webArchive, DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH);
|
||||
}
|
||||
|
||||
if (webArchive.contains(DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH_JS)) {
|
||||
DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(webArchive, DeploymentArchiveProcessorUtils.ADAPTER_CONFIG_PATH_JS);
|
||||
}
|
||||
}
|
||||
|
||||
protected static WebArchive exampleDeployment(String name, String contextPath) throws IOException {
|
||||
return exampleDeployment(name, contextPath, webArchive -> {});
|
||||
}
|
||||
|
||||
protected static WebArchive exampleDeployment(String name, String contextPath, Consumer<WebArchive> additionalResources) throws IOException {
|
||||
URL webXML = Paths.get(EXAMPLES_WEB_XML).toUri().toURL();
|
||||
String webXmlContent = IOUtils.toString(webXML.openStream(), "UTF-8")
|
||||
.replace("%CONTEXT_PATH%", contextPath);
|
||||
|
@ -69,12 +96,12 @@ public abstract class AbstractExampleAdapterTest extends AbstractAdapterTest {
|
|||
new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".war"))
|
||||
.addAsWebInfResource(jbossDeploymentStructure, JBOSS_DEPLOYMENT_STRUCTURE_XML)
|
||||
.add(new StringAsset(webXmlContent), "/WEB-INF/web.xml");
|
||||
|
||||
additionalResources.accept(webArchive);
|
||||
|
||||
modifyOIDCAdapterConfig(webArchive);
|
||||
|
||||
return webArchive;
|
||||
}
|
||||
|
||||
protected static JavaArchive exampleJarDeployment(String name) {
|
||||
return ShrinkWrap.createFromZipFile(JavaArchive.class,
|
||||
new File(EXAMPLES_HOME + "/" + name + "-" + EXAMPLES_VERSION_SUFFIX + ".jar"));
|
||||
}
|
||||
|
||||
}
|
|
@ -24,6 +24,7 @@ import org.jboss.shrinkwrap.api.spec.WebArchive;
|
|||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
|
||||
import org.keycloak.testsuite.util.WaitUtils;
|
||||
import org.keycloak.testsuite.utils.arquillian.DeploymentArchiveProcessorUtils;
|
||||
import org.keycloak.testsuite.utils.io.IOUtil;
|
||||
import org.openqa.selenium.By;
|
||||
|
||||
|
@ -51,9 +52,16 @@ public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest {
|
|||
URL config2Url = AbstractServletsAdapterTest.class.getResource(webInfPath + config2);
|
||||
Assert.assertNotNull("config2Url should be in " + webInfPath + config2, config2Url);
|
||||
|
||||
return servletDeployment
|
||||
servletDeployment
|
||||
.add(new UrlAsset(config1Url), "/WEB-INF/classes/" + config1)
|
||||
.add(new UrlAsset(config2Url), "/WEB-INF/classes/" + config2);
|
||||
|
||||
// In this scenario DeploymentArchiveProcessorUtils can not act automatically since the adapter configurations
|
||||
// are not stored in typical places. We need to modify them manually.
|
||||
DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(servletDeployment, "/WEB-INF/classes/" + config1);
|
||||
DeploymentArchiveProcessorUtils.modifyOIDCAdapterConfig(servletDeployment, "/WEB-INF/classes/" + config2);
|
||||
|
||||
return servletDeployment;
|
||||
}
|
||||
|
||||
protected static WebArchive servletDeployment(String name, Class... servletClasses) {
|
||||
|
|
|
@ -2,7 +2,9 @@ package org.keycloak.testsuite.adapter.example.authorization;
|
|||
|
||||
import org.jboss.arquillian.drone.api.annotation.Drone;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
|
||||
|
@ -52,6 +54,11 @@ public abstract class AbstractPhotozJavascriptExecutorTest extends AbstractExamp
|
|||
|
||||
protected UserRepresentation jdoeUser = UserBuilder.create().username("jdoe").password("jdoe").build();
|
||||
|
||||
@BeforeClass
|
||||
public static void checkIfTLSIsTurnedOn() {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setDefaultValues() {
|
||||
jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME);
|
||||
|
|
|
@ -44,7 +44,7 @@ public class PhotozExampleLazyLoadPathsAdapterTest extends AbstractPhotozExample
|
|||
|
||||
@Deployment(name = RESOURCE_SERVER_ID, managed = false, testable = false)
|
||||
public static WebArchive deploymentResourceServer() throws IOException {
|
||||
return exampleDeployment(RESOURCE_SERVER_ID)
|
||||
.addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/photoz/keycloak-lazy-load-path-authz-service.json"), "keycloak.json");
|
||||
return exampleDeployment(RESOURCE_SERVER_ID,
|
||||
webArchive -> webArchive.addAsWebInfResource(new File(TEST_APPS_HOME_DIR + "/photoz/keycloak-lazy-load-path-authz-service.json"), "keycloak.json"));
|
||||
}
|
||||
}
|
|
@ -55,7 +55,14 @@ import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
|
|||
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
|
||||
|
||||
/**
|
||||
* Created by fkiss.
|
||||
* Tests CORS fuctionality in adapters.
|
||||
*
|
||||
* <p>
|
||||
* Note, for SSL this test disables TLS certificate verification. Since CORS uses different hostnames
|
||||
* (localhost-auth for example), the Subject Name won't match.
|
||||
* </p>
|
||||
*
|
||||
* @author fkiss
|
||||
*/
|
||||
@AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY)
|
||||
@AppServerContainer(ContainerConstants.APP_SERVER_WILDFLY_DEPRECATED)
|
||||
|
@ -88,7 +95,7 @@ public class CorsExampleAdapterTest extends AbstractExampleAdapterTest {
|
|||
@JavascriptBrowser
|
||||
private Account jsDriverTestRealmAccount;
|
||||
|
||||
@Deployment(name = AngularCorsProductTestApp.DEPLOYMENT_NAME)
|
||||
@Deployment(name = AngularCorsProductTestApp.DEPLOYMENT_NAME, managed = false)
|
||||
protected static WebArchive angularCorsProductExample() throws IOException {
|
||||
return exampleDeployment(AngularCorsProductTestApp.CLIENT_ID);
|
||||
}
|
||||
|
@ -108,11 +115,13 @@ public class CorsExampleAdapterTest extends AbstractExampleAdapterTest {
|
|||
public void onBefore() {
|
||||
Assume.assumeFalse(System.getProperty("os.name").startsWith("Windows"));
|
||||
deployer.deploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME);
|
||||
deployer.deploy(AngularCorsProductTestApp.DEPLOYMENT_NAME);
|
||||
}
|
||||
|
||||
@After
|
||||
public void onAfter() {
|
||||
deployer.undeploy(CorsDatabaseServiceTestApp.DEPLOYMENT_NAME);
|
||||
deployer.undeploy(AngularCorsProductTestApp.DEPLOYMENT_NAME);
|
||||
}
|
||||
|
||||
static{
|
||||
|
|
|
@ -17,10 +17,19 @@
|
|||
|
||||
package org.keycloak.testsuite.adapter.jaas;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
@ -36,7 +45,10 @@ import javax.security.auth.login.LoginException;
|
|||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.KeycloakPrincipal;
|
||||
import org.keycloak.adapters.jaas.AbstractKeycloakLoginModule;
|
||||
|
@ -55,11 +67,50 @@ import org.keycloak.testsuite.utils.io.IOUtil;
|
|||
*/
|
||||
public class LoginModulesTest extends AbstractKeycloakTest {
|
||||
|
||||
public static final URI DIRECT_GRANT_CONFIG;
|
||||
public static final URI BEARER_CONFIG;
|
||||
|
||||
private static final File DIRECT_GRANT_CONFIG_FILE;
|
||||
private static final File BEARER_CONFIG_FILE;
|
||||
|
||||
static {
|
||||
try {
|
||||
DIRECT_GRANT_CONFIG = MethodHandles.lookup().lookupClass().getResource("/adapter-test/customer-portal/WEB-INF/keycloak.json").toURI();
|
||||
BEARER_CONFIG = MethodHandles.lookup().lookupClass().getResource("/adapter-test/customer-db-audience-required/WEB-INF/keycloak.json").toURI();
|
||||
|
||||
DIRECT_GRANT_CONFIG_FILE = File.createTempFile("LoginModulesTest", "testDirectAccessGrantLoginModuleLoginFailed");
|
||||
BEARER_CONFIG_FILE = File.createTempFile("LoginModulesTest", "testBearerLoginFailedLogin");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
testRealms.add(IOUtil.loadRealm("/adapter-test/demorealm.json"));
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void createTemporaryFiles() throws Exception {
|
||||
copyContentAndReplaceAuthServerAddress(new File(DIRECT_GRANT_CONFIG), DIRECT_GRANT_CONFIG_FILE);
|
||||
copyContentAndReplaceAuthServerAddress(new File(BEARER_CONFIG), BEARER_CONFIG_FILE);
|
||||
}
|
||||
|
||||
public void removeTemporaryFiles() {
|
||||
DIRECT_GRANT_CONFIG_FILE.deleteOnExit();
|
||||
BEARER_CONFIG_FILE.deleteOnExit();
|
||||
}
|
||||
|
||||
private static void copyContentAndReplaceAuthServerAddress(File input, File output) throws IOException {
|
||||
try (InputStream inputStream = httpsAwareConfigurationStream(new FileInputStream(input))) {
|
||||
try (FileOutputStream outputStream = new FileOutputStream(output)) {
|
||||
byte[] buffer = new byte[inputStream.available()];
|
||||
inputStream.read(buffer);
|
||||
outputStream.write(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void generateAudienceClientScope() {
|
||||
if (ApiUtil.findClientScopeByName(adminClient.realm("demo"), "customer-db-audience-required") != null) {
|
||||
|
@ -76,6 +127,10 @@ public class LoginModulesTest extends AbstractKeycloakTest {
|
|||
|
||||
@Test
|
||||
public void testDirectAccessGrantLoginModuleLoginFailed() throws Exception {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
|
||||
|
||||
|
||||
LoginContext loginContext = new LoginContext("does-not-matter", null,
|
||||
createJaasCallbackHandler("bburke@redhat.com", "bad-password"),
|
||||
createJaasConfigurationForDirectGrant(null));
|
||||
|
@ -91,6 +146,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
|
|||
|
||||
@Test
|
||||
public void testDirectAccessGrantLoginModuleLoginSuccess() throws Exception {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
oauth.realm("demo");
|
||||
|
||||
LoginContext loginContext = directGrantLogin(null);
|
||||
|
@ -113,6 +169,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
|
|||
|
||||
@Test
|
||||
public void testBearerLoginFailedLogin() throws Exception {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
oauth.realm("demo");
|
||||
|
||||
LoginContext directGrantCtx = directGrantLogin(null);
|
||||
|
@ -137,6 +194,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
|
|||
|
||||
@Test
|
||||
public void testBearerLoginSuccess() throws Exception {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
oauth.realm("demo");
|
||||
|
||||
LoginContext directGrantCtx = directGrantLogin("customer-db-audience-required");
|
||||
|
@ -213,7 +271,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
|
|||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, "classpath:adapter-test/customer-portal/WEB-INF/keycloak.json");
|
||||
options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, DIRECT_GRANT_CONFIG_FILE.getAbsolutePath());
|
||||
if (scope != null) {
|
||||
options.put(DirectAccessGrantsLoginModule.SCOPE_OPTION, scope);
|
||||
}
|
||||
|
@ -231,7 +289,7 @@ public class LoginModulesTest extends AbstractKeycloakTest {
|
|||
@Override
|
||||
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, "classpath:adapter-test/customer-db-audience-required/WEB-INF/keycloak.json");
|
||||
options.put(AbstractKeycloakLoginModule.KEYCLOAK_CONFIG_FILE_OPTION, BEARER_CONFIG_FILE.getAbsolutePath());
|
||||
|
||||
AppConfigurationEntry LMConfiguration = new AppConfigurationEntry(BearerTokenLoginModule.class.getName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
|
||||
return new AppConfigurationEntry[] { LMConfiguration };
|
||||
|
|
|
@ -112,7 +112,7 @@ public abstract class AbstractJavascriptTest extends AbstractAuthTest {
|
|||
.client(
|
||||
ClientBuilder.create()
|
||||
.clientId(CLIENT_ID)
|
||||
.redirectUris(JAVASCRIPT_URL + "/*", JAVASCRIPT_ENCODED_SPACE_URL + "/*")
|
||||
.redirectUris(oauth.SERVER_ROOT + JAVASCRIPT_URL + "/*", oauth.SERVER_ROOT + JAVASCRIPT_ENCODED_SPACE_URL + "/*")
|
||||
.publicClient()
|
||||
)
|
||||
.accessTokenLifespan(30 + TOKEN_LIFESPAN_LEEWAY)
|
||||
|
|
|
@ -94,6 +94,10 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
jsDriver.manage().deleteAllCookies();
|
||||
|
||||
setStandardFlowForClient();
|
||||
|
||||
//tests cleanup
|
||||
oauth.setDriver(driver);
|
||||
setTimeOffset(0);
|
||||
}
|
||||
|
||||
protected JSObjectBuilder defaultArguments() {
|
||||
|
@ -175,6 +179,7 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
|
||||
ClientResource clientResource = ApiUtil.findClientResourceByClientId(adminClient.realm(REALM_NAME), CLIENT_ID);
|
||||
ClientRepresentation client = clientResource.toRepresentation();
|
||||
try {
|
||||
client.setConsentRequired(true);
|
||||
clientResource.update(client);
|
||||
|
||||
|
@ -209,11 +214,12 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
testExecutor.configure() // need to configure because we refreshed page
|
||||
.init(defaultArguments(), this::assertInitNotAuth)
|
||||
.login((driver1, output, events) -> assertTrue(oAuthGrantPage.isCurrent(driver1)));
|
||||
|
||||
} finally {
|
||||
// Clean
|
||||
client.setConsentRequired(false);
|
||||
clientResource.update(client);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void implicitFlowTest() {
|
||||
|
@ -268,6 +274,7 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
public void implicitFlowOnTokenExpireTest() {
|
||||
RealmRepresentation realm = adminClient.realms().realm(REALM_NAME).toRepresentation();
|
||||
Integer storeAccesTokenLifespan = realm.getAccessTokenLifespanForImplicitFlow();
|
||||
try {
|
||||
realm.setAccessTokenLifespanForImplicitFlow(5);
|
||||
adminClient.realms().realm(REALM_NAME).update(realm);
|
||||
|
||||
|
@ -276,11 +283,12 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
.addTimeSkew(-5); // Move in time instead of wait
|
||||
|
||||
waitUntilElement(eventsArea).text().contains("Access token expired");
|
||||
|
||||
} finally {
|
||||
// Get to origin state
|
||||
realm.setAccessTokenLifespanForImplicitFlow(storeAccesTokenLifespan);
|
||||
adminClient.realms().realm(REALM_NAME).update(realm);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void implicitFlowCertEndpoint() {
|
||||
|
@ -350,8 +358,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
.sendXMLHttpRequest(request, assertResponseStatus(401))
|
||||
.refreshToken(5, assertEventsContains("Auth Refresh Success"))
|
||||
.sendXMLHttpRequest(request, assertResponseStatus(200));
|
||||
|
||||
setTimeOffset(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -418,6 +424,7 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
// it looks like phantomjs double encode %20 => %25%20
|
||||
Assume.assumeTrue("This test doesn't work with phantomjs", !"phantomjs".equals(System.getProperty("js.browser")));
|
||||
|
||||
try {
|
||||
adminClient.realm(REALM_NAME).update(RealmBuilder.edit(adminClient.realm(REALM_NAME).toRepresentation()).name(SPACE_REALM_NAME).build());
|
||||
|
||||
JSObjectBuilder configuration = JSObjectBuilder.create()
|
||||
|
@ -435,11 +442,11 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
.loginForm(testUser, this::assertOnTestAppUrl)
|
||||
.configure(configuration)
|
||||
.init(defaultArguments(), this::assertSuccessfullyLoggedIn);
|
||||
|
||||
// Clean
|
||||
} finally {
|
||||
adminClient.realm(SPACE_REALM_NAME).update(RealmBuilder.edit(adminClient.realm(SPACE_REALM_NAME).toRepresentation()).name(REALM_NAME).build());
|
||||
jsDriverTestRealmLoginPage.setAuthRealm(REALM_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializeWithTokenTest() {
|
||||
|
@ -460,9 +467,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
.add("refreshToken", refreshToken)
|
||||
, this::assertSuccessfullyLoggedIn)
|
||||
.refreshToken(9999, assertEventsContains("Auth Refresh Success"));
|
||||
|
||||
|
||||
oauth.setDriver(driver);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -496,15 +500,12 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
both(greaterThan(-600L - TIME_SKEW_TOLERANCE))
|
||||
.and(lessThan(-600L + TIME_SKEW_TOLERANCE))
|
||||
)));
|
||||
|
||||
setTimeOffset(0);
|
||||
|
||||
oauth.setDriver(driver); // Clean
|
||||
}
|
||||
|
||||
@Test
|
||||
// KEYCLOAK-4503
|
||||
public void initializeWithRefreshToken() {
|
||||
|
||||
oauth.setDriver(jsDriver); // Oauth need to login with jsDriver
|
||||
|
||||
oauth.realm(REALM_NAME);
|
||||
|
@ -523,8 +524,6 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
assertInitNotAuth(driver1, output, events);
|
||||
waitUntilElement(events).text().not().contains("Auth Success");
|
||||
});
|
||||
|
||||
oauth.setDriver(driver); // Clean
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -31,7 +31,9 @@ import org.jboss.arquillian.graphene.page.Page;
|
|||
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.After;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
|
||||
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
|
||||
|
@ -74,6 +76,11 @@ public class SecuredDeploymentsAdapterTest extends AbstractServletsAdapterTest i
|
|||
return servletDeployment(CustomerDb.DEPLOYMENT_NAME, AdapterActionsFilter.class, CustomerDatabaseServlet.class);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void assumeTLSEnabled() {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
}
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void startServer() {
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
|||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.RealmBuilder;
|
||||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
|
@ -61,7 +62,7 @@ public class CrossRealmPermissionsTest extends AbstractKeycloakTest {
|
|||
.addPassword("password"));
|
||||
testRealms.add(builder.build());
|
||||
|
||||
realm1 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret").realm(REALM_NAME);
|
||||
realm1 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret", TLSUtils.initializeTLS()).realm(REALM_NAME);
|
||||
|
||||
builder = RealmBuilder.create().name(REALM2_NAME).testMail();
|
||||
builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants());
|
||||
|
@ -73,7 +74,7 @@ public class CrossRealmPermissionsTest extends AbstractKeycloakTest {
|
|||
|
||||
testRealms.add(builder.build());
|
||||
|
||||
realm2 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM2_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret").realm(REALM2_NAME);
|
||||
realm2 = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM2_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret", TLSUtils.initializeTLS()).realm(REALM2_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.keycloak.services.resources.admin.permissions.GroupPermissionManageme
|
|||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.ProfileAssume;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
import org.keycloak.testsuite.util.AdminClientUtil;
|
||||
|
@ -893,7 +894,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
Assert.assertNotNull(exchanged);
|
||||
|
||||
Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, exchanged);
|
||||
AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, exchanged, TLSUtils.initializeTLS());
|
||||
|
||||
Assert.assertNotNull(client.realm("master").roles().get("offline_access"));
|
||||
}
|
||||
|
@ -949,7 +950,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
});
|
||||
|
||||
Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
"test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID);
|
||||
"test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS());
|
||||
|
||||
List<UserRepresentation> result = client.realm("test").users().search(null, "test", null, null, -1, 20);
|
||||
|
||||
|
@ -961,7 +962,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
Assert.assertEquals(0, result.size());
|
||||
|
||||
client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
"test", "regular-admin-user", "password", Constants.ADMIN_CLI_CLIENT_ID);
|
||||
"test", "regular-admin-user", "password", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS());
|
||||
|
||||
result = client.realm("test").users().search(null, "test", null, null, -1, 20);
|
||||
|
||||
|
@ -974,7 +975,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
|
|||
Assert.assertThat(result, Matchers.everyItem(Matchers.hasProperty("username", Matchers.startsWith("a"))));
|
||||
|
||||
client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
"test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID);
|
||||
"test", "customer-a-manager", "password", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS());
|
||||
|
||||
result = client.realm("test").users().search(null, null, null, null, -1, 20);
|
||||
|
||||
|
|
|
@ -638,7 +638,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
|
|||
Assert.assertEquals("Parsed export type", EntityDescriptorType.class, entBody.getClass());
|
||||
EntityDescriptorType entity = (EntityDescriptorType) entBody;
|
||||
|
||||
Assert.assertEquals("EntityID", "http://localhost:8180/auth/realms/admin-client-test", entity.getEntityID());
|
||||
Assert.assertEquals("EntityID", oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test", entity.getEntityID());
|
||||
|
||||
Assert.assertNotNull("ChoiceType not null", entity.getChoiceType());
|
||||
Assert.assertEquals("ChoiceType.size", 1, entity.getChoiceType().size());
|
||||
|
@ -667,7 +667,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
|
|||
IndexedEndpointType endpoint = desc.getAssertionConsumerService().get(0);
|
||||
|
||||
Assert.assertEquals("AssertionConsumerService.Location",
|
||||
new URI("http://localhost:8180/auth/realms/admin-client-test/broker/saml/endpoint"), endpoint.getLocation());
|
||||
new URI(oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test/broker/saml/endpoint"), endpoint.getLocation());
|
||||
Assert.assertEquals("AssertionConsumerService.Binding",
|
||||
new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), endpoint.getBinding());
|
||||
Assert.assertTrue("AssertionConsumerService.isDefault", endpoint.isIsDefault());
|
||||
|
@ -679,7 +679,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
|
|||
EndpointType sloEndpoint = desc.getSingleLogoutService().get(0);
|
||||
|
||||
Assert.assertEquals("SingleLogoutService.Location",
|
||||
new URI("http://localhost:8180/auth/realms/admin-client-test/broker/saml/endpoint"), sloEndpoint.getLocation());
|
||||
new URI(oauth.AUTH_SERVER_ROOT + "/realms/admin-client-test/broker/saml/endpoint"), sloEndpoint.getLocation());
|
||||
Assert.assertEquals("SingleLogoutService.Binding",
|
||||
new URI("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), sloEndpoint.getBinding());
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ import org.keycloak.services.resources.admin.AdminAuth.Resource;
|
|||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.util.AdminClientUtil;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.CredentialBuilder;
|
||||
|
@ -194,31 +195,31 @@ public class PermissionsTest extends AbstractKeycloakTest {
|
|||
|
||||
clients.put(AdminRoles.REALM_ADMIN,
|
||||
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client",
|
||||
"secret"));
|
||||
"secret", TLSUtils.initializeTLS()));
|
||||
|
||||
clients.put("none",
|
||||
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "none", "password", "test-client", "secret"));
|
||||
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "none", "password", "test-client", "secret", TLSUtils.initializeTLS()));
|
||||
|
||||
clients.put("multi",
|
||||
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "multi", "password", "test-client", "secret"));
|
||||
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "multi", "password", "test-client", "secret", TLSUtils.initializeTLS()));
|
||||
|
||||
for (String role : AdminRoles.ALL_REALM_ROLES) {
|
||||
clients.put(role, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, role, "password", "test-client"));
|
||||
clients.put(role, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, role, "password", "test-client", TLSUtils.initializeTLS()));
|
||||
}
|
||||
|
||||
clients.put("REALM2", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "realm2", "admin", "password", "test-client"));
|
||||
clients.put("REALM2", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "realm2", "admin", "password", "test-client", TLSUtils.initializeTLS()));
|
||||
|
||||
clients.put("master-admin", adminClient);
|
||||
|
||||
clients.put("master-none",
|
||||
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-none", "password",
|
||||
Constants.ADMIN_CLI_CLIENT_ID));
|
||||
Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()));
|
||||
|
||||
|
||||
for (String role : AdminRoles.ALL_REALM_ROLES) {
|
||||
clients.put("master-" + role,
|
||||
Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-" + role, "password",
|
||||
Constants.ADMIN_CLI_CLIENT_ID));
|
||||
Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,6 @@ import java.util.List;
|
|||
*/
|
||||
public class UserTotpTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth");
|
||||
public static String ACCOUNT_REDIRECT = AccountFormService.loginRedirectUrl(BASE.clone()).build("test").toString();
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(this);
|
||||
|
||||
|
@ -71,7 +68,7 @@ public class UserTotpTest extends AbstractTestRealmKeycloakTest {
|
|||
totpPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=totp").assertEvent();
|
||||
|
||||
Assert.assertTrue(totpPage.isCurrent());
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
@ -102,7 +103,7 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest {
|
|||
.directAccessGrants())
|
||||
.client(ClientBuilder.create().clientId("public-client-test")
|
||||
.publicClient()
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*")
|
||||
.directAccessGrants())
|
||||
.build());
|
||||
}
|
||||
|
@ -347,7 +348,11 @@ public class PolicyEnforcerClaimsTest extends AbstractKeycloakTest {
|
|||
}
|
||||
|
||||
private InputStream getAdapterConfiguration(String fileName) {
|
||||
return getClass().getResourceAsStream("/authorization-test/" + fileName);
|
||||
try {
|
||||
return httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + fileName));
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("Could not load keycloak configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.ws.rs.HttpMethod;
|
|||
import javax.ws.rs.core.HttpHeaders;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
@ -73,7 +74,6 @@ import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
|
|||
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.ProfileAssume;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.RealmBuilder;
|
||||
|
@ -116,7 +116,7 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest {
|
|||
.directAccessGrants())
|
||||
.client(ClientBuilder.create().clientId("public-client-test")
|
||||
.publicClient()
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*")
|
||||
.directAccessGrants())
|
||||
.build());
|
||||
}
|
||||
|
@ -486,7 +486,11 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest {
|
|||
}
|
||||
|
||||
private InputStream getAdapterConfiguration(String fileName) {
|
||||
return getClass().getResourceAsStream("/authorization-test/" + fileName);
|
||||
try {
|
||||
return httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + fileName));
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("Unexpected I/O error while dealing with configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ResourceRepresentation createResource(ClientResource clientResource, String name, String uri, String... scopes) {
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.keycloak.admin.client.resource.RealmResource;
|
|||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -68,7 +70,7 @@ public abstract class AbstractConcurrencyTest extends AbstractTestRealmKeycloakT
|
|||
ThreadLocal<Keycloak> keycloaks = new ThreadLocal<Keycloak>() {
|
||||
@Override
|
||||
protected Keycloak initialValue() {
|
||||
return Keycloak.getInstance(testImpl.getAuthServerRoot().toString(), "master", "admin", "admin", org.keycloak.models.Constants.ADMIN_CLI_CLIENT_ID);
|
||||
return Keycloak.getInstance(testImpl.getAuthServerRoot().toString(), "master", "admin", "admin", org.keycloak.models.Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ import java.net.URISyntaxException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.ws.rs.core.Response;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
|
@ -33,11 +36,13 @@ import org.apache.http.client.methods.HttpPost;
|
|||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.LaxRedirectStrategy;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.junit.Assert;
|
||||
|
@ -89,8 +94,8 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
ClientRepresentation client = ClientBuilder.create()
|
||||
.clientId("client" + i)
|
||||
.directAccessGrants()
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*")
|
||||
.addWebOrigin("http://localhost:8180")
|
||||
.redirectUris("*")
|
||||
.addWebOrigin("*")
|
||||
.secret("password")
|
||||
.build();
|
||||
|
||||
|
@ -111,7 +116,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
AtomicReference<String> userSessionId = new AtomicReference<>();
|
||||
LoginTask loginTask = null;
|
||||
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) {
|
||||
try (CloseableHttpClient httpClient = getHttpsAwareClient()) {
|
||||
loginTask = new LoginTask(httpClient, userSessionId, 100, 1, false, Arrays.asList(
|
||||
createHttpClientContextForUser(httpClient, "test-user@localhost", "password")
|
||||
));
|
||||
|
@ -126,6 +131,15 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
}
|
||||
}
|
||||
|
||||
protected CloseableHttpClient getHttpsAwareClient() {
|
||||
HttpClientBuilder builder = HttpClientBuilder.create()
|
||||
.setRedirectStrategy(new LaxRedirectStrategy());
|
||||
if (AUTH_SERVER_SSL_REQUIRED) {
|
||||
builder.setSSLHostnameVerifier((s, sslSession) -> true);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected HttpClientContext createHttpClientContextForUser(final CloseableHttpClient httpClient, String userName, String password) throws IOException {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
CookieStore cookieStore = new BasicCookieStore();
|
||||
|
@ -143,7 +157,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
AtomicReference<String> userSessionId = new AtomicReference<>();
|
||||
LoginTask loginTask = null;
|
||||
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) {
|
||||
try (CloseableHttpClient httpClient = getHttpsAwareClient()) {
|
||||
loginTask = new LoginTask(httpClient, userSessionId, 100, 1, true, Arrays.asList(
|
||||
createHttpClientContextForUser(httpClient, "test-user@localhost", "password")
|
||||
));
|
||||
|
@ -166,7 +180,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
AtomicReference<String> userSessionId = new AtomicReference<>();
|
||||
LoginTask loginTask = null;
|
||||
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) {
|
||||
try (CloseableHttpClient httpClient = getHttpsAwareClient()) {
|
||||
loginTask = new LoginTask(httpClient, userSessionId, 100, 1, false, Arrays.asList(
|
||||
createHttpClientContextForUser(httpClient, "test-user@localhost", "password"),
|
||||
createHttpClientContextForUser(httpClient, "john-doh@localhost", "password"),
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.keycloak.testsuite.AbstractAuthTest;
|
|||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
|
@ -128,7 +129,7 @@ public class AdminEventAuthDetailsTest extends AbstractAuthTest {
|
|||
|
||||
private void testClient(String realmName, String username, String password, String clientId, String expectedRealmId, String expectedClientUuid, String expectedUserId) {
|
||||
try (Keycloak keycloak = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
realmName, username, password, clientId)) {
|
||||
realmName, username, password, clientId, TLSUtils.initializeTLS())) {
|
||||
UserRepresentation rep = UserBuilder.create().id(appUserId).username("app-user").email("foo@email.org").build();
|
||||
keycloak.realm("test").users().get(appUserId).update(rep);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
|||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.RoleBuilder;
|
||||
|
@ -540,7 +541,7 @@ public class GroupTest extends AbstractGroupTest {
|
|||
createUser(realmName, userName, "pwd");
|
||||
|
||||
try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID)) {
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) {
|
||||
|
||||
expectedException.expect(ClientErrorException.class);
|
||||
expectedException.expectMessage(String.valueOf(Response.Status.FORBIDDEN.getStatusCode()));
|
||||
|
@ -569,7 +570,7 @@ public class GroupTest extends AbstractGroupTest {
|
|||
mappings.realmLevel().add(Collections.singletonList(adminRole));
|
||||
|
||||
Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID);
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS());
|
||||
|
||||
assertThat(userClient.realms().findAll(), // Any admin operation will do
|
||||
not(empty()));
|
||||
|
@ -601,7 +602,7 @@ public class GroupTest extends AbstractGroupTest {
|
|||
realm.users().get(userId).joinGroup(groupId);
|
||||
}
|
||||
try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID)) {
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) {
|
||||
|
||||
assertThat(userClient.realms().findAll(), // Any admin operation will do
|
||||
not(empty()));
|
||||
|
@ -636,7 +637,7 @@ public class GroupTest extends AbstractGroupTest {
|
|||
mappings.realmLevel().add(Collections.singletonList(adminRole));
|
||||
}
|
||||
try (Keycloak userClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID)) {
|
||||
realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) {
|
||||
|
||||
assertThat(userClient.realms().findAll(), // Any admin operation will do
|
||||
not(empty()));
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.keycloak.testsuite.AssertEvents;
|
|||
import org.keycloak.testsuite.admin.AbstractAdminTest;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
@ -271,7 +272,7 @@ public class RealmTest extends AbstractAdminTest {
|
|||
public void loginAfterRemoveRealm() {
|
||||
realm.remove();
|
||||
|
||||
try (Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID)) {
|
||||
try (Keycloak client = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) {
|
||||
client.serverInfo().getInfo();
|
||||
}
|
||||
|
||||
|
@ -662,7 +663,7 @@ public class RealmTest extends AbstractAdminTest {
|
|||
GlobalRequestResult globalRequestResult = realm.pushRevocation();
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM);
|
||||
|
||||
assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/app/admin"));
|
||||
assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder(oauth.AUTH_SERVER_ROOT + "/realms/master/app/admin"));
|
||||
assertNull(globalRequestResult.getFailedRequests());
|
||||
|
||||
PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore();
|
||||
|
@ -684,8 +685,8 @@ public class RealmTest extends AbstractAdminTest {
|
|||
GlobalRequestResult globalRequestResult = realm.pushRevocation();
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM);
|
||||
|
||||
assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/app/admin"));
|
||||
assertThat(globalRequestResult.getFailedRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/saml-app/saml"));
|
||||
assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder(oauth.AUTH_SERVER_ROOT + "/realms/master/app/admin"));
|
||||
assertThat(globalRequestResult.getFailedRequests(), Matchers.containsInAnyOrder(oauth.AUTH_SERVER_ROOT + "/realms/master/saml-app/saml"));
|
||||
|
||||
PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore();
|
||||
assertEquals(time, adminPushNotBefore.getNotBefore());
|
||||
|
@ -709,7 +710,7 @@ public class RealmTest extends AbstractAdminTest {
|
|||
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "logout-all", globalRequestResult, ResourceType.REALM);
|
||||
|
||||
assertEquals(1, globalRequestResult.getSuccessRequests().size());
|
||||
assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0));
|
||||
assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0));
|
||||
assertNull(globalRequestResult.getFailedRequests());
|
||||
|
||||
assertNotNull(testingClient.testApp().getAdminLogoutAction());
|
||||
|
|
|
@ -75,7 +75,7 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
|
|||
.directAccessGrants()
|
||||
.serviceAccountsEnabled(true))
|
||||
.client(ClientBuilder.create().clientId("test-app")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth", "https://localhost:8543/auth/realms/master/app/auth")
|
||||
.publicClient())
|
||||
.build());
|
||||
}
|
||||
|
@ -165,7 +165,11 @@ public abstract class AbstractResourceServerTest extends AbstractAuthzTest {
|
|||
}
|
||||
|
||||
protected AuthzClient getAuthzClient() {
|
||||
return AuthzClient.create(getClass().getResourceAsStream("/authorization-test/default-keycloak-uma2.json"));
|
||||
try {
|
||||
return AuthzClient.create(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/default-keycloak-uma2.json")));
|
||||
} catch (IOException cause) {
|
||||
throw new RuntimeException("Failed to create authz client", cause);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertPermissions(Collection<Permission> permissions, String expectedResource, String... expectedScopes) {
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.testsuite.authz;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -208,6 +209,10 @@ public class AuthorizationAPITest extends AbstractAuthzTest {
|
|||
}
|
||||
|
||||
private AuthzClient getAuthzClient(String configFile) {
|
||||
return AuthzClient.create(getClass().getResourceAsStream("/authorization-test/" + configFile));
|
||||
try {
|
||||
return AuthzClient.create(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + configFile)));
|
||||
} catch (IOException cause) {
|
||||
throw new RuntimeException("Failed to create authz client", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
|
|||
.directAccessGrants())
|
||||
.client(ClientBuilder.create().clientId(PUBLIC_TEST_CLIENT)
|
||||
.secret("secret")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/auth/*", "https://localhost:8543/auth/realms/master/app/auth/*")
|
||||
.publicClient())
|
||||
.build());
|
||||
}
|
||||
|
@ -1374,7 +1374,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
|
|||
if (authzClient == null) {
|
||||
Configuration configuration;
|
||||
try {
|
||||
configuration = JsonSerialization.readValue(getClass().getResourceAsStream("/authorization-test/" + configFile), Configuration.class);
|
||||
configuration = JsonSerialization.readValue(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/" + configFile)), Configuration.class);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to read configuration", e);
|
||||
}
|
||||
|
|
|
@ -451,6 +451,10 @@ public class PermissionClaimTest extends AbstractAuthzTest {
|
|||
}
|
||||
|
||||
private AuthzClient getAuthzClient() {
|
||||
return AuthzClient.create(getClass().getResourceAsStream("/authorization-test/default-keycloak.json"));
|
||||
try {
|
||||
return AuthzClient.create(httpsAwareConfigurationStream(getClass().getResourceAsStream("/authorization-test/default-keycloak.json")));
|
||||
} catch (IOException cause) {
|
||||
throw new RuntimeException("Failed to create authz client", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,8 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
|
|||
.fullScopeEnabled(true)
|
||||
.protocol(SamlProtocol.LOGIN_PROTOCOL)
|
||||
.baseUrl("http://localhost:8080/sales-post")
|
||||
.addRedirectUri("http://localhost:8080/sales-post/*")
|
||||
.addRedirectUri("http://localhost:8180/sales-post/*")
|
||||
.addRedirectUri("https://localhost:8543/sales-post/*")
|
||||
.attribute(SamlConfigAttributes.SAML_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE)
|
||||
.attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE)
|
||||
.build(),
|
||||
|
@ -163,7 +164,8 @@ public class KcSamlBrokerConfiguration implements BrokerConfiguration {
|
|||
.fullScopeEnabled(true)
|
||||
.protocol(SamlProtocol.LOGIN_PROTOCOL)
|
||||
.baseUrl("http://localhost:8080/sales-post")
|
||||
.addRedirectUri("http://localhost:8080/sales-post/*")
|
||||
.addRedirectUri("http://localhost:8180/sales-post/*")
|
||||
.addRedirectUri("https://localhost:8543/sales-post/*")
|
||||
.attribute(SamlConfigAttributes.SAML_AUTHNSTATEMENT, SamlProtocol.ATTRIBUTE_TRUE_VALUE)
|
||||
.attribute(SamlConfigAttributes.SAML_CLIENT_SIGNATURE_ATTRIBUTE, SamlProtocol.ATTRIBUTE_FALSE_VALUE)
|
||||
.build(),
|
||||
|
|
|
@ -138,7 +138,7 @@ public class KcSamlBrokerTest extends AbstractBrokerTest {
|
|||
// KEYCLOAK-6106
|
||||
@Test
|
||||
public void loginClientWithDotsInName() throws Exception {
|
||||
AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST + ".dot/ted", AbstractSamlTest.SAML_ASSERTION_CONSUMER_URL_SALES_POST, null);
|
||||
AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST + ".dot/ted", AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT + "/sales-post/saml", null);
|
||||
|
||||
Document doc = SAML2Request.convert(loginRep);
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.keycloak.testsuite.broker;
|
||||
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.broker.saml.SAMLIdentityProviderConfig;
|
||||
import org.keycloak.crypto.Algorithm;
|
||||
import org.keycloak.dom.saml.v2.protocol.AuthnRequestType;
|
||||
|
@ -210,7 +209,7 @@ public class KcSamlSignedBrokerTest extends KcSamlBrokerTest {
|
|||
// KEYCLOAK-5581
|
||||
@Test
|
||||
public void loginUserAllNamespacesInTopElement() {
|
||||
AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST, AbstractSamlTest.SAML_ASSERTION_CONSUMER_URL_SALES_POST, null);
|
||||
AuthnRequestType loginRep = SamlClient.createLoginRequestDocument(AbstractSamlTest.SAML_CLIENT_ID_SALES_POST, AUTH_SERVER_SCHEME + "://localhost:" + AUTH_SERVER_PORT + "/sales-post/saml", null);
|
||||
|
||||
Document doc;
|
||||
try {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package org.keycloak.testsuite.cli;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.cli.exec.AbstractExec;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -11,6 +13,23 @@ import java.util.List;
|
|||
*/
|
||||
public abstract class AbstractCliTest extends AbstractKeycloakTest {
|
||||
|
||||
protected String serverUrl = "http://localhost:" + getAuthServerHttpPort() + "/auth";
|
||||
|
||||
static int getAuthServerHttpPort() {
|
||||
try {
|
||||
return Integer.valueOf(System.getProperty("auth.server.http.port"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("System property 'auth.server.http.port' not set or invalid: '"
|
||||
+ System.getProperty("auth.server.http.port") + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
for (RealmRepresentation tr : testRealms) {
|
||||
tr.setSslRequired("external");
|
||||
}
|
||||
}
|
||||
|
||||
public void assertExitCodeAndStdOutSize(AbstractExec exe, int exitCode, int stdOutLineCount) {
|
||||
assertExitCodeAndStreamSizes(exe, exitCode, stdOutLineCount, -1);
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
|
||||
package org.keycloak.testsuite.cli;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
|
@ -26,17 +33,22 @@ import org.junit.Rule;
|
|||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.authentication.RequiredActionProvider;
|
||||
import org.keycloak.authentication.authenticators.console.ConsoleUsernamePasswordAuthenticatorFactory;
|
||||
import org.keycloak.authentication.requiredactions.TermsAndConditions;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowBindings;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.PasswordPolicy;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.TimeBasedOTP;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
||||
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
|
||||
|
@ -46,28 +58,14 @@ import org.keycloak.services.resources.admin.permissions.AdminPermissions;
|
|||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.actions.DummyRequiredActionFactory;
|
||||
import org.keycloak.testsuite.authentication.PushButtonAuthenticator;
|
||||
import org.keycloak.testsuite.authentication.PushButtonAuthenticatorFactory;
|
||||
import org.keycloak.testsuite.forms.PassThroughAuthenticator;
|
||||
import org.keycloak.testsuite.pages.AppPage;
|
||||
import org.keycloak.testsuite.pages.ErrorPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
import org.keycloak.testsuite.util.GreenMailRule;
|
||||
import org.keycloak.testsuite.util.MailUtils;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
import org.keycloak.utils.TotpUtils;
|
||||
import org.openqa.selenium.By;
|
||||
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Test that clients can override auth flows
|
||||
*
|
||||
|
@ -111,7 +109,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
ClientModel kcinit = realm.addClient(KCINIT_CLIENT);
|
||||
kcinit.setEnabled(true);
|
||||
kcinit.addRedirectUri("http://localhost:*");
|
||||
kcinit.addRedirectUri("*");
|
||||
kcinit.setPublicClient(true);
|
||||
kcinit.removeRole(realm.getRole(OAuth2Constants.OFFLINE_ACCESS));
|
||||
|
||||
|
@ -239,7 +237,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
|||
.executeAsync();
|
||||
exe.waitForStderr("Open browser and continue login? [y/n]");
|
||||
exe.sendLine("y");
|
||||
exe.waitForStdout("http://");
|
||||
exe.waitForStdout("http");
|
||||
|
||||
// the --fake-browser skips launching a browser and outputs url to stdout
|
||||
String redirect = exe.stdoutString().trim();
|
||||
|
@ -312,7 +310,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
exe.waitForStderr("Open browser and continue login? [y/n]");
|
||||
exe.sendLine("y");
|
||||
exe.waitForStdout("http://");
|
||||
exe.waitForStdout("http");
|
||||
|
||||
// the --fake-browser skips launching a browser and outputs url to stdout
|
||||
String redirect = exe.stdoutString().trim();
|
||||
|
@ -348,7 +346,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
|
|||
//exe.waitForStderr("(y/n):");
|
||||
//exe.sendLine("n");
|
||||
exe.waitForStderr("Authentication server URL [http://localhost:8080/auth]:");
|
||||
exe.sendLine(OAuthClient.AUTH_SERVER_ROOT);
|
||||
exe.sendLine(oauth.AUTH_SERVER_ROOT);
|
||||
//System.out.println(exe.stderrString());
|
||||
exe.waitForStderr("Name of realm [master]:");
|
||||
exe.sendLine("test");
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
|||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.cli.AbstractCliTest;
|
||||
import org.keycloak.testsuite.cli.KcAdmExec;
|
||||
import org.keycloak.testsuite.cli.KcRegExec;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
@ -37,40 +38,14 @@ import static org.keycloak.testsuite.cli.KcAdmExec.execute;
|
|||
*/
|
||||
public abstract class AbstractAdmCliTest extends AbstractCliTest {
|
||||
|
||||
protected String serverUrl = isAuthServerSSL() ?
|
||||
"https://localhost:" + getAuthServerHttpsPort() + "/auth" :
|
||||
"http://localhost:" + getAuthServerHttpPort() + "/auth";
|
||||
|
||||
static boolean runIntermittentlyFailingTests() {
|
||||
return "true".equals(System.getProperty("test.intermittent"));
|
||||
}
|
||||
|
||||
static boolean isAuthServerSSL() {
|
||||
return "true".equals(System.getProperty("auth.server.ssl.required"));
|
||||
}
|
||||
|
||||
static File getDefaultConfigFilePath() {
|
||||
return new File(System.getProperty("user.home") + "/.keycloak/kcadm.config");
|
||||
}
|
||||
|
||||
static int getAuthServerHttpsPort() {
|
||||
try {
|
||||
return Integer.valueOf(System.getProperty("auth.server.https.port"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("System property 'auth.server.https.port' not set or invalid: '"
|
||||
+ System.getProperty("auth.server.https.port") + "'");
|
||||
}
|
||||
}
|
||||
|
||||
static int getAuthServerHttpPort() {
|
||||
try {
|
||||
return Integer.valueOf(System.getProperty("auth.server.http.port"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("System property 'auth.server.http.port' not set or invalid: '"
|
||||
+ System.getProperty("auth.server.http.port") + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
|
||||
|
@ -320,7 +295,7 @@ public abstract class AbstractAdmCliTest extends AbstractCliTest {
|
|||
|
||||
exe = execute("delete clients/" + client.getId() + " --no-config --server " + serverUrl + " --realm test " + credentials + " " + extraOptions);
|
||||
|
||||
int linecountOffset = loginMessage.equals("") ? 1 : 0; // if there is no login, then there is one less stdErrLinecount
|
||||
int linecountOffset = "".equals(loginMessage) ? 1 : 0; // if there is no login, then there is one less stdErrLinecount
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1 - linecountOffset);
|
||||
|
||||
lastModified2 = configFile.exists() ? configFile.lastModified() : 0;
|
||||
|
@ -376,13 +351,7 @@ public abstract class AbstractAdmCliTest extends AbstractCliTest {
|
|||
KcAdmExec exe = KcAdmExec.execute("config credentials --server " + server + " --realm " + realm +
|
||||
" --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath());
|
||||
|
||||
Assert.assertEquals("exitCode == 0", 0, exe.exitCode());
|
||||
|
||||
List<String> lines = exe.stdoutLines();
|
||||
Assert.assertTrue("stdout output empty", lines.size() == 0);
|
||||
|
||||
lines = exe.stderrLines();
|
||||
Assert.assertTrue("stderr output one line", lines.size() == 1);
|
||||
Assert.assertEquals("stderr first line", "Logging into " + server + " as user " + user + " of realm " + realm, lines.get(0));
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -577,6 +577,8 @@ public class KcAdmTest extends AbstractAdmCliTest {
|
|||
* Test create, get, update, and delete using on-the-fly authentication - without using any config file.
|
||||
* Login is performed by each operation again, and again using username, password, and client secret.
|
||||
*/
|
||||
//non-TLS endpoint
|
||||
oauth.baseUrl(serverUrl);
|
||||
oauth.realm("master");
|
||||
oauth.clientId("admin-cli");
|
||||
String token = oauth.doGrantAccessTokenRequest("", "admin", "admin").getAccessToken();
|
||||
|
|
|
@ -33,7 +33,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest {
|
|||
Assert.assertEquals("try help", "Try '" + OsUtil.CMD + " help config truststore' for more information", exe.stderrLines().get(1));
|
||||
|
||||
// only run this test if ssl protected keycloak server is available
|
||||
if (!isAuthServerSSL()) {
|
||||
if (!AUTH_SERVER_SSL_REQUIRED) {
|
||||
System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'");
|
||||
return;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest {
|
|||
|
||||
// perform authentication against server - asks for password, then for truststore password
|
||||
exe = KcAdmExec.newBuilder()
|
||||
.argsLine("config credentials --server " + serverUrl + " --realm test --user user1" +
|
||||
.argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" +
|
||||
" --config '" + configFile.getName() + "'")
|
||||
.executeAsync();
|
||||
|
||||
|
@ -71,7 +71,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest {
|
|||
|
||||
// perform authentication against server - asks for password, then for truststore password
|
||||
exe = KcAdmExec.newBuilder()
|
||||
.argsLine("config credentials --server " + serverUrl + " --realm test --user user1" +
|
||||
.argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" +
|
||||
" --config '" + configFile.getName() + "'")
|
||||
.executeAsync();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.keycloak.testsuite.cli.registration;
|
|||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.resource.ClientInitialAccessResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
|
||||
|
@ -47,11 +48,6 @@ import static org.keycloak.testsuite.cli.KcRegExec.execute;
|
|||
*/
|
||||
public abstract class AbstractRegCliTest extends AbstractCliTest {
|
||||
|
||||
protected String serverUrl = isAuthServerSSL() ?
|
||||
"https://localhost:" + getAuthServerHttpsPort() + "/auth" :
|
||||
"http://localhost:" + getAuthServerHttpPort() + "/auth";
|
||||
|
||||
|
||||
@Before
|
||||
public void deleteDefaultConfig() {
|
||||
getDefaultConfigFilePath().delete();
|
||||
|
@ -61,33 +57,10 @@ public abstract class AbstractRegCliTest extends AbstractCliTest {
|
|||
return "true".equals(System.getProperty("test.intermittent"));
|
||||
}
|
||||
|
||||
static boolean isAuthServerSSL() {
|
||||
return "true".equals(System.getProperty("auth.server.ssl.required"));
|
||||
}
|
||||
|
||||
static int getAuthServerHttpsPort() {
|
||||
try {
|
||||
return Integer.valueOf(System.getProperty("auth.server.https.port"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("System property 'auth.server.https.port' not set or invalid: '"
|
||||
+ System.getProperty("auth.server.https.port") + "'");
|
||||
}
|
||||
}
|
||||
|
||||
static int getAuthServerHttpPort() {
|
||||
try {
|
||||
return Integer.valueOf(System.getProperty("auth.server.http.port"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("System property 'auth.server.http.port' not set or invalid: '"
|
||||
+ System.getProperty("auth.server.http.port") + "'");
|
||||
}
|
||||
}
|
||||
|
||||
static File getDefaultConfigFilePath() {
|
||||
return new File(System.getProperty("user.home") + "/.keycloak/kcreg.config");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
RealmRepresentation realmRepresentation = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class);
|
||||
|
@ -159,23 +132,13 @@ public abstract class AbstractRegCliTest extends AbstractCliTest {
|
|||
.build();
|
||||
|
||||
realmRepresentation.getClients().add(regClient);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loginAsUser(File configFile, String server, String realm, String user, String password) {
|
||||
|
||||
KcRegExec exe = execute("config credentials --server " + server + " --realm " + realm +
|
||||
" --user " + user + " --password " + password + " --config " + configFile.getAbsolutePath());
|
||||
|
||||
Assert.assertEquals("exitCode == 0", 0, exe.exitCode());
|
||||
|
||||
List<String> lines = exe.stdoutLines();
|
||||
Assert.assertTrue("stdout output empty", lines.size() == 0);
|
||||
|
||||
lines = exe.stderrLines();
|
||||
Assert.assertTrue("stderr output one line", lines.size() == 1);
|
||||
Assert.assertEquals("stderr first line", "Logging into " + server + " as user " + user + " of realm " + realm, lines.get(0));
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1);
|
||||
}
|
||||
|
||||
void assertFieldsEqualWithExclusions(ConfigData config1, ConfigData config2, String ... excluded) {
|
||||
|
|
|
@ -2,6 +2,8 @@ package org.keycloak.testsuite.cli.registration;
|
|||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
|
@ -32,6 +34,11 @@ import static org.keycloak.testsuite.cli.KcRegExec.execute;
|
|||
*/
|
||||
public class KcRegCreateTest extends AbstractRegCliTest {
|
||||
|
||||
@Before
|
||||
public void assumeTLSEnabled() {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithRealmOverride() throws IOException {
|
||||
|
||||
|
@ -41,15 +48,15 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
|
||||
// authenticate as a regular user against one realm
|
||||
KcRegExec exe = execute("config credentials -x --config '" + configFile.getName() +
|
||||
"' --server " + serverUrl + " --realm master --user admin --password admin");
|
||||
"' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm master --user admin --password admin");
|
||||
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1);
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 3);
|
||||
|
||||
// use initial token of another realm with server, and realm override
|
||||
String token = issueInitialAccessToken("test");
|
||||
exe = execute("create --config '" + configFile.getName() + "' --server " + serverUrl + " --realm test -s clientId=my_first_client -t " + token);
|
||||
exe = execute("create --config '" + configFile.getName() + "' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm test -s clientId=my_first_client -t " + token);
|
||||
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1);
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,15 +73,15 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
final String realm = "test";
|
||||
|
||||
KcRegExec exe = execute("config initial-token -x --config '" + configFile.getName() +
|
||||
"' --server " + serverUrl + " --realm " + realm + " " + token);
|
||||
"' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm " + realm + " " + token);
|
||||
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 0);
|
||||
|
||||
// check that current server, realm, and initial token are saved in the file
|
||||
ConfigData config = handler.loadConfig();
|
||||
Assert.assertEquals("Config serverUrl", serverUrl, config.getServerUrl());
|
||||
Assert.assertEquals("Config serverUrl", oauth.AUTH_SERVER_ROOT, config.getServerUrl());
|
||||
Assert.assertEquals("Config realm", realm, config.getRealm());
|
||||
Assert.assertEquals("Config initial access token", token, config.ensureRealmConfigData(serverUrl, realm).getInitialToken());
|
||||
Assert.assertEquals("Config initial access token", token, config.ensureRealmConfigData(oauth.AUTH_SERVER_ROOT, realm).getInitialToken());
|
||||
|
||||
// create configuration from file using stdin redirect ... output an object
|
||||
String content = "{\n" +
|
||||
|
@ -96,9 +103,9 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
|
||||
try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) {
|
||||
|
||||
exe = execute("create --config '" + configFile.getName() + "' -o -f - < '" + tmpFile.getName() + "'");
|
||||
exe = execute("create --insecure --config '" + configFile.getName() + "' -o -f - < '" + tmpFile.getName() + "'");
|
||||
|
||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||
assertExitCodeAndStdErrSize(exe, 0, 2);
|
||||
|
||||
ClientRepresentation client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
|
||||
Assert.assertNotNull("id", client.getId());
|
||||
|
@ -119,12 +126,12 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
Assert.assertNull("mappers are null", client.getProtocolMappers());
|
||||
|
||||
// create configuration from file as a template and override clientId and other attributes ... output an object
|
||||
exe = execute("create --config '" + configFile.getName() + "' -o -f '" + tmpFile.getName() +
|
||||
exe = execute("create --insecure --config '" + configFile.getName() + "' -o -f '" + tmpFile.getName() +
|
||||
"' -s clientId=my_client2 -s enabled=false -s 'redirectUris=[\"http://localhost:8980/myapp2/*\"]'" +
|
||||
" -s 'name=My Client App II' -s protocol=openid-connect -s 'webOrigins=[\"http://localhost:8980/myapp2\"]'" +
|
||||
" -s baseUrl=http://localhost:8980/myapp2 -s rootUrl=http://localhost:8980/myapp2");
|
||||
|
||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||
assertExitCodeAndStdErrSize(exe, 0, 2);
|
||||
|
||||
ClientRepresentation client2 = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
|
||||
Assert.assertNotNull("id", client2.getId());
|
||||
|
@ -152,16 +159,16 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
}
|
||||
|
||||
// simple create, output an id
|
||||
exe = execute("create --config '" + configFile.getName() + "' -i -s clientId=my_client3");
|
||||
exe = execute("create --insecure --config '" + configFile.getName() + "' -i -s clientId=my_client3");
|
||||
|
||||
assertExitCodeAndStreamSizes(exe, 0, 1, 0);
|
||||
assertExitCodeAndStreamSizes(exe, 0, 1, 2);
|
||||
Assert.assertEquals("only clientId returned", "my_client3", exe.stdoutLines().get(0));
|
||||
|
||||
// simple create, default output
|
||||
exe = execute("create --config '" + configFile.getName() + "' -s clientId=my_client4");
|
||||
exe = execute("create --insecure --config '" + configFile.getName() + "' -s clientId=my_client4");
|
||||
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1);
|
||||
Assert.assertEquals("only clientId returned", "Registered new client with client_id 'my_client4'", exe.stderrLines().get(0));
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 3);
|
||||
Assert.assertEquals("only clientId returned", "Registered new client with client_id 'my_client4'", exe.stderrLines().get(2));
|
||||
|
||||
|
||||
|
||||
|
@ -176,11 +183,11 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
|
||||
try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) {
|
||||
|
||||
exe = execute("create --config '" + configFile.getName() + "' -s 'client_name=My Client App V' " +
|
||||
exe = execute("create --insecure --config '" + configFile.getName() + "' -s 'client_name=My Client App V' " +
|
||||
" -s 'redirect_uris=[\"http://localhost:8980/myapp5/*\"]' -s client_uri=http://localhost:8980/myapp5" +
|
||||
" -o -f - < '" + tmpFile.getName() + "'");
|
||||
|
||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||
assertExitCodeAndStdErrSize(exe, 0, 2);
|
||||
|
||||
OIDCClientRepresentation client = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class);
|
||||
|
||||
|
@ -205,9 +212,9 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
File samlSpMetaFile = new File(System.getProperty("user.dir") + "/src/test/resources/cli/kcreg/saml-sp-metadata.xml");
|
||||
Assert.assertTrue("saml-sp-metadata.xml exists", samlSpMetaFile.isFile());
|
||||
|
||||
exe = execute("create --config '" + configFile.getName() + "' -o -f - < '" + samlSpMetaFile.getAbsolutePath() + "'");
|
||||
exe = execute("create --insecure --config '" + configFile.getName() + "' -o -f - < '" + samlSpMetaFile.getAbsolutePath() + "'");
|
||||
|
||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||
assertExitCodeAndStdErrSize(exe, 0, 2);
|
||||
|
||||
ClientRepresentation client = JsonSerialization.readValue(exe.stdout(), ClientRepresentation.class);
|
||||
Assert.assertNotNull("id", client.getId());
|
||||
|
@ -219,7 +226,7 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
|
||||
|
||||
// delete initial token
|
||||
exe = execute("config initial-token --config '" + configFile.getName() + "' --server " + serverUrl + " --realm " + realm + " --delete");
|
||||
exe = execute("config initial-token --config '" + configFile.getName() + "' --insecure --server " + serverUrl + " --realm " + realm + " --delete");
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 0);
|
||||
|
||||
config = handler.loadConfig();
|
||||
|
@ -234,12 +241,12 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) {
|
||||
|
||||
KcRegExec exe = execute("config credentials -x --config '" + configFile.getName() +
|
||||
"' --server " + serverUrl + " --realm master --user admin --password admin");
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1);
|
||||
"' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm master --user admin --password admin");
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 3);
|
||||
|
||||
String token = issueInitialAccessToken("test");
|
||||
exe = execute("create --config '" + configFile.getName() + "' --server " + serverUrl + " --realm test -s clientId=authz-client -s authorizationServicesEnabled=true -t " + token);
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 1);
|
||||
exe = execute("create --config '" + configFile.getName() + "' --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm test -s clientId=authz-client -s authorizationServicesEnabled=true -t " + token);
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 3);
|
||||
|
||||
RealmResource realm = adminClient.realm("test");
|
||||
ClientsResource clients = realm.clients();
|
||||
|
@ -271,11 +278,11 @@ public class KcRegCreateTest extends AbstractRegCliTest {
|
|||
|
||||
try (TempFileResource tmpFile = new TempFileResource(initTempFile(".json", content))) {
|
||||
|
||||
exe = execute("create --config '" + configFile.getName() + "' -s 'client_name=My Reg Authz' --realm test -t " + token +
|
||||
exe = execute("create --insecure --config '" + configFile.getName() + "' -s 'client_name=My Reg Authz' --realm test -t " + token +
|
||||
" -s 'redirect_uris=[\"http://localhost:8980/myapp5/*\"]' -s client_uri=http://localhost:8980/myapp5" +
|
||||
" -o -f - < '" + tmpFile.getName() + "'");
|
||||
|
||||
assertExitCodeAndStdErrSize(exe, 0, 0);
|
||||
assertExitCodeAndStdErrSize(exe, 0, 2);
|
||||
|
||||
OIDCClientRepresentation oidcClient = JsonSerialization.readValue(exe.stdout(), OIDCClientRepresentation.class);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.keycloak.testsuite.cli.registration;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.client.registration.cli.config.ConfigData;
|
||||
import org.keycloak.client.registration.cli.config.FileConfigHandler;
|
||||
|
@ -571,24 +572,25 @@ public class KcRegTest extends AbstractRegCliTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDeleteWithInitialAndRegistrationTokens() throws IOException {
|
||||
public void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption() throws IOException {
|
||||
/*
|
||||
* Test create using initial client token, and subsequent delete using registration access token.
|
||||
* A config file is used to save registration access token for newly created client.
|
||||
*/
|
||||
testCreateDeleteWithInitialAndRegistrationTokens(true);
|
||||
testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDeleteWithInitialAndRegistrationTokensNoConfig() throws IOException {
|
||||
public void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOptionNoConfig() throws IOException {
|
||||
/*
|
||||
* Test create using initial client token, and subsequent delete using registration access token.
|
||||
* No config file is used so registration access token for newly created client is not saved to config.
|
||||
*/
|
||||
testCreateDeleteWithInitialAndRegistrationTokens(false);
|
||||
testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption(false);
|
||||
}
|
||||
|
||||
private void testCreateDeleteWithInitialAndRegistrationTokens(boolean useConfig) throws IOException {
|
||||
private void testCreateDeleteWithInitialAndRegistrationTokensWithUnsecureOption(boolean useConfig) throws IOException {
|
||||
Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED);
|
||||
|
||||
// prepare for loading a config file
|
||||
// only used when useConfig is true
|
||||
|
@ -601,7 +603,7 @@ public class KcRegTest extends AbstractRegCliTest {
|
|||
final String realm = "master";
|
||||
|
||||
KcRegExec exe = execute("create " + (useConfig ? ("--config '" + configFile.getAbsolutePath()) + "'" : "--no-config")
|
||||
+ " --server " + serverUrl + " --realm " + realm + " -s clientId=test-client2 -o -t " + token);
|
||||
+ " --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm " + realm + " -s clientId=test-client2 -o -t " + token);
|
||||
|
||||
Assert.assertEquals("exitCode == 0", 0, exe.exitCode());
|
||||
|
||||
|
@ -615,15 +617,15 @@ public class KcRegTest extends AbstractRegCliTest {
|
|||
if (useConfig) {
|
||||
ConfigData config = handler.loadConfig();
|
||||
Assert.assertEquals("Registration Access Token in config file", client.getRegistrationAccessToken(),
|
||||
config.ensureRealmConfigData(serverUrl, realm).getClients().get("test-client2"));
|
||||
config.ensureRealmConfigData(oauth.AUTH_SERVER_ROOT, realm).getClients().get("test-client2"));
|
||||
} else {
|
||||
Assert.assertFalse("There should be no config file", configFile.isFile());
|
||||
}
|
||||
|
||||
exe = execute("delete test-client2 " + (useConfig ? ("--config '" + configFile.getAbsolutePath()) + "'" : "--no-config")
|
||||
+ " --server " + serverUrl + " --realm " + realm + " -t " + client.getRegistrationAccessToken());
|
||||
+ " --insecure --server " + oauth.AUTH_SERVER_ROOT + " --realm " + realm + " -t " + client.getRegistrationAccessToken());
|
||||
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 0);
|
||||
assertExitCodeAndStreamSizes(exe, 0, 0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest {
|
|||
Assert.assertEquals("try help", "Try '" + OsUtil.CMD + " help config truststore' for more information", exe.stderrLines().get(1));
|
||||
|
||||
// only run the rest of this test if ssl protected keycloak server is available
|
||||
if (!isAuthServerSSL()) {
|
||||
if (!AUTH_SERVER_SSL_REQUIRED) {
|
||||
System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'");
|
||||
return;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest {
|
|||
|
||||
// perform authentication against server - asks for password, then for truststore password
|
||||
exe = KcRegExec.newBuilder()
|
||||
.argsLine("config credentials --server " + serverUrl + " --realm test --user user1" +
|
||||
.argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" +
|
||||
" --config '" + configFile.getName() + "'")
|
||||
.executeAsync();
|
||||
|
||||
|
@ -71,7 +71,7 @@ public class KcRegTruststoreTest extends AbstractRegCliTest {
|
|||
|
||||
// perform authentication against server - asks for password, then for truststore password
|
||||
exe = KcRegExec.newBuilder()
|
||||
.argsLine("config credentials --server " + serverUrl + " --realm test --user user1" +
|
||||
.argsLine("config credentials --server " + oauth.AUTH_SERVER_ROOT + " --realm test --user user1" +
|
||||
" --config '" + configFile.getName() + "'")
|
||||
.executeAsync();
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.keycloak.models.Constants;
|
|||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.util.ContainerAssume;
|
||||
|
||||
|
@ -118,7 +119,7 @@ public abstract class AbstractClusterTest extends AbstractKeycloakTest {
|
|||
protected Keycloak createAdminClientFor(ContainerInfo node) {
|
||||
log.info("Initializing admin client for " + node.getContextRoot() + "/auth");
|
||||
return Keycloak.getInstance(node.getContextRoot() + "/auth",
|
||||
MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
||||
MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS());
|
||||
}
|
||||
|
||||
protected KeycloakTestingClient createTestingClientFor(ContainerInfo node) {
|
||||
|
|
|
@ -94,7 +94,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
|
|||
.name("REALM_COMPOSITE_1_APPLICATION")
|
||||
.fullScopeEnabled(Boolean.FALSE)
|
||||
// addScopeMapping(realmComposite1)
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*")
|
||||
.baseUrl("http://localhost:8180/auth/realms/master/app/auth")
|
||||
.adminUrl("http://localhost:8180/auth/realms/master/app/logout")
|
||||
.secret("password");
|
||||
|
@ -105,7 +105,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
|
|||
.name("REALM_ROLE_1_APPLICATION")
|
||||
.fullScopeEnabled(Boolean.FALSE)
|
||||
// addScopeMapping(realmRole1)
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*")
|
||||
.baseUrl("http://localhost:8180/auth/realms/master/app/auth")
|
||||
.adminUrl("http://localhost:8180/auth/realms/master/app/logout")
|
||||
.secret("password");
|
||||
|
@ -115,7 +115,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
|
|||
.clientId("APP_ROLE_APPLICATION")
|
||||
.name("APP_ROLE_APPLICATION")
|
||||
.fullScopeEnabled(Boolean.FALSE)
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*")
|
||||
.baseUrl("http://localhost:8180/auth/realms/master/app/auth")
|
||||
.adminUrl("http://localhost:8180/auth/realms/master/app/logout")
|
||||
.defaultRoles("APP_ROLE_1", "APP_ROLE_2")
|
||||
|
@ -139,7 +139,7 @@ public class CompositeRoleTest extends AbstractCompositeKeycloakTest {
|
|||
.fullScopeEnabled(Boolean.FALSE)
|
||||
//.scopeMapping(appRole2)
|
||||
.defaultRoles("APP_COMPOSITE_ROLE")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*")
|
||||
.baseUrl("http://localhost:8180/auth/realms/master/app/auth")
|
||||
.adminUrl("http://localhost:8180/auth/realms/master/app/logout")
|
||||
.secret("password");
|
||||
|
|
|
@ -32,8 +32,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.LaxRedirectStrategy;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.testsuite.arquillian.annotation.InitialDcState;
|
||||
|
||||
|
@ -75,7 +73,7 @@ public class ConcurrentLoginCrossDCTest extends ConcurrentLoginTest {
|
|||
AtomicReference<String> userSessionId = new AtomicReference<>();
|
||||
LoginTask loginTask = null;
|
||||
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) {
|
||||
try (CloseableHttpClient httpClient = getHttpsAwareClient()) {
|
||||
loginTask = new LoginTask(httpClient, userSessionId, LOGIN_TASK_DELAY_MS, LOGIN_TASK_RETRIES, false, Arrays.asList(
|
||||
createHttpClientContextForUser(httpClient, "test-user@localhost", "password")
|
||||
));
|
||||
|
|
|
@ -92,8 +92,9 @@ public class SessionExpirationCrossDCTest extends AbstractAdminCrossDCTest {
|
|||
ClientRepresentation client = ClientBuilder.create()
|
||||
.clientId("test-app")
|
||||
.directAccessGrants()
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*", "https://localhost:8543/auth/realms/master/app/*")
|
||||
.addWebOrigin("http://localhost:8180")
|
||||
.addWebOrigin("https://localhost:8543")
|
||||
.secret("password")
|
||||
.build();
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ public class ChallengeFlowTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
@Before
|
||||
public void setupFlows() {
|
||||
SerializableApplicationData serializedApplicationData = new SerializableApplicationData(oauth.APP_AUTH_ROOT, oauth.APP_ROOT + "/admin", oauth.APP_AUTH_ROOT + "/*");
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
|
||||
|
@ -116,10 +118,10 @@ public class ChallengeFlowTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
client = realm.addClient(TEST_APP_FLOW);
|
||||
client.setSecret("password");
|
||||
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth");
|
||||
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin");
|
||||
client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
|
||||
client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
|
||||
client.setEnabled(true);
|
||||
client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*");
|
||||
client.addRedirectUri(serializedApplicationData.applicationRedirectUrl);
|
||||
client.addRedirectUri("urn:ietf:wg:oauth:2.0:oob");
|
||||
client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId());
|
||||
client.setPublicClient(false);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.keycloak.testsuite.forms;
|
||||
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
|
@ -58,7 +57,6 @@ import javax.ws.rs.core.Form;
|
|||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -99,9 +97,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
|
|||
.addPackages(true, "org.keycloak.testsuite");
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setupFlows() {
|
||||
SerializableApplicationData serializedApplicationData = new SerializableApplicationData(oauth.APP_AUTH_ROOT, oauth.APP_ROOT + "/admin", oauth.APP_AUTH_ROOT + "/*");
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
|
||||
|
@ -113,8 +112,6 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
|
|||
client = session.realms().getClientByClientId("test-app", realm);
|
||||
client.setDirectAccessGrantsEnabled(true);
|
||||
|
||||
|
||||
|
||||
// Parent flow
|
||||
AuthenticationFlowModel browser = new AuthenticationFlowModel();
|
||||
browser.setAlias("parent-flow");
|
||||
|
@ -163,10 +160,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
client = realm.addClient(TEST_APP_FLOW);
|
||||
client.setSecret("password");
|
||||
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth");
|
||||
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin");
|
||||
client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
|
||||
client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
|
||||
client.setEnabled(true);
|
||||
client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*");
|
||||
client.addRedirectUri(serializedApplicationData.applicationRedirectUrl);
|
||||
client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId());
|
||||
client.setPublicClient(false);
|
||||
|
||||
|
@ -206,10 +203,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
client = realm.addClient(TEST_APP_DIRECT_OVERRIDE);
|
||||
client.setSecret("password");
|
||||
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth");
|
||||
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin");
|
||||
client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
|
||||
client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
|
||||
client.setEnabled(true);
|
||||
client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*");
|
||||
client.addRedirectUri(serializedApplicationData.applicationRedirectUrl);
|
||||
client.setPublicClient(false);
|
||||
client.setDirectAccessGrantsEnabled(true);
|
||||
client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.BROWSER_BINDING, browser.getId());
|
||||
|
@ -218,10 +215,10 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
client = realm.addClient(TEST_APP_HTTP_CHALLENGE);
|
||||
client.setSecret("password");
|
||||
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth");
|
||||
client.setManagementUrl("http://localhost:8180/auth/realms/master/app/admin");
|
||||
client.setBaseUrl(serializedApplicationData.applicationBaseUrl);
|
||||
client.setManagementUrl(serializedApplicationData.applicationManagementUrl);
|
||||
client.setEnabled(true);
|
||||
client.addRedirectUri("http://localhost:8180/auth/realms/master/app/auth/*");
|
||||
client.addRedirectUri(serializedApplicationData.applicationRedirectUrl);
|
||||
client.setPublicClient(true);
|
||||
client.setDirectAccessGrantsEnabled(true);
|
||||
client.setAuthenticationFlowBindingOverride(AuthenticationFlowBindings.DIRECT_GRANT_BINDING, realm.getFlowByAlias("http challenge").getId());
|
||||
|
@ -522,7 +519,7 @@ public class FlowOverrideTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
form.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE);
|
||||
form.param(OAuth2Constants.CLIENT_ID, TEST_APP_HTTP_CHALLENGE);
|
||||
form.param(OAuth2Constants.REDIRECT_URI, "http://localhost:8180/auth/realms/master/app/auth");
|
||||
form.param(OAuth2Constants.REDIRECT_URI, oauth.APP_AUTH_ROOT);
|
||||
form.param(OAuth2Constants.CODE, location.substring(location.indexOf(OAuth2Constants.CODE) + OAuth2Constants.CODE.length() + 1));
|
||||
|
||||
// exchange code to token
|
||||
|
|
|
@ -73,7 +73,7 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
String sessionId = events.expectLogin().assertEvent().getSessionId();
|
||||
|
||||
String redirectUri = AppPage.baseUrl + "?logout";
|
||||
String redirectUri = oauth.APP_AUTH_ROOT + "?logout";
|
||||
|
||||
String logoutUrl = oauth.getLogoutUrl().redirectUri(redirectUri).build();
|
||||
driver.navigate().to(logoutUrl);
|
||||
|
@ -130,8 +130,8 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
|
|||
events.expectLogin().session(sessionId).removeDetail(Details.USERNAME).assertEvent();
|
||||
|
||||
// Logout session 1 by redirect
|
||||
driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build());
|
||||
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent();
|
||||
driver.navigate().to(oauth.getLogoutUrl().redirectUri(oauth.APP_AUTH_ROOT).build());
|
||||
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT).assertEvent();
|
||||
|
||||
// Check session 1 not logged-in
|
||||
oauth.openLoginForm();
|
||||
|
@ -147,8 +147,8 @@ public class LogoutTest extends AbstractTestRealmKeycloakTest {
|
|||
events.expectLogin().session(sessionId3).removeDetail(Details.USERNAME).assertEvent();
|
||||
|
||||
// Logout session 3 by redirect
|
||||
driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build());
|
||||
events.expectLogout(sessionId3).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent();
|
||||
driver.navigate().to(oauth.getLogoutUrl().redirectUri(oauth.APP_AUTH_ROOT).build());
|
||||
events.expectLogout(sessionId3).detail(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT).assertEvent();
|
||||
}
|
||||
|
||||
//KEYCLOAK-2741
|
||||
|
|
|
@ -60,6 +60,11 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean modifyRealmForSSL() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
UserRepresentation user = UserBuilder.create()
|
||||
|
@ -269,6 +274,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
// KEYCLOAK-5797
|
||||
@Test
|
||||
public void loginWithDifferentClients() throws Exception {
|
||||
String redirectUri = String.format("%s://localhost:%s/foo/bar/baz", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT);
|
||||
// Open tab1 and start login here
|
||||
oauth.openLoginForm();
|
||||
loginPage.assertCurrent();
|
||||
|
@ -277,7 +283,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
// Go to tab2 and start login with different client "root-url-client"
|
||||
oauth.clientId("root-url-client");
|
||||
oauth.redirectUri("http://localhost:8180/foo/bar/baz");
|
||||
oauth.redirectUri(redirectUri);
|
||||
oauth.openLoginForm();
|
||||
loginPage.assertCurrent();
|
||||
String tab2Url = driver.getCurrentUrl();
|
||||
|
@ -294,16 +300,18 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
// Go back to tab2 and finish login here. Should be on the root-url-client page
|
||||
driver.navigate().to(tab2Url);
|
||||
String currentUrl = driver.getCurrentUrl();
|
||||
Assert.assertThat(currentUrl, Matchers.startsWith("http://localhost:8180/foo/bar/baz"));
|
||||
Assert.assertThat(currentUrl, Matchers.startsWith(redirectUri));
|
||||
}
|
||||
|
||||
|
||||
// KEYCLOAK-5938
|
||||
@Test
|
||||
public void loginWithSameClientDifferentStatesLoginInTab1() throws Exception {
|
||||
String redirectUri1 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix1", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT);
|
||||
String redirectUri2 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix2", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT);
|
||||
// Open tab1 and start login here
|
||||
oauth.stateParamHardcoded("state1");
|
||||
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix1");
|
||||
oauth.redirectUri(redirectUri1);
|
||||
oauth.openLoginForm();
|
||||
loginPage.assertCurrent();
|
||||
loginPage.login("login-test", "bad-password");
|
||||
|
@ -311,7 +319,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
// Go to tab2 and start login with different client "root-url-client"
|
||||
oauth.stateParamHardcoded("state2");
|
||||
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix2");
|
||||
oauth.redirectUri(redirectUri2);
|
||||
oauth.openLoginForm();
|
||||
loginPage.assertCurrent();
|
||||
String tab2Url = driver.getCurrentUrl();
|
||||
|
@ -325,7 +333,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
// Assert I am redirected to the appPage in tab1 and have state corresponding to tab1
|
||||
appPage.assertCurrent();
|
||||
String currentUrl = driver.getCurrentUrl();
|
||||
Assert.assertThat(currentUrl, Matchers.startsWith("http://localhost:8180/auth/realms/master/app/auth/suffix1"));
|
||||
Assert.assertThat(currentUrl, Matchers.startsWith(redirectUri1));
|
||||
Assert.assertTrue(currentUrl.contains("state1"));
|
||||
}
|
||||
|
||||
|
@ -333,9 +341,11 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
// KEYCLOAK-5938
|
||||
@Test
|
||||
public void loginWithSameClientDifferentStatesLoginInTab2() throws Exception {
|
||||
String redirectUri1 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix1", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT);
|
||||
String redirectUri2 = String.format("%s://localhost:%s/auth/realms/master/app/auth/suffix2", AUTH_SERVER_SCHEME, AUTH_SERVER_PORT);
|
||||
// Open tab1 and start login here
|
||||
oauth.stateParamHardcoded("state1");
|
||||
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix1");
|
||||
oauth.redirectUri(redirectUri1);
|
||||
oauth.openLoginForm();
|
||||
loginPage.assertCurrent();
|
||||
loginPage.login("login-test", "bad-password");
|
||||
|
@ -343,7 +353,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
|
||||
// Go to tab2 and start login with different client "root-url-client"
|
||||
oauth.stateParamHardcoded("state2");
|
||||
oauth.redirectUri("http://localhost:8180/auth/realms/master/app/auth/suffix2");
|
||||
oauth.redirectUri(redirectUri2);
|
||||
oauth.openLoginForm();
|
||||
loginPage.assertCurrent();
|
||||
String tab2Url = driver.getCurrentUrl();
|
||||
|
@ -356,7 +366,7 @@ public class MultipleTabsLoginTest extends AbstractTestRealmKeycloakTest {
|
|||
// Assert I am redirected to the appPage in tab2 and have state corresponding to tab2
|
||||
appPage.assertCurrent();
|
||||
String currentUrl = driver.getCurrentUrl();
|
||||
Assert.assertThat(currentUrl, Matchers.startsWith("http://localhost:8180/auth/realms/master/app/auth/suffix2"));
|
||||
Assert.assertThat(currentUrl, Matchers.startsWith(redirectUri2));
|
||||
Assert.assertTrue(currentUrl.contains("state2"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
assertEquals(403, response.getStatus());
|
||||
assertEquals(AUTH_SERVER_SSL_REQUIRED ? 200 : 403, response.getStatus());
|
||||
response.close();
|
||||
|
||||
{
|
||||
|
@ -932,7 +932,7 @@ public class AccessTokenTest extends AbstractKeycloakTest {
|
|||
adminClient.realm("test").clients().create(ClientBuilder.create()
|
||||
.clientId("sample-public-client")
|
||||
.authenticatorType("client-secret")
|
||||
.redirectUris("http://localhost:8180/auth/realms/master/app/*")
|
||||
.redirectUris(oauth.getRedirectUri() + "/*")
|
||||
.publicClient()
|
||||
.build());
|
||||
|
||||
|
|
|
@ -88,9 +88,9 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest {
|
|||
String title = PageUtils.getPageTitle(driver);
|
||||
Assert.assertEquals("Success code", title);
|
||||
|
||||
String code = driver.findElement(By.id(OAuth2Constants.CODE)).getAttribute("value");
|
||||
driver.findElement(By.id(OAuth2Constants.CODE)).getAttribute("value");
|
||||
|
||||
String codeId = events.expectLogin().detail(Details.REDIRECT_URI, "http://localhost:8180/auth/realms/test/protocol/openid-connect/oauth/oob").assertEvent().getDetails().get(Details.CODE_ID);
|
||||
events.expectLogin().detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/protocol/openid-connect/oauth/oob").assertEvent().getDetails().get(Details.CODE_ID);
|
||||
|
||||
ClientManager.realm(adminClient.realm("test")).clientId("test-app").removeRedirectUris(Constants.INSTALLED_APP_URN);
|
||||
}
|
||||
|
|
|
@ -140,13 +140,13 @@ public class LogoutTest extends AbstractKeycloakTest {
|
|||
|
||||
String logoutUrl = oauth.getLogoutUrl()
|
||||
.idTokenHint(idTokenString)
|
||||
.postLogoutRedirectUri(AppPage.baseUrl)
|
||||
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
|
||||
.build();
|
||||
|
||||
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
|
||||
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
|
||||
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,13 +165,13 @@ public class LogoutTest extends AbstractKeycloakTest {
|
|||
|
||||
String logoutUrl = oauth.getLogoutUrl()
|
||||
.idTokenHint(idTokenString)
|
||||
.postLogoutRedirectUri(AppPage.baseUrl)
|
||||
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
|
||||
.build();
|
||||
|
||||
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
|
||||
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
|
||||
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,13 +190,13 @@ public class LogoutTest extends AbstractKeycloakTest {
|
|||
// Logout should succeed with user already logged out, see KEYCLOAK-3399
|
||||
String logoutUrl = oauth.getLogoutUrl()
|
||||
.idTokenHint(idTokenString)
|
||||
.postLogoutRedirectUri(AppPage.baseUrl)
|
||||
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
|
||||
.build();
|
||||
|
||||
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
|
||||
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
|
||||
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,13 +226,13 @@ public class LogoutTest extends AbstractKeycloakTest {
|
|||
|
||||
String logoutUrl = oauth.getLogoutUrl()
|
||||
.idTokenHint(idTokenString)
|
||||
.postLogoutRedirectUri(AppPage.baseUrl)
|
||||
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
|
||||
.build();
|
||||
|
||||
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
|
||||
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
|
||||
assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(AppPage.baseUrl));
|
||||
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
|
||||
package org.keycloak.testsuite.oauth;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
|
@ -76,7 +79,8 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest {
|
|||
ClientRepresentation client = new ClientRepresentation();
|
||||
client.setClientId("more-uris-client");
|
||||
client.setEnabled(true);
|
||||
client.setRedirectUris(Arrays.asList("http://localhost:8180/auth/realms/master/app/auth", "http://localhost:8180/foo"));
|
||||
client.setRedirectUris(Arrays.asList("http://localhost:8180/auth/realms/master/app/auth", "http://localhost:8180/foo",
|
||||
"https://localhost:8543/auth/realms/master/app/auth", "https://localhost:8543/foo"));
|
||||
client.setBaseUrl("http://localhost:8180/auth/realms/master/app/auth");
|
||||
|
||||
testRealm.getClients().add(client);
|
||||
|
@ -85,6 +89,15 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest {
|
|||
.filter(cl -> cl.getClientId().equals("test-app"))
|
||||
.findFirst().get();
|
||||
testApp.setImplicitFlowEnabled(true);
|
||||
trimRedirectUris(testApp);
|
||||
}
|
||||
|
||||
// testMissingRedirectUri requires only one redirection url defined in the client. We need to trim the other one.
|
||||
private final void trimRedirectUris(ClientRepresentation testApp) {
|
||||
List<String> filteredUris = testApp.getRedirectUris().stream()
|
||||
.filter(uri -> AUTH_SERVER_SSL_REQUIRED ? uri.startsWith("https://") : uri.startsWith("http://"))
|
||||
.collect(Collectors.toList());
|
||||
testApp.setRedirectUris(filteredUris);
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -93,7 +106,7 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest {
|
|||
/*
|
||||
* Configure the default client ID. Seems like OAuthClient is keeping the state of clientID
|
||||
* For example: If some test case configure oauth.clientId("sample-public-client"), other tests
|
||||
* will faile and the clientID will always be "sample-public-client
|
||||
* will fail and the clientID will always be "sample-public-client
|
||||
* @see AccessTokenTest#testAuthorizationNegotiateHeaderIgnored()
|
||||
*/
|
||||
oauth.init(driver);
|
||||
|
|
|
@ -144,7 +144,7 @@ public class OAuthRedirectUriTest extends AbstractKeycloakTest {
|
|||
realm.client(installedApp7);
|
||||
|
||||
ClientBuilder installedApp8 = ClientBuilder.create().id("test-fragment").name("test-fragment")
|
||||
.redirectUris("http://localhost/*")
|
||||
.redirectUris("http://localhost/*", "https://localhost:8543/*")
|
||||
.secret("password");
|
||||
realm.client(installedApp8);
|
||||
|
||||
|
|
|
@ -89,12 +89,6 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
|
|||
@Rule
|
||||
public AssertEvents events = new AssertEvents(this);
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeAbstractKeycloakTest() throws Exception {
|
||||
super.beforeAbstractKeycloakTest();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void clientConfiguration() {
|
||||
ClientManager.realm(adminClient.realm("test")).clientId("test-app").directAccessGrant(true);
|
||||
|
@ -237,8 +231,7 @@ public class OIDCProtocolMappersTest extends AbstractKeycloakTest {
|
|||
Assert.assertThat(accessToken.getAudience(), arrayContainingInAnyOrder( "app", "account"));
|
||||
|
||||
// Assert allowed origins
|
||||
String expectedOrigin = UriUtils.getOrigin(oauth.getRedirectUri());
|
||||
Assert.assertNames(accessToken.getAllowedOrigins(), expectedOrigin);
|
||||
Assert.assertNames(accessToken.getAllowedOrigins(), "http://localhost:8180", "https://localhost:8543");
|
||||
|
||||
oauth.openLogout();
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.keycloak.testsuite.AssertEvents;
|
|||
import org.keycloak.testsuite.account.AccountFormServiceTest;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
|
||||
import org.keycloak.testsuite.arquillian.undertow.TLSUtils;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
import org.keycloak.testsuite.pages.AccountApplicationsPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
|
@ -514,7 +515,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
|||
|
||||
// Use accessToken to admin REST request
|
||||
try (Keycloak offlineTokenAdmin = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
|
||||
AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, tokenResponse.getAccessToken())) {
|
||||
AuthRealm.MASTER, Constants.ADMIN_CLI_CLIENT_ID, tokenResponse.getAccessToken(), TLSUtils.initializeTLS())) {
|
||||
RealmRepresentation testRealm = offlineTokenAdmin.realm("test").toRepresentation();
|
||||
Assert.assertNotNull(testRealm);
|
||||
}
|
||||
|
@ -560,7 +561,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
|||
// Go to account mgmt applications page
|
||||
applicationsPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, AccountFormServiceTest.ACCOUNT_REDIRECT + "?path=applications").assertEvent();
|
||||
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=applications").assertEvent();
|
||||
assertTrue(applicationsPage.isCurrent());
|
||||
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
|
||||
assertTrue(apps.containsKey("offline-client-2"));
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue