Introducció
Utilització d’un client axis per consumir un webservice per https.
.
Descripció i solució del problema
Generar les clases d’axis mitjançant ant.
Utilitzar l’url sense securitzar (http)
<property name="wsdl.url" value="http://domini/AppJava/ws/documentService?wsdl" />
<axis-wsdl2java output="${sourceDir}/auto-generated" testcase="false" verbose="${verboseProp}" url="${wsdl.url}" debug="${verboseProp}" all="true" />
Crear una clase que extengui de JSSESocketFactory
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Hashtable;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.axis.components.net.JSSESocketFactory;
import org.apache.axis.components.net.SecureSocketFactory;
import org.apache.commons.lang.StringUtils;
/**
* Custom SSL socket factory to use our integrated keystore.
*
* Based loosely on org.apache.axis.components.net.SunJSSESocketFactory
*/
public class DTSSLSocketFactory extends JSSESocketFactory implements SecureSocketFactory {
public DTSSLSocketFactory(Hashtable attributes) {
super(attributes);
}
/* local keystore password */
private static String MY_KEYSTORE_PASSWORD = "12345678";
/* local keystore file (contains the self-signed certificate from the server */
private static String RESOURCE_PATH_TO_KEYSTORE = "pre_electia.jks";
/**
* Read the keystore, init the SSL socket factory
*
* This overrides the parent class to provide our SocketFactory
* implementation.
*
* @throws IOException
*/
protected void initFactory() throws IOException {
try {
SSLContext context = getContext();
sslFactory = context.getSocketFactory();
} catch (Exception e) {
if (e instanceof IOException) {
throw (IOException) e;
}
throw new IOException(e.getMessage());
}
}
/**
* Gets a custom SSL Context. This is the main working of this class. The
* following are the steps that make up our custom configuration:
*
* 1. Open our keystore file using the password provided 2. Create a
* KeyManagerFactory and TrustManagerFactory using this file 3. Initialise a
* SSLContext using these factories
*
* @return SSLContext
* @throws WebServiceClientConfigException
* @throws Exception
*/
protected SSLContext getContext() throws Exception {
char[] keystorepass = MY_KEYSTORE_PASSWORD.toCharArray();
if (StringUtils.isBlank(new String(keystorepass)))
throw new Exception("Could not read password for configured keystore!");
// InputStream keystoreFile = this.getClass().getResourceAsStream(RESOURCE_PATH_TO_KEYSTORE);
InputStream keystoreFile = Thread.currentThread().getContextClassLoader().getResourceAsStream(RESOURCE_PATH_TO_KEYSTORE);
if (keystoreFile == null)
throw new Exception("Could not read the configured keystore file at " + RESOURCE_PATH_TO_KEYSTORE);
try {
// create required keystores and their corresponding manager objects
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(keystoreFile, keystorepass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keystorepass);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// congifure a local SSLContext to use created keystores
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
// sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
return sslContext;
} catch (Exception e) {
throw new Exception("Error creating context for SSLSocket!", e);
}
}
}
Creació del jks del certificat del domini
Exportar la clau pública del domini com format PEM
Amb l’eina keytoolui crear un magatzem .jks i donar-li un pwd
Importar la clau pública del servidor (importar el pem cap al magatzen .jks)
Executar el servei
WSDocumentBoLocator locator = new WSDocumentBoLocator();
locator.setWSDocumentBoHttpPortEndpointAddress("https://domini/AppJava/ws/documentServicel");
AxisProperties.setProperty("axis.socketSecureFactory", "DTSSLSocketFactory_nom de la clase feta en el punt anterior");
WSDocumentBoPortType service = locator.getWSDocumentBoHttpPort();
Referències