You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2016/11/15 20:48:52 UTC
[05/50] [abbrv] incubator-geode git commit: GEODE-1570: add a test to
verify rest security with SSL.
GEODE-1570: add a test to verify rest security with SSL.
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/a515ee06
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/a515ee06
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/a515ee06
Branch: refs/heads/feature/GEODE-1930
Commit: a515ee06deeca3adf0ba053883a488787267ebcb
Parents: 08bbbe2
Author: Jinmei Liao <ji...@pivotal.io>
Authored: Mon Nov 7 18:10:52 2016 -0800
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Wed Nov 9 08:11:07 2016 -0800
----------------------------------------------------------------------
.../rest/internal/web/GeodeRestClient.java | 154 +++++++++++--------
.../internal/web/RestSecurityWithSSLTest.java | 85 ++++++++++
.../src/test/resources/ssl/trusted.keystore | Bin 0 -> 2241 bytes
.../SecurityClusterConfigDUnitTest.java | 32 ++--
.../test/dunit/rules/LocatorStarterRule.java | 14 ++
5 files changed, 205 insertions(+), 80 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/a515ee06/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/GeodeRestClient.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/GeodeRestClient.java b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/GeodeRestClient.java
index 071b95c..4510e20 100644
--- a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/GeodeRestClient.java
+++ b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/GeodeRestClient.java
@@ -15,13 +15,10 @@
package org.apache.geode.rest.internal.web;
-import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.AuthCache;
-import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
@@ -30,46 +27,85 @@ 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.client.protocol.HttpClientContext;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
-import org.junit.Assert;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
-import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
public class GeodeRestClient {
-
- public final static String PROTOCOL = "http";
public final static String CONTEXT = "/geode/v1";
private int restPort = 0;
private String bindAddress = null;
+ private String protocol = "http";
+ private boolean useHttps = false;
+ private KeyStore keyStore;
public GeodeRestClient(String bindAddress, int restPort) {
this.bindAddress = bindAddress;
this.restPort = restPort;
}
- public HttpResponse doHEAD(String query, String username, String password)
- throws MalformedURLException {
+ public GeodeRestClient(String bindAddress, int restPort, boolean useHttps) {
+ if (useHttps) {
+ this.protocol = "https";
+ this.useHttps = true;
+ } else {
+ this.protocol = "http";
+ this.useHttps = false;
+ }
+ this.bindAddress = bindAddress;
+ this.restPort = restPort;
+ }
+
+ public static String getContentType(HttpResponse response) {
+ return response.getEntity().getContentType().getValue();
+ }
+
+ /**
+ * Retrieve the status code of the HttpResponse
+ *
+ * @param response The HttpResponse message received from the server
+ * @return a numeric value
+ */
+ public static int getCode(HttpResponse response) {
+ return response.getStatusLine().getStatusCode();
+ }
+
+ public static JSONObject getJsonObject(HttpResponse response) throws IOException, JSONException {
+ JSONTokener tokener = new JSONTokener(new InputStreamReader(response.getEntity().getContent()));
+ return new JSONObject(tokener);
+ }
+
+ public static JSONArray getJsonArray(HttpResponse response) throws IOException, JSONException {
+ JSONTokener tokener = new JSONTokener(new InputStreamReader(response.getEntity().getContent()));
+ return new JSONArray(tokener);
+ }
+
+ public HttpResponse doHEAD(String query, String username, String password) throws Exception {
HttpHead httpHead = new HttpHead(CONTEXT + query);
return doRequest(httpHead, username, password);
}
public HttpResponse doPost(String query, String username, String password, String body)
- throws MalformedURLException {
+ throws Exception {
HttpPost httpPost = new HttpPost(CONTEXT + query);
httpPost.addHeader("content-type", "application/json");
httpPost.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
@@ -77,83 +113,69 @@ public class GeodeRestClient {
}
public HttpResponse doPut(String query, String username, String password, String body)
- throws MalformedURLException {
+ throws Exception {
HttpPut httpPut = new HttpPut(CONTEXT + query);
httpPut.addHeader("content-type", "application/json");
httpPut.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
return doRequest(httpPut, username, password);
}
- public HttpResponse doGet(String uri, String username, String password)
- throws MalformedURLException {
+ public HttpResponse doGet(String uri, String username, String password) throws Exception {
HttpGet getRequest = new HttpGet(CONTEXT + uri);
return doRequest(getRequest, username, password);
}
- public HttpResponse doGetRequest(String url) throws MalformedURLException {
+ public HttpResponse doGetRequest(String url) throws Exception {
HttpGet getRequest = new HttpGet(url);
return doRequest(getRequest, null, null);
}
-
- public HttpResponse doDelete(String uri, String username, String password)
- throws MalformedURLException {
+ public HttpResponse doDelete(String uri, String username, String password) throws Exception {
HttpDelete httpDelete = new HttpDelete(CONTEXT + uri);
return doRequest(httpDelete, username, password);
}
- public static String getContentType(HttpResponse response) {
- return response.getEntity().getContentType().getValue();
- }
-
- /**
- * Retrieve the status code of the HttpResponse
- *
- * @param response The HttpResponse message received from the server
- *
- * @return a numeric value
- */
- public static int getCode(HttpResponse response) {
- return response.getStatusLine().getStatusCode();
- }
-
- public static JSONObject getJsonObject(HttpResponse response) throws IOException, JSONException {
- JSONTokener tokener = new JSONTokener(new InputStreamReader(response.getEntity().getContent()));
- return new JSONObject(tokener);
- }
-
- public static JSONArray getJsonArray(HttpResponse response) throws IOException, JSONException {
- JSONTokener tokener = new JSONTokener(new InputStreamReader(response.getEntity().getContent()));
- return new JSONArray(tokener);
- }
-
public HttpResponse doRequest(HttpRequestBase request, String username, String password)
- throws MalformedURLException {
- HttpHost targetHost = new HttpHost(bindAddress, restPort, PROTOCOL);
- CloseableHttpClient httpclient = HttpClients.custom().build();
+ throws Exception {
+ HttpHost targetHost = new HttpHost(bindAddress, restPort, protocol);
+
+ HttpClientBuilder clientBuilder = HttpClients.custom();
HttpClientContext clientContext = HttpClientContext.create();
- // if username is null, do not put in authentication
+
+ // configures the clientBuilder and clientContext
if (username != null) {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()),
new UsernamePasswordCredentials(username, password));
- httpclient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
- AuthCache authCache = new BasicAuthCache();
- BasicScheme basicAuth = new BasicScheme();
- authCache.put(targetHost, basicAuth);
- clientContext.setCredentialsProvider(credsProvider);
- clientContext.setAuthCache(authCache);
+ clientBuilder.setDefaultCredentialsProvider(credsProvider);
+ }
+
+ if (useHttps) {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()},
+ new SecureRandom());
+ clientBuilder.setSSLContext(ctx);
+ clientBuilder.setSSLHostnameVerifier(new NoopHostnameVerifier());
+ }
+
+ return clientBuilder.build().execute(targetHost, request, clientContext);
+ }
+
+ private static class DefaultTrustManager implements X509TrustManager {
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1)
+ throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1)
+ throws CertificateException {
}
- try {
- return httpclient.execute(targetHost, request, clientContext);
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- Assert.fail("Rest GET should not have thrown ClientProtocolException!");
- } catch (IOException e) {
- e.printStackTrace();
- Assert.fail("Rest GET Request should not have thrown IOException!");
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
}
- return null;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/a515ee06/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityWithSSLTest.java
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityWithSSLTest.java b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityWithSSLTest.java
new file mode 100644
index 0000000..f1df632
--- /dev/null
+++ b/geode-assembly/src/test/java/org/apache/geode/rest/internal/web/RestSecurityWithSSLTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.rest.internal.web;
+
+import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_BIND_ADDRESS;
+import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_TYPE;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD;
+import static org.apache.geode.distributed.ConfigurationProperties.START_DEV_REST_API;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.internal.security.SecurableCommunicationChannel;
+import org.apache.geode.security.templates.SimpleSecurityManager;
+import org.apache.geode.test.dunit.rules.ServerStarterRule;
+import org.apache.geode.test.junit.categories.IntegrationTest;
+import org.apache.geode.test.junit.categories.SecurityTest;
+import org.apache.http.HttpResponse;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.net.URL;
+import java.util.Properties;
+
+@Category({IntegrationTest.class, SecurityTest.class})
+public class RestSecurityWithSSLTest {
+
+ private static int restPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ ServerStarterRule serverStarter = null;
+
+ @Test
+ public void testRestSecurityWithSSL() throws Exception {
+ URL keystoreUrl =
+ RestSecurityWithSSLTest.class.getClassLoader().getResource("ssl/trusted.keystore");
+
+ Properties properties = new Properties();
+ properties.setProperty(SECURITY_MANAGER, SimpleSecurityManager.class.getName());
+ properties.setProperty(START_DEV_REST_API, "true");
+ properties.setProperty(HTTP_SERVICE_BIND_ADDRESS, "localhost");
+ properties.setProperty(HTTP_SERVICE_PORT, restPort + "");
+ properties.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant());
+ properties.setProperty(SSL_KEYSTORE, keystoreUrl.getPath());
+ properties.setProperty(SSL_KEYSTORE_PASSWORD, "password");
+ properties.setProperty(SSL_KEYSTORE_TYPE, "JKS");
+ properties.setProperty(SSL_TRUSTSTORE, keystoreUrl.getPath());
+ properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "password");
+ properties.setProperty(SSL_PROTOCOLS, "TLSv1.2,TLSv1.1");
+
+ serverStarter = new ServerStarterRule(properties);
+ serverStarter.startServer();
+
+ GeodeRestClient restClient = new GeodeRestClient("localhost", restPort, true);
+ HttpResponse response = restClient.doGet("/servers", "cluster", "cluster");
+
+ assertEquals(200, GeodeRestClient.getCode(response));
+ }
+
+ @After
+ public void after() {
+ if (serverStarter != null) {
+ serverStarter.after();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/a515ee06/geode-assembly/src/test/resources/ssl/trusted.keystore
----------------------------------------------------------------------
diff --git a/geode-assembly/src/test/resources/ssl/trusted.keystore b/geode-assembly/src/test/resources/ssl/trusted.keystore
new file mode 100644
index 0000000..bd75039
Binary files /dev/null and b/geode-assembly/src/test/resources/ssl/trusted.keystore differ
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/a515ee06/geode-core/src/test/java/org/apache/geode/security/SecurityClusterConfigDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/security/SecurityClusterConfigDUnitTest.java b/geode-core/src/test/java/org/apache/geode/security/SecurityClusterConfigDUnitTest.java
index cce4fdb..5d843d8 100644
--- a/geode-core/src/test/java/org/apache/geode/security/SecurityClusterConfigDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/security/SecurityClusterConfigDUnitTest.java
@@ -15,17 +15,14 @@
package org.apache.geode.security;
-import static org.apache.geode.distributed.ConfigurationProperties.*;
-import static org.assertj.core.api.Java6Assertions.*;
-import static org.junit.Assert.*;
-
-import java.util.Properties;
-
-import org.apache.geode.test.dunit.rules.ServerStarterRule;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
+import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
+import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_POST_PROCESSOR;
+import static org.assertj.core.api.Java6Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.apache.geode.GemFireConfigException;
import org.apache.geode.distributed.DistributedSystem;
@@ -34,8 +31,15 @@ import org.apache.geode.security.templates.SimpleSecurityManager;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
+import org.apache.geode.test.dunit.rules.ServerStarterRule;
import org.apache.geode.test.junit.categories.DistributedTest;
import org.apache.geode.test.junit.categories.SecurityTest;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.util.Properties;
@Category({DistributedTest.class, SecurityTest.class})
public class SecurityClusterConfigDUnitTest extends JUnit4DistributedTestCase {
@@ -51,9 +55,9 @@ public class SecurityClusterConfigDUnitTest extends JUnit4DistributedTestCase {
.addIgnoredException(LocalizedStrings.GEMFIRE_CACHE_SECURITY_MISCONFIGURATION_2.toString());
Properties props = new Properties();
props.setProperty(SECURITY_MANAGER, SimpleSecurityManager.class.getName());
- props.put(JMX_MANAGER, "false");
- props.put(JMX_MANAGER_START, "false");
- props.put(JMX_MANAGER_PORT, 0);
+ props.setProperty(JMX_MANAGER, "false");
+ props.setProperty(JMX_MANAGER_START, "false");
+ props.setProperty(JMX_MANAGER_PORT, 0 + "");
props.setProperty(SECURITY_POST_PROCESSOR, PDXPostProcessor.class.getName());
lsRule.getLocatorVM(0, props);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/a515ee06/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorStarterRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorStarterRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorStarterRule.java
index 72627a0..3329a40 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorStarterRule.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorStarterRule.java
@@ -15,6 +15,9 @@
package org.apache.geode.test.dunit.rules;
+import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
+import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
+import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START;
import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.junit.Assert.assertTrue;
@@ -51,6 +54,17 @@ public class LocatorStarterRule extends ExternalResource implements Serializable
if (!properties.containsKey(MCAST_PORT)) {
properties.setProperty(MCAST_PORT, "0");
}
+ if (properties.containsKey(JMX_MANAGER_PORT)) {
+ int jmxPort = Integer.parseInt(properties.getProperty(JMX_MANAGER_PORT));
+ if (jmxPort > 0) {
+ if (!properties.containsKey(JMX_MANAGER)) {
+ properties.put(JMX_MANAGER, "true");
+ }
+ if (!properties.containsKey(JMX_MANAGER_START)) {
+ properties.put(JMX_MANAGER_START, "true");
+ }
+ }
+ }
locator = (InternalLocator) Locator.startLocatorAndDS(0, null, properties);
int locatorPort = locator.getPort();
locator.resetInternalLocatorFileNamesWithCorrectPortNumber(locatorPort);