pythoniesta
pythoniesta

Reputation: 317

Calling a SOAP service requiring certificate using Nodejs

Nodejs SOAP client throwing error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames:

I am trying to call a SOAP service using soap in nodejs. However I am getting error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: IP: XXX.XXX.XXX.XXX is not in the cert's list:. I am new to nodejs and not sure how to call a SOAP service which requires certificate from nodejs. Other ways to call SOAP services requiring certificates in Nodejs are also welcome.

var url = "https://soapserviceurl?wsdl";

soap.createClient(url, function (err, client) { 
    if (err) {
        console.log("Error Occurred!!");
        console.log(err);       
    }
    else {
        console.log(client.describe());
    }
});

Upvotes: 1

Views: 11048

Answers (2)

Victor Rodniansky
Victor Rodniansky

Reputation: 513

please try

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" //this is insecure 
Or:

var soap = require('soap'),
        request = require('request'),
        fs = require('fs');

    var url = "https://soapserviceurl?wsdl";
    
    var req = request.defaults({
       strictSSL: false
    });

    soap.createClient(url, { 
            request : req
    }, function(err, client) {
        //your code
    });

Or:

soap.createClient(url, { 
            request : req,
            wsdl_options: {
            cert: fs.readFileSync('cert/cert.pem'), //path to pem
            key: fs.readFileSync('cert/cert.key'),   //path to private key
            rejectUnauthorized: false
        }
    }, function(err, client) {
        //your code
});

Upvotes: 5

simplegamer
simplegamer

Reputation: 213

The answer above doesn't work anymore because as of SOAP as of v0.40.0, it uses Axios for web requests, and not the request package. I couldn't find a recent answer for this and I spent a while figuring it out.

See in the documentation:

request (Object): Override the default request module (Axios as of v0.40.0).

wsdl_options (Object): Set options for the request module on WSDL requests. If using the default request module, see Request Config | Axios Docs.

Based on the link above and instructions like these https://smallstep.com/hello-mtls/doc/client/axios, this is the new way to do it:

First, so the WSDL endpoint is fetched with authentication, get the client like this:

import soap from 'soap';
import fs from 'fs';
import https from 'https';

const client = await soap.createClientAsync(api_url, {
    wsdl_options: {
        httpsAgent: new https.Agent({
            key: fs.readFileSync('personal.key'),
            cert: fs.readFileSync('personal.cert'),
        }),
    }
});

The key difference is that instead of passing cert and key in wsdl_options, you have to pass a new https.Agent with the cert and key.

Next, before making any call, ensure they are also called with certificate authentication:

client.setSecurity(new soap.ClientSSLSecurity('personal.key', 'personal.cert'));

Upvotes: 0

Related Questions