From b87763dba175291a234a37d0d2f288a7b1acffe9 Mon Sep 17 00:00:00 2001 From: Madhawa Perera Date: Wed, 18 Apr 2018 15:18:59 +0530 Subject: [PATCH] Add capability to WSO2 IOT server to route HTTP/HTTPS calls through Proxy server (#1244) * Fix IoT Server HTTP/HTTPS calls bypassing a Proxy server Since the Feign client is not supporting proxy routing this fix has included okhttp client and pass it to the feigns okkhttp client wrapper in order to pass HTTP/HTTPS call through proxy server if the system proxy properties are set. Further this modifies the apache http client also to pick system properties. fixes wso2/product-iots#1806 * Remove unwanted comments and commented lines * Remove the localhost host check * Add default non proxy hosts Added localhost as a default non proxy host * use the version property from parent pom Use the version property, "github.openfeign.version" from parent pom instead of hard-coding the version range --- .../pom.xml | 11 ++ .../client/OAuthRequestInterceptor.java | 6 +- .../client/publisher/PublisherClient.java | 6 +- .../integration/client/store/StoreClient.java | 6 +- .../apimgt/integration/client/util/Utils.java | 102 ++++++++++++++---- .../client/extension/util/JWTClientUtil.java | 2 +- pom.xml | 12 +++ 7 files changed, 118 insertions(+), 27 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml index fd1e4f3f48..9daac391ce 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml @@ -72,6 +72,9 @@ javax.xml, org.wso2.carbon.base, javax.net.ssl, + feign.okhttp; version=${github.openfeign.version}, + okhttp3, + org.apache.commons.lang jsr311-api, @@ -110,6 +113,14 @@ + + com.squareup.okhttp3 + okhttp + + + io.github.openfeign + feign-okhttp + org.wso2.carbon org.wso2.carbon.logging diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java index b4bc910686..4bf2875509 100755 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java @@ -22,6 +22,7 @@ import feign.auth.BasicAuthRequestInterceptor; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -65,8 +66,9 @@ public class OAuthRequestInterceptor implements RequestInterceptor { public OAuthRequestInterceptor() { String username = APIMConfigReader.getInstance().getConfig().getUsername(); String password = APIMConfigReader.getInstance().getConfig().getPassword(); - dcrClient = Feign.builder().client(Utils.getSSLClient()).logger(new Slf4jLogger()).logLevel( - Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password)) + dcrClient = Feign.builder().client(new OkHttpClient(Utils.getSSLClient())).logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, + password)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(DCRClient.class, Utils.replaceProperties( APIMConfigReader.getInstance().getConfig().getDcrEndpoint())); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java index 8b52380f1c..3887d59c66 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java @@ -22,6 +22,7 @@ import feign.Logger; import feign.RequestInterceptor; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; +import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -49,8 +50,9 @@ public class PublisherClient { * */ public PublisherClient(RequestInterceptor requestInterceptor) { - Feign.Builder builder = Feign.builder().client( - org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient()).logger(new Slf4jLogger()) + Feign.Builder builder = Feign.builder().client(new OkHttpClient( + org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient())).logger(new + Slf4jLogger()) .logLevel(Logger.Level.FULL) .requestInterceptor(requestInterceptor).encoder(new GsonEncoder()).decoder(new GsonDecoder()); String basePath = Utils.replaceSystemProperty(APIMConfigReader.getInstance().getConfig().getPublisherEndpoint()); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java index 19633fa009..db751f204e 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java @@ -24,6 +24,7 @@ import feign.RequestInterceptor; import feign.Retryer; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; +import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.integration.client.configs.APIMConfigReader; @@ -52,8 +53,9 @@ public class StoreClient { public StoreClient(RequestInterceptor requestInterceptor) { - Feign.Builder builder = Feign.builder().client( - org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient()).logger(new Slf4jLogger()) + Feign.Builder builder = Feign.builder().client(new OkHttpClient( + org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient())).logger(new + Slf4jLogger()) .logLevel(Logger.Level.FULL) .requestInterceptor(requestInterceptor).encoder(new GsonEncoder()).decoder(new GsonDecoder()); String basePath = Utils.replaceSystemProperty(APIMConfigReader.getInstance().getConfig().getStoreEndpoint()); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java index 3474d836bd..d42baf2c43 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java @@ -18,24 +18,38 @@ package org.wso2.carbon.apimgt.integration.client.util; +import okhttp3.OkHttpClient; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.ServerConfiguration; -import feign.Client; - -import javax.net.ssl.*; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.security.*; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import feign.Logger; -import feign.Request; -import feign.Response; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.ServerConfiguration; public class Utils { @@ -73,17 +87,65 @@ public class Utils { return text; } - public static Client getSSLClient() { - boolean isIgnoreHostnameVerification = Boolean.parseBoolean(System.getProperty("org.wso2.ignoreHostnameVerification")); - if(isIgnoreHostnameVerification) { - return new Client.Default(getSimpleTrustedSSLSocketFactory(), new HostnameVerifier() { - @Override - public boolean verify(String s, SSLSession sslSession) { - return true; + public static OkHttpClient getSSLClient() { + + boolean isIgnoreHostnameVerification = Boolean.parseBoolean(System.getProperty("org.wso2" + + ".ignoreHostnameVerification")); + OkHttpClient okHttpClient; + final String proxyHost = System.getProperty("http.proxyHost"); + final String proxyPort = System.getProperty("http.proxyPort"); + final String nonProxyHostsValue = System.getProperty("http.nonProxyHosts"); + + final ProxySelector proxySelector = new ProxySelector() { + @Override + public java.util.List select(final URI uri) { + final List proxyList = new ArrayList(1); + + final String host = uri.getHost(); + + if (host.startsWith("127.0.0.1") || host.startsWith("localhost") || StringUtils.contains + (nonProxyHostsValue, host)) { + proxyList.add(Proxy.NO_PROXY); + } else { + proxyList.add(new Proxy(Proxy.Type.HTTP, + new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)))); } - }); + + return proxyList; + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + + X509TrustManager trustAllCerts = new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[0]; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + }; + if(isIgnoreHostnameVerification) { + okHttpClient = new OkHttpClient.Builder() + .sslSocketFactory(getSimpleTrustedSSLSocketFactory(), trustAllCerts) + .hostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }).proxySelector(proxySelector).build(); + return okHttpClient; }else { - return new Client.Default(getTrustedSSLSocketFactory(), null); + SSLSocketFactory trustedSSLSocketFactory = getTrustedSSLSocketFactory(); + okHttpClient = new OkHttpClient.Builder().sslSocketFactory(trustedSSLSocketFactory) + .proxySelector(proxySelector).build(); + return okHttpClient; } } diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java index d4c21f6e5a..93f6e6fd17 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java @@ -97,7 +97,7 @@ public class JWTClientUtil { SSLContextBuilder builder = new SSLContextBuilder(); builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); - httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); + httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).useSystemProperties().build(); } else { httpclient = HttpClients.createDefault(); } diff --git a/pom.xml b/pom.xml index 503dd5a7f7..16d41042da 100644 --- a/pom.xml +++ b/pom.xml @@ -1238,6 +1238,16 @@ gson ${google.gson.version} + + com.squareup.okhttp3 + okhttp + ${squareup.okhttp3.version} + + + io.github.openfeign + feign-okhttp + ${github.openfeign.version} + org.apache.httpcomponents httpclient @@ -1971,6 +1981,8 @@ 3.0.0.wso2v1 1.3 2.3.1 + 3.8.1 + 9.3.1 1.1.1 1.2 4.5.1