Rest Client: add callback to customize http client settings
The callback replaces the ability to fully replace the http client instance. By doing that, one used to lose any default that the RestClient had set for the underlying http client. Given that you'd usually override one or two things only, like a couple of timeout values, the ssl factory or the default credentials providers, it is not uder friendly if by doing that users end up replacing the whole http client instance and lose any default set by us. Original commit: elastic/x-pack-elasticsearch@03adca6f62
This commit is contained in:
parent
4360cccad7
commit
107ab2d71d
|
@ -5,8 +5,6 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.authc.pki;
|
package org.elasticsearch.xpack.security.authc.pki;
|
||||||
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.elasticsearch.client.Response;
|
import org.elasticsearch.client.Response;
|
||||||
import org.elasticsearch.client.ResponseException;
|
import org.elasticsearch.client.ResponseException;
|
||||||
|
@ -15,16 +13,16 @@ import org.elasticsearch.client.transport.TransportClient;
|
||||||
import org.elasticsearch.common.network.NetworkModule;
|
import org.elasticsearch.common.network.NetworkModule;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||||
|
import org.elasticsearch.test.SecurityIntegTestCase;
|
||||||
|
import org.elasticsearch.test.SecuritySettingsSource;
|
||||||
|
import org.elasticsearch.transport.Transport;
|
||||||
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.elasticsearch.xpack.security.Security;
|
import org.elasticsearch.xpack.security.Security;
|
||||||
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
import org.elasticsearch.xpack.security.authc.support.SecuredString;
|
||||||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.xpack.security.transport.SSLClientAuth;
|
import org.elasticsearch.xpack.security.transport.SSLClientAuth;
|
||||||
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyHttpServerTransport;
|
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyHttpServerTransport;
|
||||||
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyTransport;
|
import org.elasticsearch.xpack.security.transport.netty.SecurityNettyTransport;
|
||||||
import org.elasticsearch.test.SecurityIntegTestCase;
|
|
||||||
import org.elasticsearch.test.SecuritySettingsSource;
|
|
||||||
import org.elasticsearch.transport.Transport;
|
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
@ -79,8 +77,7 @@ public class PkiOptionalClientAuthTests extends SecurityIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRestClientWithoutClientCertificate() throws Exception {
|
public void testRestClientWithoutClientCertificate() throws Exception {
|
||||||
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(getSSLContext()).build();
|
try (RestClient restClient = createRestClient(new SSLContextHttpConfigCallback(getSSLContext()), "https")) {
|
||||||
try (RestClient restClient = createRestClient(httpClient, "https")) {
|
|
||||||
try {
|
try {
|
||||||
restClient.performRequest("GET", "_nodes");
|
restClient.performRequest("GET", "_nodes");
|
||||||
fail("request should have failed");
|
fail("request should have failed");
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
package org.elasticsearch.xpack.security.authc.pki;
|
package org.elasticsearch.xpack.security.authc.pki;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.client.Response;
|
import org.elasticsearch.client.Response;
|
||||||
|
@ -78,8 +76,7 @@ public class PkiWithoutClientAuthenticationTests extends SecurityIntegTestCase {
|
||||||
public void testThatHttpWorks() throws Exception {
|
public void testThatHttpWorks() throws Exception {
|
||||||
SSLContext sc = SSLContext.getInstance("SSL");
|
SSLContext sc = SSLContext.getInstance("SSL");
|
||||||
sc.init(null, trustAllCerts, new SecureRandom());
|
sc.init(null, trustAllCerts, new SecureRandom());
|
||||||
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sc).build();
|
try (RestClient restClient = createRestClient(new SSLContextHttpConfigCallback(sc), "https")) {
|
||||||
try (RestClient restClient = createRestClient(httpClient, "https")) {
|
|
||||||
try (Response response = restClient.performRequest("GET", "/_nodes",
|
try (Response response = restClient.performRequest("GET", "/_nodes",
|
||||||
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
|
||||||
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.DEFAULT_USER_NAME,
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.xpack.security.authc.pki;
|
||||||
|
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.elasticsearch.client.RestClient;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
|
class SSLContextHttpConfigCallback implements RestClient.HttpClientConfigCallback {
|
||||||
|
|
||||||
|
private final SSLContext sslContext;
|
||||||
|
|
||||||
|
SSLContextHttpConfigCallback(SSLContext sslContext) {
|
||||||
|
this.sslContext = sslContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customizeDefaultRequestConfig(RequestConfig.Builder requestConfigBuilder) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
|
||||||
|
httpClientBuilder.setSSLContext(sslContext);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,10 +5,10 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.transport.ssl;
|
package org.elasticsearch.xpack.security.transport.ssl;
|
||||||
|
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.apache.http.ssl.SSLContexts;
|
import org.apache.http.ssl.SSLContexts;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
|
@ -61,8 +61,7 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
|
||||||
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
|
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
|
||||||
SSLContexts.createDefault(),
|
SSLContexts.createDefault(),
|
||||||
NoopHostnameVerifier.INSTANCE);
|
NoopHostnameVerifier.INSTANCE);
|
||||||
|
try (RestClient restClient = createRestClient(new SSLSocketFactoryHttpConfigCallback(socketFactory), "https")) {
|
||||||
try (RestClient restClient = createRestClient(HttpClients.custom().setSSLSocketFactory(socketFactory).build(), "https")) {
|
|
||||||
restClient.performRequest("GET", "/");
|
restClient.performRequest("GET", "/");
|
||||||
fail("Expected SSLHandshakeException");
|
fail("Expected SSLHandshakeException");
|
||||||
} catch (SSLHandshakeException e) {
|
} catch (SSLHandshakeException e) {
|
||||||
|
@ -75,14 +74,10 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
|
||||||
.put(getSSLSettingsForStore("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient"))
|
.put(getSSLSettingsForStore("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testclient.jks", "testclient"))
|
||||||
.build();
|
.build();
|
||||||
ClientSSLService sslService = new ClientSSLService(settings, new Global(settings));
|
ClientSSLService sslService = new ClientSSLService(settings, new Global(settings));
|
||||||
|
|
||||||
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
|
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
|
||||||
sslService.sslContext(),
|
sslService.sslContext(),
|
||||||
NoopHostnameVerifier.INSTANCE);
|
NoopHostnameVerifier.INSTANCE);
|
||||||
|
try (RestClient restClient = createRestClient(new SSLSocketFactoryHttpConfigCallback(socketFactory), "https")) {
|
||||||
CloseableHttpClient client = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
|
|
||||||
|
|
||||||
try (RestClient restClient = createRestClient(client, "https")) {
|
|
||||||
try (Response response = restClient.performRequest("GET", "/",
|
try (Response response = restClient.performRequest("GET", "/",
|
||||||
new BasicHeader("Authorization", basicAuthHeaderValue(transportClientUsername(), transportClientPassword())))) {
|
new BasicHeader("Authorization", basicAuthHeaderValue(transportClientUsername(), transportClientPassword())))) {
|
||||||
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
|
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
|
||||||
|
@ -115,4 +110,23 @@ public class SslClientAuthTests extends SecurityIntegTestCase {
|
||||||
assertGreenClusterState(client);
|
assertGreenClusterState(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class SSLSocketFactoryHttpConfigCallback implements RestClient.HttpClientConfigCallback {
|
||||||
|
|
||||||
|
private final SSLConnectionSocketFactory sslSocketFactory;
|
||||||
|
|
||||||
|
SSLSocketFactoryHttpConfigCallback(SSLConnectionSocketFactory sslSocketFactory) {
|
||||||
|
this.sslSocketFactory = sslSocketFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customizeDefaultRequestConfig(RequestConfig.Builder requestConfigBuilder) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customizeHttpClient(HttpClientBuilder httpClientBuilder) {
|
||||||
|
httpClientBuilder.setSSLSocketFactory(sslSocketFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue