Reputation: 1006
Our Spring Integration application runs on Websphere. It is a client to an SSL external service.
I've imported a certificate using Retrive from port [into default trust store], giving host and 443 port. Enabled tracing on WebSphere and it seems it is looking at cacert file and not trust.p12.
[18-2-19 13:44:59:154 CET] 00000063 SystemOut O 2019-02-18 13:44:59.153 INFO 30426 --- [ver.startup : 0] pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]
[18-2-19 13:44:59:826 CET] 00000063 SystemOut O keyStore is: /srv/opt/IBM/WebSphere/AppServer/java/8.0/jre/lib/security/cacerts
Code:
public class PreemptiveMessageSender extends HttpComponentsMessageSender {
@Autowired
private Environment env;
private String host;
private String userId;
private String password;
public PreemptiveMessageSender() {
super();
}
public PreemptiveMessageSender(HttpClient httpClient) {
super(httpClient);
}
@Override
protected HttpContext createContext(URI uri) {
HttpHost targetHost = new HttpHost(host, 443, "https");
String decryptedPassword = getDecryptedPassword();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(userId, decryptedPassword));
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
// Add AuthCache to the execution context
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
return context;
}
private String getDecryptedPassword() {
BasicTextEncryptor textEncrypt = new BasicTextEncryptor();
textEncrypt.setPassword(env.getProperty("KEY_PASSWORD"));
return textEncrypt.decrypt(password);
}
@Override
public WebServiceConnection createConnection(URI uri) throws IOException {
HttpPost httpPost = new HttpPost(uri);
if (isAcceptGzipEncoding()) {
httpPost.addHeader(HttpTransportConstants.HEADER_ACCEPT_ENCODING,
HttpTransportConstants.CONTENT_ENCODING_GZIP);
}
HttpContext httpContext = createContext(uri);
return new CustomHttpComponentsConnection(getHttpClient(), httpPost, httpContext);
}
...
}
Error:
"exception": "org.springframework.ws.client.WebServiceIOException", "message": "I/O error: com.ibm.jsse2.util.h: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is: \n\tjava.security.cert.CertPathValidatorException: The certificate issued by CN=ODC Test Root CA - G1, O=ODC Test, C=TU is not trusted; internal cause is: \n\tjava.security.cert.CertPathValidatorException: Certificate chaining error; nested exception is javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is: \n\tjava.security.cert.CertPathValidatorException: The certificate issued by CN=ODC Test Root CA - G1, O=ODC Test, C=TU is not trusted; internal cause is: \n\tjava.security.cert.CertPathValidatorException: Certificate chaining error",
Question: Is this problem with Spring Integration using the java cacert? How to make it use the trust store of WebSphere?
Upvotes: 0
Views: 1362
Reputation: 1006
HttpClient theClient = HttpClientBuilder.create().useSystemProperties().addInterceptorFirst(new RemoveSoapHeadersInterceptor()).build();
private static class RemoveSoapHeadersInterceptor implements HttpRequestInterceptor {
@Override
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
if (request instanceof HttpEntityEnclosingRequest) {
if (request.containsHeader(HTTP.TRANSFER_ENCODING)) {
request.removeHeaders(HTTP.TRANSFER_ENCODING);
}
if (request.containsHeader(HTTP.CONTENT_LEN)) {
request.removeHeaders(HTTP.CONTENT_LEN);
}
}
}
}
Upvotes: 0
Reputation: 439
I'll start with I don't know anything about Spring. But given the behavior you talk about it must be creating its own instance of the SSLContext. This will cause it to by pass WebSphere SSL settings. It must be doing something like SSLContext.getInstance() to create its own instance or it could be doing something like SSLContext.getDefault() which returns you the JDK's default SSLContext. Both will not get you a WebSphere SSLContext.
Upvotes: 0