javascript - 如何: wsse soap request in javascript (node)

标签 javascript node.js soap

我需要从 Wix.com 平台上的 Node 服务器与soap:xml API 进行通信。该 API 需要 Soap WSSE 身份验证。

我可以向 SoapUI 中的端点发送经过身份验证的请求,但未能在 Wix Node 平台上成功执行此操作。

Wix 仅具有可安装的 Node 包子集,并且 XMLHttpRequest 在其环境中不可用。

我尝试过node-soap,但收到错误,表明该包在 Wix Node 平台上可能存在错误。

我发现自己使用 Node “请求”( https://www.npmjs.com/package/request ) 包并尝试推出自己的解决方案来解决缺少的 Node 包和环境限制。

目前我可以向端点发送请求,但是我收到以下响应;

<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Access denied</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>\n

这表明我没有正确进行身份验证。

正如我所提到的,我已经能够通过 SoapUI 成功发送请求并接收预期响应。所以 API 正在运行,我怀疑是我的实现出了问题。老实说,我过去曾使用过 REST/JSON API,自从我使用 SOAP API 以来已经有很长一段时间了,我记得当时就感到非常痛苦!

我的请求代码

import request from 'request';
import {wsseHeaderAssoc} from 'backend/wsse';

export function getLocationID() {

    let apiUsername = "username";
    let apiPassword = "password";
    let apiURL = "https://api.serviceprovider.com/wsdl";

    // WSSE authentication header vars
    let wsse = wsseHeaderAssoc(apiUsername, apiPassword);
    let wsseUsername = wsse["Username"];
    let wssePasswordDigest = wsse["PasswordDigest"];
    let wsseCreated = wsse["Created"];
    let wsseNonce = wsse["Nonce"];

    let xml =
    `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:masked:api">`+
        `<soapenv:Header>`+
            `<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">`+
                `<wsse:UsernameToken wsu:Id="UsernameToken-19834957983507345987345987345">`+
                    `<wsse:Username>${wsseUsername}</wsse:Username>`+
                    `<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">${wssePasswordDigest}</wsse:Password>`+
                    `<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">${wsseNonce}</wsse:Nonce>`+
                    `<wsu:Created>${wsseCreated}</wsu:Created>`+
                `</wsse:UsernameToken>`+
            `</wsse:Security>`+
        `</soapenv:Header>`+
        `<soapenv:Body>`+
        ...
        `</soapenv:Body>`+
    `</soapenv:Envelope>`

    var options = {
    url: apiURL,
    method: 'POST',
    body: xml,
    headers: {
        'Content-Type':'text/xml;charset=utf-8',
        'Accept-Encoding': 'gzip,deflate',
        'Content-Length':xml.length,
        'SOAPAction':"https://api.serviceprovider.com/wsdl/service",
        'User-Agent':"Apache-HttpClient/4.1.1 (java 1.5)",
        'Connection':"Keep-Alive"
    }
    };

    let callback = (error, response, body) => {
    if (!error && response.statusCode == 200) {
        console.log('Raw result ', response);

        // If you ever get this working, do some mad magic here
    };
    console.log('Error ', response);  
    };

}

我正在使用 wsse-js ( https://github.com/vrruiz/wsse-js/blob/master/wsse.js ) 生成密码摘要、创建日期时间戳和 Nonce,因为 Node wsse 包 ( https://www.npmjs.com/package/wsse ) 在 Wix 上不可用。我已经阅读了代码,并且根据我在其他地方读到的内容,这看起来是一个很好的实现。

我做了一个小补充,以在关联数组中返回生成的详细信息;

export function wsseHeaderAssoc(Username, Password) {
    var w = wsse(Password);
    var wsseAssoc = [];
    wsseAssoc["Username"] = Username;
    wsseAssoc["PasswordDigest"] = w[2];
    wsseAssoc["Created"] = w[1];
    wsseAssoc["Nonce"] = w[0];
    return wsseAssoc;
}

如前所述,我收到的回复是:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>Access denied</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>\n

我期待一个有效的 SOAP XML 响应。

我使用了 SoapUI 中的原始 xml 结构和 header 来构建它,一切看起来都很好,我真的不知道哪里出了问题。

我希望任何人都可以向我提出任何建议 - 我已经花了 2 天时间尝试暴力破解,我需要帮助。

最佳答案

您可以使用soap 包中的WSSecurity 方法。他们的自述文件中的一个示例:

  var options = {
    hasNonce: true,
    actor: 'actor'
  };
  var wsSecurity = new soap.WSSecurity('username', 'password', options)
  client.setSecurity(wsSecurity);

关于javascript - 如何: wsse soap request in javascript (node),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57113648/

相关文章:

java - 如何将javascript变量传递到jsp页面中的java代码片段中

javascript - 使用 Javascript Do while 循环降低星号

javascript - 获取临时 AWS 凭证的推荐方法? AWS.config 还是 STS?

javascript - 查询指针数组 Mongoose Node.js

xml - 在 GOLANG 中使用带有命名空间的 SOAP

javascript - 准备好的语句未在带有 mssql 的 Node js 中执行

javascript - 使用 jQuery 随机显示/隐藏图像

mysql - 使用 MySQL 作为 session 存储时的重定向问题

java - 使用Jsp发送 SOAP 信封

java - 为第三方创建/公开 Web 服务的设计决策