You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中SOAP请求同时配置TLS与WSS双重安全的问题咨询

解答

node-soap 库的 client.setSecurity() 方法默认仅支持绑定一个安全实例,重复调用会直接覆盖前序配置,因此先后传入TLS安全实例和WSS安全实例必然会导致其中一个失效。

实现方案

方案1:请求层注入TLS配置(最简单,推荐)

TLS属于传输层安全,不需要通过setSecurity方法配置,直接将PFX证书参数注入HTTP请求配置即可,setSecurity仅用来配置WSS消息层安全。
注意旧版本node-soap在createClient顶层options中传入的pfx、passphrase仅会用于拉取WSDL文件的请求,不会自动继承到后续业务SOAP请求中,需要明确指定请求配置,必要时可以重写httpClient方法兜底:

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

// 预加载所有证书文件
const tlsPfx = fs.readFileSync("[cert-tls.p12]");
const tlsPassphrase = "[password]";
const wssPrivateKey = fs.readFileSync("[privateKey.pem]");
const wssPublicKey = fs.readFileSync("[publickey.pem]");
const wssPassphrase = "[password]";

const clientOptions = {
  endpoint: endpoint,
  // 拉取WSDL阶段的TLS配置
  wsdl_options: {
    pfx: tlsPfx,
    passphrase: tlsPassphrase
  },
  // 后续业务请求的默认TLS配置
  requestOptions: {
    pfx: tlsPfx,
    passphrase: tlsPassphrase
  }
};

soap.createClient(url, clientOptions, function (err, client) {
  if (err) {
    console.log("客户端创建失败", err);
    return;
  }
  // 仅配置WSS消息层安全
  const wssSecurity = new soap.WSSecurityCert(wssPrivateKey, wssPublicKey, wssPassphrase);
  client.setSecurity(wssSecurity);

  // 兜底:兼容部分版本requestOptions不生效的问题,强制给所有请求注入TLS配置
  const originRequest = client.httpClient.request;
  client.httpClient.request = function(reqUrl, data, callback, extraHeaders, extraOptions) {
    extraOptions = extraOptions || {};
    extraOptions.pfx = tlsPfx;
    extraOptions.passphrase = tlsPassphrase;
    return originRequest.call(this, reqUrl, data, callback, extraHeaders, extraOptions);
  };

  client.ObslugaRecepty.ObslugaReceptyWS.zapisPakietuRecept(
    recepta_podpisana,
    function (err, result) {
      if (err) {
        console.log("请求失败", err);
        return;
      }
      console.log("请求成功", result);
    }
  );
});

方案2:自定义组合安全类

如果要完全遵循setSecurity的配置逻辑,可以自定义一个组合安全类,内部同时调用TLS和WSS两个安全实例的对应方法,再传入setSecurity:

// 组合安全类
class CombinedSecurity {
  constructor(tlsSec, wssSec) {
    this.tlsSec = tlsSec;
    this.wssSec = wssSec;
  }
  // 给请求添加配置项(TLS逻辑在这里执行)
  addOptions(options) {
    this.tlsSec.addOptions(options);
    this.wssSec.addOptions(options);
  }
  // 生成SOAP安全头XML(WSS逻辑在这里执行)
  toXML() {
    return this.wssSec.toXML();
  }
  // 添加请求头
  addHeaders(headers) {
    this.wssSec.addHeaders(headers);
  }
}

// 使用示例
soap.createClient(url, {}, function(err, client) {
  if (err) throw err;
  const tlsSec = new soap.ClientSSLSecurityPFX(tlsPfx, tlsPassphrase);
  const wssSec = new soap.WSSecurityCert(wssPrivateKey, wssPublicKey, wssPassphrase);
  // 传入组合后的安全实例,不会互相覆盖
  client.setSecurity(new CombinedSecurity(tlsSec, wssSec));
  // 后续业务调用逻辑不变
})

关键说明

  • TLS/SSL是HTTPS握手阶段的传输层校验,WS-Security是SOAP报文层面的消息层校验,两者作用层级不同,不存在互斥,只是node-soap默认没有提供多安全实例绑定能力,手动组合逻辑即可。
  • 初始代码中PFX配置不生效的核心原因是旧版本库的配置隔离:顶层options中的证书配置仅用于WSDL拉取请求,不会透传给后续业务接口请求。

内容的提问来源于stack exchange,提问作者Damian Łaguna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:18:43