\r
import java.io.FileInputStream;\r
import java.security.KeyStore;\r
-import java.security.cert.X509Certificate;\r
-\r
-import javax.net.ssl.HostnameVerifier;\r
import javax.net.ssl.KeyManagerFactory;\r
import javax.net.ssl.SSLContext;\r
import javax.net.ssl.SSLSession;\r
import javax.net.ssl.TrustManager;\r
-import javax.net.ssl.X509TrustManager;\r
-\r
+import javax.ws.rs.client.Client;\r
+import javax.ws.rs.client.ClientBuilder;\r
+import org.glassfish.jersey.client.ClientProperties;\r
import org.onap.aai.restclient.enums.RestAuthenticationMode;\r
\r
-import com.sun.jersey.api.client.Client;\r
-import com.sun.jersey.api.client.config.ClientConfig;\r
-import com.sun.jersey.api.client.config.DefaultClientConfig;\r
-import com.sun.jersey.client.urlconnection.HTTPSProperties;\r
- \r
/**\r
- * This is a generic REST Client builder with flexible security validation. Sometimes it's nice to\r
- * be able to disable server chain cert validation and hostname validation to work-around lab\r
- * issues, but at the same time be able to provide complete validation with client cert + hostname +\r
- * server cert chain validation. I used the ModelLoader REST client as a base and merged in the TSUI\r
- * client I wrote which also validates the server hostname and server certificate chain.\r
+ * This is a generic REST Client builder with flexible security validation. Sometimes it's nice to be able to disable\r
+ * server chain cert validation and hostname validation to work-around lab issues, but at the same time be able to\r
+ * provide complete validation with client cert + hostname + server cert chain validation. I used the ModelLoader REST\r
+ * client as a base and merged in the TSUI client I wrote which also validates the server hostname and server\r
+ * certificate chain.\r
*/\r
public class RestClientBuilder {\r
\r
- public static final boolean DEFAULT_VALIDATE_SERVER_HOST = false;\r
- public static final boolean DEFAULT_VALIDATE_CERT_CHAIN = false;\r
- public static final String DEFAULT_CLIENT_CERT_FILENAME = null;\r
- public static final String DEFAULT_CERT_PASSWORD = null;\r
- public static final String DEFAULT_TRUST_STORE_FILENAME = null;\r
- public static final int DEFAULT_CONNECT_TIMEOUT_MS = 60000;\r
- public static final int DEFAULT_READ_TIMEOUT_MS = 60000;\r
- public static final RestAuthenticationMode DEFAULT_AUTH_MODE = RestAuthenticationMode.SSL_CERT;\r
- public static final String DEFAULT_BASIC_AUTH_USERNAME = "";\r
- public static final String DEFAULT_BASIC_AUTH_PASSWORD = "";\r
- public static final String DEFAULT_SSL_PROTOCOL = "TLS";\r
-\r
- private static final String KEYSTORE_ALGORITHM = "SunX509";\r
- private static final String KEYSTORE_TYPE = "PKCS12";\r
- private static final String TRUST_STORE_PROPERTY = "javax.net.ssl.trustStore";\r
-\r
- private boolean validateServerHostname;\r
- private boolean validateServerCertChain;\r
- private String clientCertFileName;\r
- private String clientCertPassword;\r
- private String truststoreFilename;\r
- private int connectTimeoutInMs;\r
- private int readTimeoutInMs;\r
- private RestAuthenticationMode authenticationMode;\r
- private String basicAuthUsername;\r
- private String basicAuthPassword;\r
- private String sslProtocol;\r
-\r
- /**\r
- * Rest Client Builder.\r
- */\r
- public RestClientBuilder() {\r
- validateServerHostname = DEFAULT_VALIDATE_SERVER_HOST;\r
- validateServerCertChain = DEFAULT_VALIDATE_CERT_CHAIN;\r
- clientCertFileName = DEFAULT_CLIENT_CERT_FILENAME;\r
- clientCertPassword = DEFAULT_CERT_PASSWORD;\r
- truststoreFilename = DEFAULT_TRUST_STORE_FILENAME;\r
- connectTimeoutInMs = DEFAULT_CONNECT_TIMEOUT_MS;\r
- readTimeoutInMs = DEFAULT_READ_TIMEOUT_MS;\r
- authenticationMode = DEFAULT_AUTH_MODE;\r
- basicAuthUsername = DEFAULT_BASIC_AUTH_USERNAME;\r
- basicAuthPassword = DEFAULT_BASIC_AUTH_PASSWORD;\r
- sslProtocol = DEFAULT_SSL_PROTOCOL;\r
- }\r
-\r
- public boolean isValidateServerHostname() {\r
- return validateServerHostname;\r
- }\r
-\r
- public void setValidateServerHostname(boolean validateServerHostname) {\r
- this.validateServerHostname = validateServerHostname;\r
- }\r
-\r
- public boolean isValidateServerCertChain() {\r
- return validateServerCertChain;\r
- }\r
-\r
- public void setValidateServerCertChain(boolean validateServerCertChain) {\r
- this.validateServerCertChain = validateServerCertChain;\r
- }\r
-\r
- public String getClientCertFileName() {\r
- return clientCertFileName;\r
- }\r
-\r
- public void setClientCertFileName(String clientCertFileName) {\r
- this.clientCertFileName = clientCertFileName;\r
- }\r
-\r
- public String getClientCertPassword() {\r
- return clientCertPassword;\r
- }\r
-\r
- public void setClientCertPassword(String clientCertPassword) {\r
- this.clientCertPassword = clientCertPassword;\r
- }\r
-\r
- public String getTruststoreFilename() {\r
- return truststoreFilename;\r
- }\r
-\r
- public void setTruststoreFilename(String truststoreFilename) {\r
- this.truststoreFilename = truststoreFilename;\r
- }\r
-\r
- public int getConnectTimeoutInMs() {\r
- return connectTimeoutInMs;\r
- }\r
-\r
- public void setConnectTimeoutInMs(int connectTimeoutInMs) {\r
- this.connectTimeoutInMs = connectTimeoutInMs;\r
- }\r
-\r
- public int getReadTimeoutInMs() {\r
- return readTimeoutInMs;\r
- }\r
-\r
- public void setReadTimeoutInMs(int readTimeoutInMs) {\r
- this.readTimeoutInMs = readTimeoutInMs;\r
- }\r
-\r
- public RestAuthenticationMode getAuthenticationMode() {\r
- return authenticationMode;\r
- }\r
-\r
- public void setAuthenticationMode(RestAuthenticationMode authenticationMode) {\r
- this.authenticationMode = authenticationMode;\r
- }\r
-\r
- public String getBasicAuthUsername() {\r
- return basicAuthUsername;\r
- }\r
-\r
- public void setBasicAuthUsername(String basicAuthUsername) {\r
- this.basicAuthUsername = basicAuthUsername;\r
- }\r
-\r
- public String getBasicAuthPassword() {\r
- return basicAuthPassword;\r
- }\r
-\r
- public void setBasicAuthPassword(String basicAuthPassword) {\r
- this.basicAuthPassword = basicAuthPassword;\r
- }\r
-\r
- public String getSslProtocol() {\r
- return sslProtocol;\r
- }\r
-\r
- public void setSslProtocol(String sslProtocol) {\r
- this.sslProtocol = sslProtocol;\r
- }\r
-\r
- /**\r
- * Returns Client configured for SSL\r
- */\r
- public Client getClient() throws Exception {\r
-\r
- switch (authenticationMode) {\r
- case SSL_BASIC:\r
- case SSL_CERT:\r
- return getClient(true);\r
-\r
- default:\r
- // return basic non-authenticating HTTP client\r
- return getClient(false);\r
+ public static final boolean DEFAULT_VALIDATE_SERVER_HOST = false;\r
+ public static final boolean DEFAULT_VALIDATE_CERT_CHAIN = false;\r
+ public static final String DEFAULT_CLIENT_CERT_FILENAME = null;\r
+ public static final String DEFAULT_CERT_PASSWORD = null;\r
+ public static final String DEFAULT_TRUST_STORE_FILENAME = null;\r
+ public static final int DEFAULT_CONNECT_TIMEOUT_MS = 60000;\r
+ public static final int DEFAULT_READ_TIMEOUT_MS = 60000;\r
+ public static final RestAuthenticationMode DEFAULT_AUTH_MODE = RestAuthenticationMode.SSL_CERT;\r
+ public static final String DEFAULT_BASIC_AUTH_USERNAME = "";\r
+ public static final String DEFAULT_BASIC_AUTH_PASSWORD = "";\r
+ public static final String DEFAULT_SSL_PROTOCOL = "TLS";\r
+\r
+ private static final String KEYSTORE_ALGORITHM = "SunX509";\r
+ private static final String KEYSTORE_TYPE = "PKCS12";\r
+ private static final String TRUST_STORE_PROPERTY = "javax.net.ssl.trustStore";\r
+\r
+ private boolean validateServerHostname;\r
+ private boolean validateServerCertChain;\r
+ private String clientCertFileName;\r
+ private String clientCertPassword;\r
+ private String truststoreFilename;\r
+ private int connectTimeoutInMs;\r
+ private int readTimeoutInMs;\r
+ private RestAuthenticationMode authenticationMode;\r
+ private String basicAuthUsername;\r
+ private String basicAuthPassword;\r
+ private String sslProtocol;\r
+\r
+ /**\r
+ * Rest Client Builder.\r
+ */\r
+ public RestClientBuilder() {\r
+ validateServerHostname = DEFAULT_VALIDATE_SERVER_HOST;\r
+ validateServerCertChain = DEFAULT_VALIDATE_CERT_CHAIN;\r
+ clientCertFileName = DEFAULT_CLIENT_CERT_FILENAME;\r
+ clientCertPassword = DEFAULT_CERT_PASSWORD;\r
+ truststoreFilename = DEFAULT_TRUST_STORE_FILENAME;\r
+ connectTimeoutInMs = DEFAULT_CONNECT_TIMEOUT_MS;\r
+ readTimeoutInMs = DEFAULT_READ_TIMEOUT_MS;\r
+ authenticationMode = DEFAULT_AUTH_MODE;\r
+ basicAuthUsername = DEFAULT_BASIC_AUTH_USERNAME;\r
+ basicAuthPassword = DEFAULT_BASIC_AUTH_PASSWORD;\r
+ sslProtocol = DEFAULT_SSL_PROTOCOL;\r
+ }\r
+\r
+ public boolean isValidateServerHostname() {\r
+ return validateServerHostname;\r
+ }\r
+\r
+ public void setValidateServerHostname(boolean validateServerHostname) {\r
+ this.validateServerHostname = validateServerHostname;\r
+ }\r
+\r
+ public boolean isValidateServerCertChain() {\r
+ return validateServerCertChain;\r
+ }\r
+\r
+ public void setValidateServerCertChain(boolean validateServerCertChain) {\r
+ this.validateServerCertChain = validateServerCertChain;\r
+ }\r
+\r
+ public String getClientCertFileName() {\r
+ return clientCertFileName;\r
+ }\r
+\r
+ public void setClientCertFileName(String clientCertFileName) {\r
+ this.clientCertFileName = clientCertFileName;\r
+ }\r
+\r
+ public String getClientCertPassword() {\r
+ return clientCertPassword;\r
+ }\r
+\r
+ public void setClientCertPassword(String clientCertPassword) {\r
+ this.clientCertPassword = clientCertPassword;\r
+ }\r
+\r
+ public String getTruststoreFilename() {\r
+ return truststoreFilename;\r
+ }\r
+\r
+ public void setTruststoreFilename(String truststoreFilename) {\r
+ this.truststoreFilename = truststoreFilename;\r
+ }\r
+\r
+ public int getConnectTimeoutInMs() {\r
+ return connectTimeoutInMs;\r
+ }\r
+\r
+ public void setConnectTimeoutInMs(int connectTimeoutInMs) {\r
+ this.connectTimeoutInMs = connectTimeoutInMs;\r
}\r
\r
- }\r
-\r
- protected void setupSecureSocketLayerClientConfig(ClientConfig clientConfig) throws Exception {\r
- // Check to see if we need to perform proper validation of\r
- // the certificate chains.\r
- TrustManager[] trustAllCerts = null;\r
- if (truststoreFilename != null) {\r
- System.setProperty(TRUST_STORE_PROPERTY, truststoreFilename);\r
- } else {\r
- throw new IllegalArgumentException("Trust store filename must be set!");\r
- }\r
-\r
- // Set up the SSL context, keystore, etc. to use for our connection\r
- // to the AAI.\r
- SSLContext ctx = SSLContext.getInstance(sslProtocol);\r
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM);\r
- KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);\r
-\r
- char[] pwd = null;\r
- if (clientCertPassword != null) {\r
- pwd = clientCertPassword.toCharArray();\r
+ public int getReadTimeoutInMs() {\r
+ return readTimeoutInMs;\r
}\r
\r
- if (clientCertFileName != null) {\r
- FileInputStream fin = new FileInputStream(clientCertFileName);\r
+ public void setReadTimeoutInMs(int readTimeoutInMs) {\r
+ this.readTimeoutInMs = readTimeoutInMs;\r
+ }\r
+\r
+ public RestAuthenticationMode getAuthenticationMode() {\r
+ return authenticationMode;\r
+ }\r
\r
- // Load the keystore and initialize the key manager factory.\r
- ks.load(fin, pwd);\r
- kmf.init(ks, pwd);\r
+ public void setAuthenticationMode(RestAuthenticationMode authenticationMode) {\r
+ this.authenticationMode = authenticationMode;\r
+ }\r
\r
- ctx.init(kmf.getKeyManagers(), trustAllCerts, null);\r
- } else {\r
- ctx.init(null, trustAllCerts, null);\r
+ public String getBasicAuthUsername() {\r
+ return basicAuthUsername;\r
}\r
\r
- // Are we performing validation of the server host name?\r
- if (validateServerHostname) {\r
- clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,\r
- new HTTPSProperties(null, ctx));\r
-\r
- } else {\r
- clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,\r
- new HTTPSProperties(new HostnameVerifier() {\r
- @Override\r
- public boolean verify(String str, SSLSession sslSession) {\r
- return true;\r
- }\r
- }, ctx));\r
+ public void setBasicAuthUsername(String basicAuthUsername) {\r
+ this.basicAuthUsername = basicAuthUsername;\r
}\r
- }\r
\r
+ public String getBasicAuthPassword() {\r
+ return basicAuthPassword;\r
+ }\r
\r
- /**\r
- * Returns client instance\r
- * \r
- * @param useSsl - used to configure the client with an ssl-context or just plain http\r
- */\r
- protected Client getClient(boolean useSsl) throws Exception {\r
+ public void setBasicAuthPassword(String basicAuthPassword) {\r
+ this.basicAuthPassword = basicAuthPassword;\r
+ }\r
\r
- ClientConfig clientConfig = new DefaultClientConfig();\r
+ public String getSslProtocol() {\r
+ return sslProtocol;\r
+ }\r
\r
- if (useSsl) {\r
- setupSecureSocketLayerClientConfig(clientConfig);\r
+ public void setSslProtocol(String sslProtocol) {\r
+ this.sslProtocol = sslProtocol;\r
}\r
\r
- // Finally, create and initialize our client...\r
- Client client = null;\r
- client = Client.create(clientConfig);\r
- client.setConnectTimeout(connectTimeoutInMs);\r
- client.setReadTimeout(readTimeoutInMs);\r
-\r
- // ...and return it to the caller.\r
- return client;\r
- }\r
-\r
- public String getBasicAuthenticationCredentials() {\r
-\r
- String usernameAndPassword = getBasicAuthUsername() + ":" + getBasicAuthPassword();\r
- return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());\r
- }\r
-\r
- /* \r
- * Added a little bit of logic to obfuscate passwords that could be logged out\r
- * (non-Javadoc)\r
- * @see java.lang.Object#toString()\r
- */\r
- @Override\r
- public String toString() {\r
- return "RestClientBuilder [validateServerHostname=" + validateServerHostname\r
- + ", validateServerCertChain=" + validateServerCertChain + ", "\r
- + (clientCertFileName != null ? "clientCertFileName=" + clientCertFileName + ", " : "")\r
- + (clientCertPassword != null\r
- ? "clientCertPassword="\r
- + java.util.Base64.getEncoder().encodeToString(clientCertPassword.getBytes()) + ", "\r
- : "")\r
- + (truststoreFilename != null ? "truststoreFilename=" + truststoreFilename + ", " : "")\r
- + "connectTimeoutInMs=" + connectTimeoutInMs + ", readTimeoutInMs=" + readTimeoutInMs + ", "\r
- + (authenticationMode != null ? "authenticationMode=" + authenticationMode + ", " : "")\r
- + (basicAuthUsername != null ? "basicAuthUsername=" + basicAuthUsername + ", " : "")\r
- + (basicAuthPassword != null ? "basicAuthPassword="\r
- + java.util.Base64.getEncoder().encodeToString(basicAuthPassword.getBytes()) : "")\r
- + "]";\r
- }\r
+ /**\r
+ * Returns Client configured for SSL\r
+ */\r
+ public Client getClient() throws Exception {\r
+\r
+ switch (authenticationMode) {\r
+ case SSL_BASIC:\r
+ case SSL_CERT:\r
+ return getClient(true);\r
+\r
+ default:\r
+ // return basic non-authenticating HTTP client\r
+ return getClient(false);\r
+ }\r
+\r
+ }\r
+\r
+ protected void setupSecureSocketLayerClientConfig(ClientBuilder builder) throws Exception {\r
+ // Check to see if we need to perform proper validation of\r
+ // the certificate chains.\r
+ TrustManager[] trustAllCerts = null;\r
+ if (truststoreFilename != null) {\r
+ System.setProperty(TRUST_STORE_PROPERTY, truststoreFilename);\r
+ } else {\r
+ throw new IllegalArgumentException("Trust store filename must be set!");\r
+ }\r
+\r
+ // Set up the SSL context, keystore, etc. to use for our connection\r
+ // to the AAI.\r
+ SSLContext ctx = SSLContext.getInstance(sslProtocol);\r
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM);\r
+ KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);\r
+\r
+ char[] pwd = null;\r
+ if (clientCertPassword != null) {\r
+ pwd = clientCertPassword.toCharArray();\r
+ }\r
+\r
+ if (clientCertFileName != null) {\r
+ FileInputStream fin = new FileInputStream(clientCertFileName);\r
+\r
+ // Load the keystore and initialize the key manager factory.\r
+ ks.load(fin, pwd);\r
+ kmf.init(ks, pwd);\r
+\r
+ ctx.init(kmf.getKeyManagers(), trustAllCerts, null);\r
+ } else {\r
+ ctx.init(null, trustAllCerts, null);\r
+ }\r
+\r
+ builder.sslContext(ctx);\r
+\r
+ // Are we performing validation of the server host name?\r
+ if (!validateServerHostname) {\r
+ builder.hostnameVerifier((String str, SSLSession sslSession) -> true);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns client instance\r
+ *\r
+ * @param useSsl - used to configure the client with an ssl-context or just plain http\r
+ */\r
+ protected Client getClient(boolean useSsl) throws Exception {\r
+\r
+ // Finally, create and initialize our client...\r
+ ClientBuilder builder = ClientBuilder.newBuilder();\r
+ if (useSsl) {\r
+ setupSecureSocketLayerClientConfig(builder);\r
+ }\r
+ Client client = builder.build();\r
+ client.property(ClientProperties.CONNECT_TIMEOUT, connectTimeoutInMs);\r
+ client.property(ClientProperties.READ_TIMEOUT, readTimeoutInMs);\r
+\r
+ // ...and return it to the caller.\r
+ return client;\r
+ }\r
+\r
+ public String getBasicAuthenticationCredentials() {\r
+\r
+ String usernameAndPassword = getBasicAuthUsername() + ":" + getBasicAuthPassword();\r
+ return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());\r
+ }\r
+\r
+ /*\r
+ * Added a little bit of logic to obfuscate passwords that could be logged out (non-Javadoc)\r
+ * \r
+ * @see java.lang.Object#toString()\r
+ */\r
+ @Override\r
+ public String toString() {\r
+ return "RestClientBuilder [validateServerHostname=" + validateServerHostname + ", validateServerCertChain="\r
+ + validateServerCertChain + ", "\r
+ + (clientCertFileName != null ? "clientCertFileName=" + clientCertFileName + ", " : "")\r
+ + (clientCertPassword != null\r
+ ? "clientCertPassword="\r
+ + java.util.Base64.getEncoder().encodeToString(clientCertPassword.getBytes()) + ", "\r
+ : "")\r
+ + (truststoreFilename != null ? "truststoreFilename=" + truststoreFilename + ", " : "")\r
+ + "connectTimeoutInMs=" + connectTimeoutInMs + ", readTimeoutInMs=" + readTimeoutInMs + ", "\r
+ + (authenticationMode != null ? "authenticationMode=" + authenticationMode + ", " : "")\r
+ + (basicAuthUsername != null ? "basicAuthUsername=" + basicAuthUsername + ", " : "")\r
+ + (basicAuthPassword != null ? "basicAuthPassword="\r
+ + java.util.Base64.getEncoder().encodeToString(basicAuthPassword.getBytes()) : "")\r
+ + "]";\r
+ }\r
\r
}\r