How to add client certificate in the htttp plugin

Questions and answers on developing, deploying and using plugins and JavaBeans

How to add client certificate in the htttp plugin

Postby Juan Etec » Tue Nov 14, 2023 3:34 pm

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
Un Saludo

Juan Ramírez
Juan Etec
 
Posts: 64
Joined: Mon Apr 20, 2009 8:23 pm
Location: Gran Canaria - Spain

Re: How to add client certificate in the htttp plugin

Postby Joas » Thu Nov 16, 2023 11:34 am

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:
Code: Select all
/**
* @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.
Joas de Haan
Yield Software Development
Need help on your project? yieldsd.com
User avatar
Joas
Site Admin
 
Posts: 842
Joined: Mon Mar 20, 2006 4:07 pm
Location: Leusden, NL

Re: How to add client certificate in the htttp plugin

Postby Juan Etec » Fri Nov 17, 2023 10:38 am

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:
Un Saludo

Juan Ramírez
Juan Etec
 
Posts: 64
Joined: Mon Apr 20, 2009 8:23 pm
Location: Gran Canaria - Spain


Return to Plugins and Beans

Who is online

Users browsing this forum: No registered users and 1 guest

cron