Skip to content

Commit

Permalink
[ISSUE alibaba#3315] nacos client support https
Browse files Browse the repository at this point in the history
  • Loading branch information
wangweizZZ committed Aug 20, 2020
1 parent a837c70 commit 78a9f62
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package com.alibaba.nacos.client.config.impl;

import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.client.identify.Base64;
import com.alibaba.nacos.client.identify.CredentialService;
import com.alibaba.nacos.common.codec.Base64;
import com.alibaba.nacos.common.utils.StringUtils;

import javax.crypto.Mac;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.alibaba.nacos.client.naming.utils;

import com.alibaba.nacos.client.identify.Base64;
import com.alibaba.nacos.common.codec.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.alibaba.nacos.client.identify;
package com.alibaba.nacos.common.codec;

import java.nio.charset.Charset;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,22 @@
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
import com.alibaba.nacos.common.http.client.request.DefaultAsyncHttpClientRequest;
import com.alibaba.nacos.common.http.client.request.JdkHttpClientRequest;
import com.alibaba.nacos.common.tls.SelfHostnameVerifier;
import com.alibaba.nacos.common.tls.TlsFileWatcher;
import com.alibaba.nacos.common.tls.TlsHelper;
import com.alibaba.nacos.common.tls.TlsSystemConfig;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.slf4j.Logger;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

/**
* AbstractHttpClientFactory Let the creator only specify the http client config.
*
Expand All @@ -34,7 +46,28 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory {
@Override
public final NacosRestTemplate createNacosRestTemplate() {
HttpClientConfig httpClientConfig = buildHttpClientConfig();
return new NacosRestTemplate(assignLogger(), new JdkHttpClientRequest(httpClientConfig));
final JdkHttpClientRequest clientRequest = new JdkHttpClientRequest(httpClientConfig);

if (TlsSystemConfig.tlsEnable) {
// enable ssl
clientRequest.setSSLContext(loadSSLContext());
final HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
final SelfHostnameVerifier selfHostnameVerifier = new SelfHostnameVerifier(hv);
clientRequest.replaceSSLHostnameVerifier(selfHostnameVerifier);

try {
TlsFileWatcher.getInstance().addFileChangeListener(new TlsFileWatcher.FileChangeListener() {
@Override
public void onChanged(String filePath) {
clientRequest.setSSLContext(loadSSLContext());
}
}, TlsSystemConfig.tlsClientTrustCertPath, TlsSystemConfig.tlsClientKeyPath);
} catch (IOException e) {
assignLogger().error("add tls file listener fail", e);
}
}

return new NacosRestTemplate(assignLogger(), clientRequest);
}

@Override
Expand All @@ -51,6 +84,23 @@ private RequestConfig getRequestConfig() {
.setMaxRedirects(httpClientConfig.getMaxRedirects()).build();
}

@SuppressWarnings("checkstyle:abbreviationaswordinname")
protected synchronized SSLContext loadSSLContext() {
if (!TlsSystemConfig.tlsEnable) {
return null;
}
try {
return TlsHelper.buildSslContext(true);
} catch (NoSuchAlgorithmException e) {
assignLogger().error("Failed to create SSLContext", e);
} catch (KeyManagementException e) {
assignLogger().error("Failed to create SSLContext", e);
} catch (SSLException e) {
assignLogger().error("Failed to create SSLContext", e);
}
return null;
}

/**
* build http client config.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,14 @@
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.MediaType;
import com.alibaba.nacos.common.model.RequestHttpEntity;
import com.alibaba.nacos.common.tls.SelfHostnameVerifier;
import com.alibaba.nacos.common.tls.TlsFileWatcher;
import com.alibaba.nacos.common.tls.TlsHelper;
import com.alibaba.nacos.common.tls.TlsSystemConfig;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -49,44 +42,34 @@
*/
public class JdkHttpClientRequest implements HttpClientRequest {

private static final Logger LOGGER = LoggerFactory.getLogger(JdkHttpClientRequest.class);

private HttpClientConfig httpClientConfig;

public JdkHttpClientRequest(HttpClientConfig httpClientConfig) {
this.httpClientConfig = httpClientConfig;
loadSSLContext();
replaceHostnameVerifier();
try {
TlsFileWatcher.getInstance().addFileChangeListener(new TlsFileWatcher.FileChangeListener() {
@Override
public void onChanged(String filePath) {
loadSSLContext();
}
}, TlsSystemConfig.tlsClientTrustCertPath, TlsSystemConfig.tlsClientKeyPath);
} catch (IOException e) {
LOGGER.error("add tls file listener fail", e);
}
}

/**
* Use specified {@link SSLContext}.
*
* @param sslContext ssl context
*/
@SuppressWarnings("checkstyle:abbreviationaswordinname")
private synchronized void loadSSLContext() {
if (TlsSystemConfig.tlsEnable) {
try {
HttpsURLConnection.setDefaultSSLSocketFactory(TlsHelper.buildSslContext(true).getSocketFactory());
} catch (NoSuchAlgorithmException e) {
LOGGER.error("Failed to create SSLContext", e);
} catch (KeyManagementException e) {
LOGGER.error("Failed to create SSLContext", e);
} catch (Exception e) {
e.printStackTrace();
}
public void setSSLContext(SSLContext sslContext) {
if (sslContext != null) {
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
}
}

private void replaceHostnameVerifier() {
final HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
HttpsURLConnection.setDefaultHostnameVerifier(new SelfHostnameVerifier(hv));
/**
* Replace the default HostnameVerifier.
*
* @param hostnameVerifier custom hostnameVerifier
*/
@SuppressWarnings("checkstyle:abbreviationaswordinname")
public void replaceSSLHostnameVerifier(HostnameVerifier hostnameVerifier) {
if (hostnameVerifier != null) {
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

package com.alibaba.nacos.common.tls;

import com.alibaba.nacos.common.codec.Base64;
import com.alibaba.nacos.common.utils.IoUtils;
import sun.misc.BASE64Decoder;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
Expand All @@ -44,7 +44,7 @@ final class PemReader {

private static final String ENCODE_US_ASCII = "US-ASCII";

static byte[] readPrivateKey(String keyPath) throws KeyException, IOException {
static byte[] readPrivateKey(String keyPath) throws KeyException {
try {
InputStream in = new FileInputStream(keyPath);
try {
Expand All @@ -59,9 +59,7 @@ static byte[] readPrivateKey(String keyPath) throws KeyException, IOException {
if (!m.find()) {
throw new KeyException("could not find a PKCS #8 private key in input stream");
}

final BASE64Decoder base64 = new BASE64Decoder();
return base64.decodeBuffer(m.group(1));
return Base64.decodeBase64(m.group(1).getBytes());
} finally {
IoUtils.closeQuietly(in);
}
Expand Down

0 comments on commit 78a9f62

Please sign in to comment.