Reputation: 1114
I am trying to post a service call using the SSL URL. I am getting an exception.
javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:517)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:667)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:664)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315).
I am using Spring, Jersey and trying to use ApacheClient(Reason to use, On Weblogic it is taking Weblogic specific HTTP handler, I know we can use "DUseSunHttpHandler=true" but I don't want to do that on production).
Please note, with only Jersey implementation it worked with http on both Tomcat and Weblogic. But with HTTPS it worked in Tomcat not in Weblogic. So went for ApacheConnectionProvider, from there it's not working in Tomcat as well.
POM entry
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.15</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.15</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-apache-connector</artifactId>
<version>2.15</version>
</dependency>
Code
public Client getClient() {
ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, new PoolingHttpClientConnectionManager());
//config your ssl for apache connector
SslConfigurator sslConfig = SslConfigurator.newInstance();
String trustStoreFile = "C:\\Development\\svn\\ecomm-webapp\\profiles\\uat\\workflowtrust.jks";
String trustStorePassword ="ABC12";
String keyStoreFile = "C:\\Development\\svn\\ecomm-webapp\\profiles\\uat\\workflow.jks";
String keyPassword ="abc12";
sslConfig.trustStoreFile(trustStoreFile).keyStoreFile(keyStoreFile).keyStorePassword(trustStorePassword).trustStorePassword(trustStorePassword).securityProtocol("SSL");
clientConfig.property(ApacheClientProperties.SSL_CONFIG, sslConfig);
ApacheConnectorProvider connector = new ApacheConnectorProvider();
clientConfig.connectorProvider(connector);
return ClientBuilder.newClient(clientConfig);
}
Calling Code
public <T> T postXmlFile(final File inputXml, final String targetUrl, Class<T> resultResponse, final RestfulServiceVerifier<T> restfulServiceVerifier) throws FunctionalException {
return post(MediaType.APPLICATION_XML_TYPE, MediaType.TEXT_XML_TYPE, inputXml, targetUrl, resultResponse, restfulServiceVerifier);
}
private <T> T post(final MediaType type, final MediaType accept, final Object entity, final String targetUrl, Class<T> resultResponse, final RestfulServiceVerifier<T> restfulServiceVerifier) throws FunctionalException {
Response response = null;
int responseStatus = -1;
T result = null;
while (restfulServiceVerifier.hasNextWorkFlowHit()) {
try {
response = restFulWebTargetFactory.getClient().target(targetUrl)
.request(type)
.post(Entity.entity(entity, accept));
responseStatus = response.getStatus();
if(EcommConstants.WORKFLOW_ORDER_PROPOSAL_SUCCESS_CODE == responseStatus) {
final String resultInString = response.readEntity(String.class);
//for audit purpose
if (LOG_XML_MESSAGE) {
log.info("XML Response "+ resultInString);
}
result = unMarshalXML(resultInString, resultResponse);
restfulServiceVerifier.checkResponse(result, responseStatus);
}
} catch (WorkFlowRetryException workFlowException) {
throw new FunctionalException("WebService post failed. ", workFlowException);
}catch (WorkFlowValidationException workFlowValidationException) {
log.error("Service Response Validation Exception " + workFlowValidationException.getErrorCode() + " Error Description " + workFlowValidationException.getDescription(), workFlowValidationException);
}catch (final Exception e) {
log.error("Exception occurred" , e);
} finally {
if(null != response) {
response.close();
}
}
}
if(-1 == responseStatus) {
throw new FunctionalException("WebService post failed. ", new Exception());
}
return result;
}
Upvotes: 2
Views: 3192
Reputation: 1114
I fixed it, please find the solution. I changed getClient() method.
Code Sample
private SslConfigurator createSSLContext() {
return SslConfigurator.newInstance()
.trustStoreFile(trustStoreFile)
.trustStorePassword(trustStorePassword)
.keyStoreFile(keyStoreFile)
.keyPassword(keyPassword).securityProtocol("SSL");
}
@Override
public Client getClient() {
HostnameVerifier defaultHostnameVerifier=new DefaultHostnameVerifier();
SslConfigurator sslConfig = createSSLContext();
LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
sslConfig.createSSLContext(),
defaultHostnameVerifier);
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactory)
.build();
ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, new PoolingHttpClientConnectionManager(registry));
clientConfig.property(ApacheClientProperties.SSL_CONFIG, sslConfig);
ApacheConnectorProvider connector = new ApacheConnectorProvider();
clientConfig.connectorProvider(connector);
return ClientBuilder.newBuilder().withConfig(clientConfig).build();
}
Upvotes: 4