JaxB not Unmarshalling due to SSL error on cloud foundry?

微笑、不失礼 提交于 2021-01-04 04:30:54

问题


I have an web application, Using thymeleaf, springboot, angularjs, and oracle sql developer db.

Locally I am able to connect and get values from oracle. But when I push my application to cloud foundry, I am getting status=500.

ERROR

The url that I am unmarshalling has a untrusted certificate ("Your connection is not secured)". I added cacerts into my jvm, which allowed it to work locally. but I believe I need to add the cacerts into cloud foundry. How would I be able to do so?

SSL error

 ERR java.net.ConnectException: Connection timed out  
 ERR at java.net.PlainSocketImpl.socketConnect(Native Method)  
 ERR at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)  
 ERR at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)  
 ERR at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)  
 ERR at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)  
 ERR at java.net.Socket.connect(Socket.java:589)  
 ERR at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:668)  
 ERR at sun.net.NetworkClient.doConnect(NetworkClient.java:180)  
 ERR at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)  
 ERR at sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:173)  
 ERR at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:367)  
 ERR at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)  
 ERR at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264)  
 ERR at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)  
 ERR at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1105)  
 ERR at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)  
 ERR at rest.springframework.controllers.IndexController.getDetails(IndexController.java:59)  
 ERR at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
 ERR at java.lang.reflect.Method.invoke(Method.java:498)  
 ERR at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:999)  

ERR at rest.springframework.jaxb.JAXSample.readXML(JAXSample.java:34)

Reason

I removed jaxB unmarshalling from my application and uploaded into cloud foundry and I was did not get status=500. How can I add SSL to prevent this from happening?

JaxB Sample

public deviceCert readXML(String MAC) throws MalformedURLException {
  results customer = null;
  deviceCert dcert = null;
  String APPKEY = "Production";

  try {
      JAXBContext jaxbContext  = JAXBContext.newInstance(results.class);
      //line 34 is below VV.
      URL url = new URL("https://untrusted.page.that.I.Am/unmarshalling" + "?mac=" + MAC + "&app_key=" + APPKEY);

      HttpURLConnection http = (HttpURLConnection) url.openConnection(); 

      http.addRequestProperty("User-Agent", "Mozilla/4.76"); 
      InputStream is = http.getInputStream();
      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
      customer = (results) jaxbUnmarshaller.unmarshal(is);

      List<deviceCert> dcerts = customer.getDcerts();
      dcert = dcerts.get(0);

Found related link here

I followed CF CLI SSL But that did not do the trick.

Attempt

  1. Created folders resources/config/truststore in my application.
  2. Added Cert.cer into truststore folder.
  3. Pushed app to cloud foundry.
  4. cf set-env my-app JAVA_OPTS '-Djavax.net.ssl.TrustStore=classpath:resources/config/truststore'

Same error nothings changed.

Attempt 2

 <dependency>
  <groupId>io.pivotal.spring.cloud</groupId>
  <artifactId>cloudfoundry-certificate-truster</artifactId>
  <version>1.0.1.RELEASE</version>
 </dependency>
  1. added dependency

  2. Repackaged app, upload to cf.

  3. Added environment variable on cloud foundry

    CF_TARGET=https://api.my-cf-domain.com

               //url of my secured/untrusted page
    

Github example

New StackTrace error

ERR at java.util.concurrent.FutureTask.get(FutureTask.java:205)
ERR at io.pivotal.springcloud.ssl.SslCertificateTruster.getUntrustedCertificateInternal(SslCertificateTruster.java:90)
ERR at io.pivotal.springcloud.ssl.SslCertificateTruster.getUntrustedCertificate(SslCertificateTruster.java:66)
ERR at io.pivotal.springcloud.ssl.CloudFoundryCertificateTruster.trustCertificatesInternal(CloudFoundryCertificateTruster.java:44)
ERR at io.pivotal.springcloud.ssl.CloudFoundryCertificateTruster.trustCertificates(CloudFoundryCertificateTruster.java:32)
ERR at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:420)
ERR at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:403)
ERR at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:394)
ERR at org.springframework.boot.SpringApplication.initialize(SpringApplication.java:261)
ERR at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:237)
ERR at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)
ERR at rest.springframework.SpringBootWebApplication.main(SpringBootWebApplication.java:13)
ERR at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
ERR at java.lang.reflect.Method.invoke(Method.java:498)
ERR at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
ERR at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
ERR at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)

Why does this work find locally but not on the cloud?


回答1:


There are a number of ways to add a CA cert to your container:
https://discuss.pivotal.io/hc/en-us/articles/223454928-How-to-tell-application-containers-running-Java-apps-to-trust-self-signed-certs-or-a-private-internal-CA

The easiest one is probably to point the Java VM to a cacert file you bundle in your app, using cf set-env <app> JAVA_OPTS '-Djavax.net.ssl.TrustStore=classpath:resources/config/truststore' or with the "env" attribute in your app manifest.




回答2:


If you control your CloudFoundry platform then you can use the following approach::

1) Add certs via ops manager for PCF or via bosh http://bosh.io/docs/trusted-certs.html

2) Configure buildpack to use custom certificate trust store.

cf set-env app JBP_CONFIG_CONTAINER_CERTIFICATE_TRUST_STORE ‘{enabled: true}'

Links:

https://docs.cloudfoundry.org/buildpacks/java/bosh_custom_trusted_certs.html

https://github.com/cloudfoundry/java-buildpack/blob/master/README.md#configuration-and-extension




回答3:


Fist you have to create jks file for downloaded certificate. You can find keytool from JDK bin.

keytool -importcert -file "your.cer" -keystore your.jks -alias "testAlias"

Add your.jks file as a resource in spring-boot project.

set path and password of certificate store using configuration in application.properties eg:

your.ssl.trust-store = your.jks
your.ssl.trust-password = changeit

Load it from application startup.

Eg:

public class LoadSSLTrustStore implements CommandLineRunner{


       @Value("${your.ssl.trust-store}")
        private  String keyUrl;
       @Value("${your.ssl.trust-password}")
       private  String keyPassword;
    @Override
    public void run(String... arg0) throws Exception {
        try{
            System.setProperty("javax.net.ssl.trustStore",CustomerMasterServiceApplication.class.getClassLoader().getResource(keyUrl).getFile());
            System.setProperty("javax.net.ssl.trustStorePassword",keyPassword);

        }catch(Exception e){
            LOGGER.error("Error in loading SSL trusted key store for Connect to GCIN service",e);
        }

    }

} 

Related question

Add SSL keystore file to java trusted store for HTTP Client request on PCF (Cloud Foundry)



来源:https://stackoverflow.com/questions/42399137/jaxb-not-unmarshalling-due-to-ssl-error-on-cloud-foundry

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!