How to add client certificate in the htttp plugin

Hi,
using the http plugins, is there any way to add client certificates?
I have done in postman adding myCertificate.pfx and my password, but I have no idea to develop it in servoy.

Thanks

This is not possible with the http plugin, but you can do it with the Apache http client using inline java.
I needed to do the same thing to call a couple of soap webservices, so I created a method for that.

Here a simplified version:

/**
 * @param {XML} xml
 * @param {String} url
 * @param {String} [certPath] The path of the certificate file
 * @param {String} [certPassword]
 * @param {*} [httpHeaders] for example: '{"Authorization":"Basic abcdef","SOAPAction":"SOAPACTION"}'
 * @param {String} [username] for basic authentication
 * @param {String} [password]
 *
 * @return {String}
 *
 * @properties={typeid:24,uuid:"86F518A3-472C-4F6B-9B70-2B6D3749AC37"}
 */
function callSoap(xml, url, certPath, certPassword, httpHeaders, username, password) {

	//Save references to java classes
	var FileInputStream = Packages.java.io.FileInputStream;
	var StandardCharsets = Packages.java.nio.charset.StandardCharsets;
	var KeyStore = Packages.java.security.KeyStore;
	var SecureRandom = Packages.java.security.SecureRandom;
	var Base64 = Packages.java.util.Base64;

	var KeyManagerFactory = Packages.javax.net.ssl.KeyManagerFactory;
	var SSLContext = Packages.javax.net.ssl.SSLContext;

	var HttpPost = Packages.org.apache.http.client.methods.HttpPost;
	var HttpClients = Packages.org.apache.http.impl.client.HttpClients;
	var StringEntity = Packages.org.apache.http.entity.StringEntity;
	var EntityUtils = Packages.org.apache.http.util.EntityUtils;
	var ByteArrayOutputStream = Packages.java.io.ByteArrayOutputStream;

	//Create http client
	var httpClient;

	if (certPassword && certPath) {
		//Add client certificate
		certPassword = new java.lang.String(certPassword);
		var inputStream = new FileInputStream(certPath);
		var kmf = KeyManagerFactory.getInstance("SunX509");
		var keyStore = KeyStore.getInstance("PKCS12", "SunJSSE");
		keyStore.load(inputStream, certPassword.toCharArray());
		kmf.init(keyStore, certPassword.toCharArray());

		var ctx = SSLContext.getInstance("SSL");
		ctx.init(kmf.getKeyManagers(), null, new SecureRandom());

		httpClient = HttpClients.custom().setSSLContext(ctx).build();
		//For older version of httpclient: httpClient = HttpClients.custom().setSslcontext(ctx).build();
	} else {
		httpClient = HttpClients.createDefault();
	}

	//Create request
	var request = new HttpPost(url);

	//Set default headers
	request.setHeader("Accept", "text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2");
	request.setHeader("Content-Type", "text/xml; charset=UTF-8");
	request.setHeader("Accept-Encoding", "gzip,deflate");
	request.setHeader("MIME-Version", "1.0");

	//Add basic authentication
	if (username && password) {
		var up = new java.lang.String(username + ":" + password);
		var authentication = new java.lang.String(Base64.getEncoder().encode(up.getBytes(StandardCharsets.UTF_8)));
		request.setHeader("Authorization", "Basic " + authentication);
	}

	//Add http headers to the request
	if (httpHeaders) {
		for (var i in httpHeaders) {
			request.setHeader(i, httpHeaders[i]);
		}
	}

	//Set the xml as body content of the post
	request.setEntity(new StringEntity(xml));

	//Output request as a string in developer
	if (application.isInDeveloper()) {
		var requestHeaders = request.getRequestLine() + "\n" + (request.getAllHeaders().join("\n"));

		var outputStream = new ByteArrayOutputStream();
		request.getEntity().writeTo(outputStream);
		var strMsg = requestHeaders + "\n" + outputStream.toString();
		application.output("====REQUEST START====" + utils.dateFormat(application.getServerTimeStamp(), "yyyy-MM-dd HH:mm:ss") + "\n" + strMsg + "\n====REQUEST END====");
	}

	//Execute request
	var response = httpClient.execute(request);

	//Handle response
	var entity = response.getEntity();

	if (entity != null) {
		//Save the reponse body as string
		var responseString = EntityUtils.toString(entity, "UTF-8");

		if (responseString) {
			//Get rid of the soap envelope, just get the body xml
			var bodyMatch = responseString.replace(/\n/g, "").match(/<.*:body[^>]*>(.*)<\/.*:body>/i);

			if (bodyMatch) {
				return bodyMatch[1];
			} else {
				return responseString;
			}
		}
	}
	return null;
}

To run this, you need to download the httpclient and httpcore jars and put them in your plugins folder.

Hi Joas,
thanks for your reply.
Is really helpful.
I didn’t know that it doesn’t work, with the http plugin.
I owe you a couple of beers in Gran Canaria. :lol: