diff --git a/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/SSLITest.java b/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/SSLITest.java
index 9285aac29..bb3a17888 100644
--- a/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/SSLITest.java
+++ b/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/SSLITest.java
@@ -25,10 +25,13 @@
import io.restassured.itest.java.support.WithJetty;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
+import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
@@ -39,10 +42,8 @@
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
-public class SSLITest extends WithJetty {
-
- @Rule
- public ExpectedException exception = ExpectedException.none();
+@RunWith(Enclosed.class)
+public class SSLITest {
public static ResponseSpecification helloWorldSpec() {
return new ResponseSpecBuilder().
@@ -50,215 +51,260 @@ public static ResponseSpecification helloWorldSpec() {
expectStatusCode(200).build();
}
- @Test(expected = SSLException.class)
- public void throwsSSLExceptionWhenHostnameInCertDoesntMatch() throws Exception {
- RestAssured.get("https://localhost:8443/hello");
- }
+ public static class OneWaySSLTest extends WithJetty {
- @Test
- public void givenTrustStoreDefinedStaticallyWhenSpecifyingJksKeyStoreFileWithCorrectPasswordAllowsToUseSSL() throws Exception {
- RestAssured.trustStore("jetty_localhost_client.jks", "test1234");
- try {
- RestAssured.expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
- } finally {
- RestAssured.reset();
- }
- }
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
- @Test(expected = SSLHandshakeException.class)
- public void whenEnablingAllowAllHostNamesVerifierWithoutActivatingAKeyStore() throws Exception {
- RestAssured.config = RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().allowAllHostnames());
- try {
- RestAssured.get("https://localhost:8443/hello").then().spec(helloWorldSpec());
- } finally {
- RestAssured.reset();
+ @Test(expected = SSLException.class)
+ public void throwsSSLExceptionWhenHostnameInCertDoesntMatch() throws Exception {
+ RestAssured.get("https://localhost:8443/hello");
}
- }
- @Test
- public void usingStaticallyConfiguredCertificateAuthenticationWorks() throws Exception {
- RestAssured.authentication = RestAssured.certificate("jetty_localhost_client.jks", "test1234", CertificateAuthSettings.certAuthSettings().allowAllHostnames());
- try {
- RestAssured.get("https://localhost:8443/hello").then().spec(helloWorldSpec());
- } finally {
- RestAssured.reset();
+ @Test
+ public void givenTrustStoreDefinedStaticallyWhenSpecifyingJksKeyStoreFileWithCorrectPasswordAllowsToUseSSL() throws Exception {
+ RestAssured.trustStore("jetty_localhost_client.jks", "test1234");
+ try {
+ RestAssured.expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
+ } finally {
+ RestAssured.reset();
+ }
}
- }
- @Test(expected = SSLException.class)
- public void usingStaticallyConfiguredCertificateAuthenticationWithIllegalHostNameInCertDoesntWork() throws Exception {
- RestAssured.authentication = RestAssured.certificate("truststore_mjvmobile.jks", "test4321");
- try {
- RestAssured.get("https://localhost:8443/hello").then().body(containsString("eurosport"));
- } finally {
- RestAssured.reset();
+ @Test(expected = SSLHandshakeException.class)
+ public void whenEnablingAllowAllHostNamesVerifierWithoutActivatingAKeyStore() throws Exception {
+ RestAssured.config = RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().allowAllHostnames());
+ try {
+ RestAssured.get("https://localhost:8443/hello").then().spec(helloWorldSpec());
+ } finally {
+ RestAssured.reset();
+ }
}
- }
- @Test
- public void usingStaticallyConfiguredCertificateAuthenticationWithIllegalHostNameInCertWorksWhenSSLConfigIsConfiguredToAllowAllHostNames() throws Exception {
- RestAssured.config = RestAssuredConfig.newConfig().sslConfig(SSLConfig.sslConfig().allowAllHostnames());
- RestAssured.authentication = RestAssured.certificate("jetty_localhost_client.jks", "test1234");
- try {
- RestAssured.get("https://localhost:8443/hello").then().spec(helloWorldSpec());
- } finally {
- RestAssured.reset();
+ @Test
+ public void usingStaticallyConfiguredCertificateAuthenticationWorks() throws Exception {
+ RestAssured.authentication = RestAssured.certificate("jetty_localhost_client.jks", "test1234", CertificateAuthSettings.certAuthSettings().allowAllHostnames());
+ try {
+ RestAssured.get("https://localhost:8443/hello").then().spec(helloWorldSpec());
+ } finally {
+ RestAssured.reset();
+ }
}
- }
- @Test
- public void givenKeystoreDefinedUsingGivenWhenSpecifyingJksKeyStoreFileWithCorrectPasswordAllowsToUseSSL() throws Exception {
- RestAssured.given().trustStore("/jetty_localhost_client.jks", "test1234").then().expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
- }
+ @Test(expected = SSLException.class)
+ public void usingStaticallyConfiguredCertificateAuthenticationWithIllegalHostNameInCertDoesntWork() throws Exception {
+ RestAssured.authentication = RestAssured.certificate("truststore_mjvmobile.jks", "test4321");
+ try {
+ RestAssured.get("https://localhost:8443/hello").then().body(containsString("eurosport"));
+ } finally {
+ RestAssured.reset();
+ }
+ }
- @Test
- public void throwsIOExceptionWhenPasswordIsIncorrect() throws Exception {
- exception.expect(IOException.class);
- exception.expectMessage("Keystore was tampered with, or password was incorrect");
-
- RestAssured.given().
- auth().certificate("jetty_localhost_client.jks", "test4333").
- when().
- get("https://localhost:8443/hello").
- then().
- body(containsString("eurosport"));
- }
+ @Test
+ public void usingStaticallyConfiguredCertificateAuthenticationWithIllegalHostNameInCertWorksWhenSSLConfigIsConfiguredToAllowAllHostNames() throws Exception {
+ RestAssured.config = RestAssuredConfig.newConfig().sslConfig(SSLConfig.sslConfig().allowAllHostnames());
+ RestAssured.authentication = RestAssured.certificate("jetty_localhost_client.jks", "test1234");
+ try {
+ RestAssured.get("https://localhost:8443/hello").then().spec(helloWorldSpec());
+ } finally {
+ RestAssured.reset();
+ }
+ }
- @Test
- public void certificateAuthenticationWorks() throws Exception {
- RestAssured.given().
- auth().certificate("jetty_localhost_client.jks", "test1234", CertificateAuthSettings.certAuthSettings().allowAllHostnames()).
- when().
- get("https://localhost:8443/hello").
- then().
- spec(helloWorldSpec());
- }
+ @Test
+ public void givenKeystoreDefinedUsingGivenWhenSpecifyingJksKeyStoreFileWithCorrectPasswordAllowsToUseSSL() throws Exception {
+ RestAssured.given().trustStore("/jetty_localhost_client.jks", "test1234").then().expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
+ }
- @Test public void
- allows_specifying_trust_store_in_dsl() throws Exception {
- InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(keyStoreStream, "test1234".toCharArray());
+ @Test
+ public void throwsIOExceptionWhenPasswordIsIncorrect() throws Exception {
+ exception.expect(IOException.class);
+ exception.expectMessage("Keystore was tampered with, or password was incorrect");
+
+ RestAssured.given().
+ auth().certificate("jetty_localhost_client.jks", "test4333").
+ when().
+ get("https://localhost:8443/hello").
+ then().
+ body(containsString("eurosport"));
+ }
- RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().allowAllHostnames())).trustStore(keyStore).when().get("https://localhost:8443/hello").then().statusCode(200);
- }
+ @Test
+ public void certificateAuthenticationWorks() throws Exception {
+ RestAssured.given().
+ auth().certificate("jetty_localhost_client.jks", "test1234", CertificateAuthSettings.certAuthSettings().allowAllHostnames()).
+ when().
+ get("https://localhost:8443/hello").
+ then().
+ spec(helloWorldSpec());
+ }
- @Ignore("Temporary ignored but I think this ought to work. Perhaps some issues with config merging?")
- @Test public void
- allows_specifying_trust_store_statically() throws Exception {
- InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(keyStoreStream, "test1234".toCharArray());
+ @Test
+ public void
+ allows_specifying_trust_store_in_dsl() throws Exception {
+ InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(keyStoreStream, "test1234".toCharArray());
- RestAssured.trustStore(keyStore);
+ RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().allowAllHostnames())).trustStore(keyStore).when().get("https://localhost:8443/hello").then().statusCode(200);
+ }
- try {
- RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().allowAllHostnames())).when().get("https://localhost:8443/hello").then().statusCode(200);
- } finally {
- RestAssured.reset();
+ @Ignore("Temporary ignored but I think this ought to work. Perhaps some issues with config merging?")
+ @Test
+ public void
+ allows_specifying_trust_store_statically() throws Exception {
+ InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(keyStoreStream, "test1234".toCharArray());
+
+ RestAssured.trustStore(keyStore);
+
+ try {
+ RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().allowAllHostnames())).when().get("https://localhost:8443/hello").then().statusCode(200);
+ } finally {
+ RestAssured.reset();
+ }
}
- }
- @Test public void
- allows_specifying_trust_store_and_allow_all_host_names_in_config_using_dsl() throws Exception {
- InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(keyStoreStream, "test1234".toCharArray());
+ @Test
+ public void
+ allows_specifying_trust_store_and_allow_all_host_names_in_config_using_dsl() throws Exception {
+ InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(keyStoreStream, "test1234".toCharArray());
- RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().trustStore(keyStore).and().allowAllHostnames())).when().get("https://localhost:8443/hello").then().spec(helloWorldSpec());
- }
+ RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().trustStore(keyStore).and().allowAllHostnames())).when().get("https://localhost:8443/hello").then().spec(helloWorldSpec());
+ }
- @Test public void
- relaxed_https_validation_works_using_instance_config() {
- RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().relaxedHTTPSValidation())).when().get("https://localhost:8443/hello").then().spec(helloWorldSpec());
- }
+ @Test
+ public void
+ relaxed_https_validation_works_using_instance_config() {
+ RestAssured.given().config(RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().relaxedHTTPSValidation())).when().get("https://localhost:8443/hello").then().spec(helloWorldSpec());
+ }
- @Ignore("Site is not working anymore")
- @Test public void
- relaxed_https_validation_works_using_instance_dsl() {
- RestAssured.given().relaxedHTTPSValidation().when().get("https://bunny.cloudamqp.com/api/").then().statusCode(200);
- }
+ @Ignore("Site is not working anymore")
+ @Test
+ public void
+ relaxed_https_validation_works_using_instance_dsl() {
+ RestAssured.given().relaxedHTTPSValidation().when().get("https://bunny.cloudamqp.com/api/").then().statusCode(200);
+ }
- @Ignore("Site is not working anymore")
- @Test public void
- relaxed_https_validation_works_when_defined_statically() {
- RestAssured.useRelaxedHTTPSValidation();
+ @Ignore("Site is not working anymore")
+ @Test
+ public void
+ relaxed_https_validation_works_when_defined_statically() {
+ RestAssured.useRelaxedHTTPSValidation();
+
+ try {
+ RestAssured.get("https://bunny.cloudamqp.com/api/").then().statusCode(200);
+ } finally {
+ RestAssured.reset();
+ }
+ }
- try {
- RestAssured.get("https://bunny.cloudamqp.com/api/").then().statusCode(200);
- } finally {
- RestAssured.reset();
+ @Ignore("Site is not working anymore")
+ @Test
+ public void
+ relaxed_https_validation_works_when_defined_statically_with_base_uri() {
+ RestAssured.useRelaxedHTTPSValidation();
+ RestAssured.baseURI = "https://bunny.cloudamqp.com";
+
+ try {
+ RestAssured.get("/api/").then().statusCode(200);
+ } finally {
+ RestAssured.reset();
+ }
}
- }
- @Ignore("Site is not working anymore")
- @Test public void
- relaxed_https_validation_works_when_defined_statically_with_base_uri() {
- RestAssured.useRelaxedHTTPSValidation();
- RestAssured.baseURI = "https://bunny.cloudamqp.com";
+ @Test
+ public void
+ truststore_works_with_static_base_uri() {
+ RestAssured.baseURI = "https://localhost:8443/hello";
- try {
- RestAssured.get("/api/").then().statusCode(200);
- } finally {
- RestAssured.reset();
+ try {
+ RestAssured.given().trustStore("/jetty_localhost_client.jks", "test1234").when().get().then().spec(helloWorldSpec());
+ } finally {
+ RestAssured.reset();
+ }
+ }
+
+ @Ignore("Temporary ignored since site has changed")
+ @Test
+ public void
+ truststrore_works_with_static_base_uri() throws Exception {
+ RestAssured.baseURI = "https://bunny.cloudamqp.com/";
+
+ InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("truststore_cloudamqp.jks");
+ KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ keyStore.load(keyStoreStream, "cloud1234".toCharArray());
+
+ try {
+ RestAssured.given().trustStore(keyStore).when().get("/api/").then().statusCode(200);
+ } finally {
+ RestAssured.reset();
+ }
}
- }
- @Test public void
- truststore_works_with_static_base_uri() {
- RestAssured.baseURI = "https://localhost:8443/hello";
- try {
- RestAssured.given().trustStore("/jetty_localhost_client.jks", "test1234").when().get().then().spec(helloWorldSpec());
- } finally {
- RestAssured.reset();
+ @Test
+ public void
+ can_make_request_to_sites_that_with_valid_ssl_cert() {
+ RestAssured.get("https://duckduckgo.com/").then().statusCode(200);
}
- }
- @Ignore("Temporary ignored since site has changed") @Test public void
- truststrore_works_with_static_base_uri() throws Exception{
- RestAssured.baseURI = "https://bunny.cloudamqp.com/";
+ @Test
+ public void
+ allows_specifying_trust_store_statically_with_request_builder() throws Exception {
+ // Load the trust store
+ InputStream trustStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
+ KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(trustStoreStream, "test1234".toCharArray());
- InputStream keyStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("truststore_cloudamqp.jks");
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(keyStoreStream, "cloud1234".toCharArray());
+ // Set the truststore on the global config
+ RestAssured.config = RestAssured.config().sslConfig(SSLConfig.sslConfig().trustStore(trustStore).and().allowAllHostnames());
- try {
- RestAssured.given().trustStore(keyStore).when().get("/api/").then().statusCode(200);
- } finally {
- RestAssured.reset();
+ final RequestSpecification spec = new RequestSpecBuilder().build();
+ RestAssured.given().spec(spec).get("https://localhost:8443/hello").then().spec(helloWorldSpec());
}
- }
+ @Test
+ public void
+ supports_setting_truststore_in_request_specification() {
+ final RequestSpecification spec = new RequestSpecBuilder().setTrustStore("/jetty_localhost_client.jks", "test1234").build();
+ RestAssured.given().spec(spec).expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
+ }
- @Test public void
- can_make_request_to_sites_that_with_valid_ssl_cert() {
- RestAssured.get("https://duckduckgo.com/").then().statusCode(200);
+ @Test
+ public void
+ supports_overriding_truststore_in_request_specification() {
+ final RequestSpecification spec = new RequestSpecBuilder().setTrustStore("/jetty_localhost_client.jks", "wrong pw").build();
+ RestAssured.given().spec(spec).trustStore("/jetty_localhost_client.jks", "test1234").expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
+ }
}
- @Test public void
- allows_specifying_trust_store_statically_with_request_builder() throws Exception {
- // Load the trust store
- InputStream trustStoreStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jetty_localhost_client.jks");
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- trustStore.load(trustStoreStream, "test1234".toCharArray());
-
- // Set the truststore on the global config
- RestAssured.config = RestAssured.config().sslConfig(SSLConfig.sslConfig().trustStore(trustStore).and().allowAllHostnames());
+ public static class TwoWaySSLTest extends WithJetty {
- final RequestSpecification spec = new RequestSpecBuilder().build();
- RestAssured.given().spec(spec).get("https://localhost:8443/hello").then().spec(helloWorldSpec());
- }
+ @BeforeClass
+ public static void startJetty() throws Exception {
+ startJettyTwoWaySSL();
+ }
- @Test public void
- supports_setting_truststore_in_request_specification() {
- final RequestSpecification spec = new RequestSpecBuilder().setTrustStore("/jetty_localhost_client.jks", "test1234").build();
- RestAssured.given().spec(spec).expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
- }
+ @Test(expected = SSLException.class)
+ public void relaxed_https_validation_throws_exception_without_keystore() {
+ RestAssuredConfig sslConfig = RestAssuredConfig.config().sslConfig(SSLConfig.sslConfig().relaxedHTTPSValidation());
+ RestAssured.given().config(sslConfig).when().get("https://localhost:8443/hello").then().spec(helloWorldSpec());
+ }
- @Test public void
- supports_overriding_truststore_in_request_specification() {
- final RequestSpecification spec = new RequestSpecBuilder().setTrustStore("/jetty_localhost_client.jks", "wrong pw").build();
- RestAssured.given().spec(spec).trustStore("/jetty_localhost_client.jks", "test1234").expect().spec(helloWorldSpec()).when().get("https://localhost:8443/hello");
+ @Test
+ public void relaxed_https_validation_works_using_instance_config() {
+ RestAssuredConfig sslConfig = RestAssuredConfig.config().sslConfig(
+ SSLConfig.sslConfig()
+ .keyStore("keystore.p12", "test1234")
+ .keystoreType("PKCS12")
+ .relaxedHTTPSValidation()
+ );
+ RestAssured.given().config(sslConfig).when().get("https://localhost:8443/hello").then().spec(helloWorldSpec());
+ }
}
}
diff --git a/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/support/WithJetty.java b/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/support/WithJetty.java
index 34cbf3314..ca27e385b 100644
--- a/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/support/WithJetty.java
+++ b/examples/rest-assured-itest-java/src/test/java/io/restassured/itest/java/support/WithJetty.java
@@ -23,7 +23,17 @@
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
-import org.eclipse.jetty.server.*;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.handler.HandlerList;
+import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.WebAppContext;
@@ -33,7 +43,11 @@
import org.junit.Rule;
import org.junit.rules.ExpectedException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import java.io.File;
+import java.io.IOException;
import java.util.Collections;
import static io.restassured.itest.java.support.WithJetty.JettyOption.RESET_REST_ASSURED_BEFORE_TEST;
@@ -61,6 +75,10 @@ protected WithJetty(JettyOption jettyOption) {
@BeforeClass
public static void startJetty() throws Exception {
+ startJettyOneWaySSL();
+ }
+
+ protected static void startJettyOneWaySSL() throws Exception {
server = new Server();
HttpConfiguration httpConfig = new HttpConfiguration();
@@ -129,6 +147,46 @@ public static void startJetty() throws Exception {
server.start();
}
+ protected static void startJettyTwoWaySSL() throws Exception {
+ server = new Server();
+ int httpsPort = 8443;
+
+ // Setup HTTP Connector
+ HttpConfiguration httpConf = new HttpConfiguration();
+ httpConf.setSecurePort(httpsPort);
+ httpConf.setSecureScheme("https");
+
+ // Setup SSL
+ String keystore = WithJetty.class.getClassLoader().getResource("keystore.p12").getFile();
+ SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
+ sslContextFactory.setKeyStorePath(keystore);
+ sslContextFactory.setKeyStorePassword("test1234");
+ sslContextFactory.setTrustAll(true);
+ sslContextFactory.setNeedClientAuth(true);
+
+ // Setup HTTPS Configuration
+ HttpConfiguration httpsConf = new HttpConfiguration();
+ httpsConf.setSecureScheme("https");
+ httpsConf.setSecurePort(httpsPort);
+ httpsConf.addCustomizer(new SecureRequestCustomizer());
+
+ // Establish the HTTPS ServerConnector
+ ServerConnector httpsConnector = new ServerConnector(server,
+ new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
+ new HttpConnectionFactory(httpsConf));
+ httpsConnector.setPort(httpsPort);
+
+ server.addConnector(httpsConnector);
+
+ // Add a Handlers for requests
+ HandlerList handlers = new HandlerList();
+ handlers.addHandler(new SecuredRedirectHandler());
+ handlers.addHandler(new HelloHandler());
+ server.setHandler(handlers);
+
+ server.start();
+ }
+
private static void dontSendDateHeader(Server server) {
// Remove the sending of date header since it makes testing of logging much harder
for (Connector y : server.getConnectors()) {
@@ -167,4 +225,15 @@ public enum JettyOption {
RESET_REST_ASSURED_BEFORE_TEST,
DONT_RESET_REST_ASSURED_BEFORE_TEST
}
+
+ private static class HelloHandler extends AbstractHandler {
+
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+ response.setContentType("text/json;charset=utf-8");
+ response.setStatus(HttpServletResponse.SC_OK);
+ baseRequest.setHandled(true);
+ response.getWriter().println("{\"hello\": \"Hello Scalatra\"}");
+ }
+ }
}
diff --git a/examples/rest-assured-itest-java/src/test/resources/keystore.p12 b/examples/rest-assured-itest-java/src/test/resources/keystore.p12
new file mode 100644
index 000000000..d07388ef3
Binary files /dev/null and b/examples/rest-assured-itest-java/src/test/resources/keystore.p12 differ
diff --git a/rest-assured/src/main/java/io/restassured/config/SSLConfig.java b/rest-assured/src/main/java/io/restassured/config/SSLConfig.java
index 4540eff2a..e51b99330 100644
--- a/rest-assured/src/main/java/io/restassured/config/SSLConfig.java
+++ b/rest-assured/src/main/java/io/restassured/config/SSLConfig.java
@@ -22,14 +22,23 @@
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import static org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
@@ -246,8 +255,10 @@ public SSLConfig trustStore(KeyStore trustStore) {
}
/**
- * Use relaxed HTTP validation. This means that you'll trust all hosts regardless if the SSL certificate is invalid. By using this
- * method you don't need to specify a keystore (see {@link #keyStore(String, String)} or trust store (see {@link #trustStore(java.security.KeyStore)}.
+ * Use relaxed HTTP validation. This means that you'll trust all hosts regardless if the SSL certificate is invalid.
+ * By using this method you don't need to specify a trust store (see {@link #trustStore(java.security.KeyStore)}.
+ * If you need to send an SSL certificate, then you can specify a key store (see {@link #keyStore(File, String)}
+ * and a key store type (see {@link #keystoreType(String)} before calling this method.
* This method assumes that the protocol for the {@link SSLContext} instance is {@value #SSL}. If this is not the case use {@link #relaxedHTTPSValidation(String)}.
*
* @return A new SSLConfig instance.
@@ -257,8 +268,10 @@ public SSLConfig relaxedHTTPSValidation() {
}
/**
- * Use relaxed HTTP validation. This means that you'll trust all hosts regardless if the SSL certificate is invalid. By using this
- * method you don't need to specify a keystore (see {@link #keyStore(String, String)} or trust store (see {@link #trustStore(java.security.KeyStore)}.
+ * Use relaxed HTTP validation. This means that you'll trust all hosts regardless if the SSL certificate is invalid.
+ * By using this method you don't need to specify a trust store (see {@link #trustStore(java.security.KeyStore)}.
+ * If you need to send an SSL certificate, then you can specify a key store (see {@link #keyStore(File, String)}
+ * and a key store type (see {@link #keystoreType(String)} before calling this method
*
* @param protocol The standard name of the requested protocol. See the SSLContext section in the Java Cryptography Architecture Standard Algorithm Name Documentation for information about standard protocol names.
* @return A new SSLConfig instance
@@ -272,9 +285,18 @@ public SSLConfig relaxedHTTPSValidation(String protocol) {
return SafeExceptionRethrower.safeRethrow(e);
}
- // Set up a TrustManager that trusts everything
try {
- sslContext.init(null, new TrustManager[]{new X509TrustManager() {
+ // Set up a KeyManager to use with relaxed HTTPS validation
+ KeyStore relaxedKeyStore = loadKeyStore();
+ KeyManager[] keyManagers = null;
+ if (relaxedKeyStore != null) {
+ KeyManagerFactory kmf =
+ KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(relaxedKeyStore, keyStorePassword.toCharArray());
+ keyManagers = kmf.getKeyManagers();
+ }
+ // Set up a TrustManager that trusts everything
+ sslContext.init(keyManagers, new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@@ -285,7 +307,7 @@ public void checkClientTrusted(X509Certificate[] certs, String authType) {
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}}, new SecureRandom());
- } catch (KeyManagementException e) {
+ } catch (KeyManagementException | UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException e) {
return SafeExceptionRethrower.safeRethrow(e);
}
@@ -451,8 +473,49 @@ public X509HostnameVerifier getX509HostnameVerifier() {
/**
* @return true
if user has configured this SSL Configuration instance, false
otherwise.
*/
+ @Override
public boolean isUserConfigured() {
return isUserConfigured;
}
+ private KeyStore loadKeyStore() {
+ if (pathToKeyStore == null) {
+ return null;
+ }
+
+ InputStream resource;
+ try {
+ if (pathToKeyStore instanceof String) {
+ String keyStorePath = (String) pathToKeyStore;
+ if (keyStorePath.trim().isEmpty()) {
+ return null;
+ }
+ resource = Thread.currentThread().getContextClassLoader().getResourceAsStream(keyStorePath);
+ if (resource == null) { // To allow for backward compatibility
+ resource = getClass().getResourceAsStream(keyStorePath);
+ }
+ if (resource == null) { // Fallback to load path as file if not found in classpath
+ resource = new FileInputStream(keyStorePath);
+ }
+ } else {
+ resource = new FileInputStream((File) pathToKeyStore);
+ }
+ } catch (FileNotFoundException e) {
+ return SafeExceptionRethrower.safeRethrow(e);
+ }
+
+ try {
+ KeyStore relaxedKeyStore = KeyStore.getInstance(keyStoreType);
+ relaxedKeyStore.load(resource, keyStorePassword.toCharArray());
+ return relaxedKeyStore;
+ } catch (IOException | KeyStoreException | CertificateException | NoSuchAlgorithmException e) {
+ return SafeExceptionRethrower.safeRethrow(e);
+ } finally {
+ try {
+ resource.close();
+ } catch (IOException e) {
+ // Nothing to do
+ }
+ }
+ }
}