如何修改node-soap的时间戳有效期与wsu前缀?
如何在不fork node-soap的情况下修改WSSecurityCert的时间戳有效期与前缀
问题场景
使用node-soap的WSSecurityCert调用SOAP服务时,服务要求时间戳满足两个条件:
- 有效期为5分钟(当前库硬编码为10分钟)
- 所有时间戳相关元素带
wsu前缀(当前生成的XML无前缀)
尝试在securityOptions中添加created/expires参数无效,且担心修改请求发送前的XML会导致签名失效。
现有代码
const client = await soap.createClientAsync(url); const securityOptions = { hasTimeStamp: true, } const wsSecurity = new soap.WSSecurityCert(PRIVATE_KEY, PUBLIC_CERT, '', securityOptions); client.setSecurity(wsSecurity); const result = await client.method(args);
当前生成的时间戳XML
<Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" Id="_1"> <Created>2024-05-08T13:20:09Z</Created> <Expires>2024-05-08T13:30:09Z</Expires> </Timestamp>
目标时间戳XML
<wsu:Timestamp wsu:Id="TS-7C14BF4AA3E26845E015637928928701"> <wsu:Created>2024-05-08T13:20:09Z</wsu:Created> <wsu:Expires>2024-05-08T13:25:09Z</wsu:Expires> </wsu:Timestamp>
解决方案:重写WSSecurityCert的时间戳生成方法
不需要fork库,通过猴子补丁重写WSSecurityCert原型上的generateTimestamp方法,直接在签名生成前修改时间戳的逻辑,确保签名有效性。
具体实现代码
const soap = require('soap'); // 重写WSSecurityCert的generateTimestamp方法,自定义有效期与前缀 soap.WSSecurityCert.prototype.generateTimestamp = function (id) { const created = new Date(); // 设置5分钟有效期 const expires = new Date(created.getTime() + 5 * 60 * 1000); // 生成符合目标格式的ID(可根据需求调整) const timestampId = id || `TS-${Date.now()}`; // 生成带wsu前缀的XML片段 return ` <wsu:Timestamp wsu:Id="${timestampId}"> <wsu:Created>${this.formatDate(created)}</wsu:Created> <wsu:Expires>${this.formatDate(expires)}</wsu:Expires> </wsu:Timestamp> `.trim(); }; // 原有业务逻辑 (async () => { const client = await soap.createClientAsync(url); const securityOptions = { hasTimeStamp: true, }; const wsSecurity = new soap.WSSecurityCert(PRIVATE_KEY, PUBLIC_CERT, '', securityOptions); // 为Security头部添加wsu命名空间声明 wsSecurity.xmlns['wsu'] = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'; client.setSecurity(wsSecurity); const result = await client.method(args); })();
说明
- 签名有效性保障:
generateTimestamp是WSSecurityCert生成签名流程中调用的方法,修改后的时间戳会直接参与签名计算,不会出现事后修改XML导致签名不匹配的问题。 - 命名空间处理:通过给
wsSecurity.xmlns添加wsu命名空间,生成的SOAP请求头部会自动包含该命名空间的声明,避免XML解析错误。 - ID格式自定义:代码中生成的ID格式为
TS-时间戳,可根据服务要求调整为其他格式。
内容的提问来源于stack exchange,提问作者Octavian
相关产品推荐
相关产品推荐

