Kris Swat
Kris Swat

Reputation: 1006

Websphere - Spring Integration SSL issue

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

Answers (2)

Kris Swat
Kris Swat

Reputation: 1006

https://developer.ibm.com/answers/questions/394270/im-using-an-apache-httpclient-to-make-an-outbound/

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

Alaine
Alaine

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

Related Questions