Output Error while setting up WSSecurity with node-soap

1.3k Views Asked by At

First, thank you for your time.

After looking everywhere and debugging this for 2 days, I gave up lol

I'm trying to create a webservice and a client,

When I do not set the WSSecurity, everything works as expected and I get the result back, either through the code or POSTMAN. ✅

But, once I enable the WSSecurity, then I keep getting the error ❌:

TypeError: Cannot read property 'output' of undefined and nothing back;

Here is a brief idea about my set up,

I have to different machines connected to the same network: Machine 1 has : server.js Machine 2 has : client.js

I'm using the NODE-SOAP library The documention on git is not that complete, I looked everywhere, but does not seems that someone has faced this problem before.

My private and public keys, are both good.

server.js

let http = require('http');
let https = require('https');
let soap = require('soap');
let express = require('express');
let bodyParser = require('body-parser');
let fs = require('fs');
var port = 8080;

var options = {
    key: fs.readFileSync('ssl/server-key.pem'),
    cert: fs.readFileSync('ssl/server-crt.pem'),
     ca: fs.readFileSync('ssl/ca-crt.pem'),
};

let myService = {
    Calculate_Service: {
        Calculate_Port: {
            sum : function(args) {
                var n = args.a + args.b;
            },
            multiply: function(args, callback) {
                try{
                 console.log('WOHOOOO!!');
                 let n = args.a * args.b;
                callback({
                    multiplicationResult : n
                });
                }catch (e) {
                    console.log(e);
                }

            },
        }
    }
}


let xml = require('fs').readFileSync('wsdls/myservice.wsdl', 'utf8');

async function main() {
    var app = express();
    app.use(bodyParser.raw({
        type: function () {
            return true;
        }, limit: '5mb'
    }));
    app.listen(port, function () {
        console.log("Express server listening on port " + port);
        soap.listen(app, '/calculatorService', myService, xml);
    });
}


main().catch((err) => {
    console.error(err);
    return process.exit(-1);
});

client.js

let soap = require('soap');
let fs = require('fs');

let url = 'http://192.168.1.3:8080/calculatorService?wsdl';

let privateKey = fs.readFileSync("ssl-cert/printcard.key");
let publicKey = fs.readFileSync("ssl-cert/printcard.csr");
var password = null; // optional password
var wsSecurity = new soap.WSSecurityCert(privateKey, publicKey, password);

let args = {
    a: '4',
    b: '4'
    };

soap.createClientAsync(url).then((client) => {
    client.setSecurity(wsSecurity);
    return  client.Calculate_Service.Calculate_Port.multiply(args,function(err, result, rawResponse, soapHeader, rawRequest) {
        console.log('-------------------rawRequest-------------------------');
        console.log('rawRequest');
        console.log(rawRequest);
        console.log('-----------------------------------------------------');
        console.log('-------------------rawResponse--------------------------');
        console.log(rawResponse);
        console.log('-----------------------------------------------------');
        console.log('RESULT');
        console.log(result);
    });
});

and here is my myservice.wsdl

<definitions name = "calculatorService"
             targetNamespace = "http://192.168.1.3:8080/HelloService?wsdl"
             xmlns = "http://schemas.xmlsoap.org/wsdl/"
             xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns = "http://192.168.1.3:8080/HelloService?wsdl"
             xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
             xmlns:wsp="http://www.w3.org/ns/ws-policy"
             xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
             xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
             xmlns:sp13="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200802"
             xmlns:wsaws="http://www.w3.org/2005/08/addressing">

    <message name = "multiplyRequest">
        <part name = "a" type = "xsd:string"/>
    </message>

    <message name = "multiplyResponse">
        <part name = "multiplicationResult" type = "xsd:string"/>
    </message>

    <portType name = "Calculate_PortType">
        <operation name = "multiply">
            <input message = "tns:multiplyRequest"/>
            <output message = "tns:multiplyResponse"/>
        </operation>
    </portType>

    <binding name = "Calculate_Binding" type = "tns:Calculate_PortType">
        <soap:binding style = "rpc"
                      transport = "http://schemas.xmlsoap.org/soap/http"/>
        <operation name = "multiply">
            <soap:operation soapAction = "multiply"/>
            <input>
                <soap:body
                        encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"
                        namespace = "urn:192.168.1.3:8080:calculatorService"
                        use = "encoded"/>
            </input>

            <output>
                <soap:body
                        encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"
                        namespace = "urn:192.168.1.3:8080:calculatorService"
                        use = "encoded"/>
            </output>
        </operation>
    </binding>

    <service name = "Calculate_Service">
        <documentation>WSDL File for HelloService</documentation>
        <port binding = "tns:Calculate_Binding" name = "Calculate_Port">
            <soap:address
                    location = "http://192.168.1.3:8080/calculatorService" />
        </port>
    </service>
</definitions>

THANKS AGAIN FOR TAKING THE TIME TO READ THIS!!!!

1

There are 1 best solutions below

0
On

I finally fixed this, that was actually a bug on node-soap, I committed the change to node-soap git rep.

Node-soap server.js files:

if (binding.style === 'rpc') {
      methodName = Object.keys(body)[0]; // REPLACE THIS
      methodName = (Object.keys(body)[0] === 'attributes' ? Object.keys(body)[1] : Object.keys(body)[0]); //BY THIS