Jul 24, 2010

Java Accessing WSDL via HTTPS SSL

For along time i tried to make it accessible as easy as HTTP, but i 've got trouble many times, i tried 6 different access mechanism to use this service.
and now i solved the problem with this :

String address = ServicePoint.WSDL_LOCATION.toString();
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
proxyFactory.setServiceClass(ServicePointPortType.class);
proxyFactory.setAddress(address);
ServicePointPortType client = (ServicePointPortType) proxyFactory.create();
configureSSLOnTheClient(client);


next, you can call client.getBSfromCELL(MAC); or other services.

private static void configureSSLOnTheClient(Object c) {
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(c);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
try {
TLSClientParameters tlsParams = new TLSClientParameters();
tlsParams.setDisableCNCheck(true);
KeyStore keyStore = KeyStore.getInstance("JKS");
String trustpass = "changeit";
File truststore = new File("/trgwimax/client.keystore");
keyStore.load(new FileInputStream(truststore), trustpass.toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(keyStore);
TrustManager[] tm = trustFactory.getTrustManagers();
tlsParams.setTrustManagers(tm);
truststore = new File("/trgwimax/client.keystore");
keyStore.load(new FileInputStream(truststore), trustpass.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, trustpass.toCharArray());
KeyManager[] km = keyFactory.getKeyManagers();
tlsParams.setKeyManagers(km);
FiltersType filter = new FiltersType();
filter.getInclude().add(".*_EXPORT_.*");
filter.getInclude().add(".*_EXPORT1024_.*");
filter.getInclude().add(".*_WITH_DES_.*");
filter.getInclude().add(".*_WITH_NULL_.*");
filter.getExclude().add(".*_DH_anon_.*");
tlsParams.setCipherSuitesFilter(filter);

httpConduit.setTlsClientParameters(tlsParams);
} catch (KeyStoreException kse) {
System.out.println("Security configuration failed with the following KSE: " + kse.getCause());
} catch (NoSuchAlgorithmException nsa) {
System.out.println("Security configuration failed with the following NSA: " + nsa.getCause());
} catch (FileNotFoundException fnfe) {
System.out.println("Security configuration failed with the following FNFE: " + fnfe.getCause());
} catch (UnrecoverableKeyException uke) {
System.out.println("Security configuration failed with the following UKE: " + uke.getCause());
} catch (CertificateException ce) {
System.out.println("Security configuration failed with the following CE: " + ce.getCause());
} catch (GeneralSecurityException gse) {
System.out.println("Security configuration failed with the following GSE: " + gse.getCause());
} catch (IOException ioe) {
System.out.println("Security configuration failed with the following IOE: " + ioe.getCause());
}

}

before running this script, you have to import key from server and register it on your local machine, It's mandatory, Java need to register the key as its certificate. Sometimes administrator just give you the key without certificate, so you need to convert it by yourself.

Remember that there are many certificate files on your machine but, the valid key is on $JAVA_HOME/jre/lib/security/cacerts so you need to add your key (after converted to certificate (PEM or CERT) to this file.

There are 3 default key parameters that you have to use to import it.
Key Type : default is JKS
Password : changeit
Alias : mykey, root, host-number such as 127.0.0.1-1

While you import the key, you need ensuring that your certificate file that you operate is the right one, it must be $JAVA_HOME/jre/lib/security/cacert

you may use keytool (portecle-1.5.zip) to export the JKS to PEM or CERT so you can add it to cacerts. The steps are :

1. use it as root

2. open file $JAVA_HOME/jre/lib/security/cacerts

3. import the JKS

4. sometimes you need to export it first to PEM or CERT

5. add the PEM or CERT into cacerts

6. save it.

some WSDL services are need to convert into String manually or just call getValue() before toString();
It's use to rid the xml elements that may still included.

i write it as my own note, so i don't need to make it later.
Read more ...