我收到“验证消息安全性时发生错误”。来自我正在使用的 SOAP 服务。我怀疑这是因为签名引用不考虑包容性命名空间。
node-soap 库允许您像这样配置签名引用:
const options: IWSSecurityCertOptions = {
additionalReferences: [
// References go here...
'wsa:To',
],
};
const wsSecurity = new WSSecurityCert(privateKey, publicKey, password, options);
soapClient.setSecurity(wsSecurity);
这会产生一个签名参考,例如:
<ds:Reference URI="#_1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>
EG__REDACTED__hI=
</ds:DigestValue>
</ds:Reference>
但是,我需要签名的参考资料如下:
<ds:Reference URI="#_1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="soap foo bar" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>
x2Q__REDACTED__EI=
</ds:DigestValue>
</ds:Reference>
注意
InclusiveNamespaces
元素。这当然会改变摘要。
如何做到这一点?
我通读了node-soap文档和源代码,但没有找到任何东西。
node-soap 使用 xml-crypto,它有一个
inclusiveNamespacesPrefixList
选项。当实例化 SignedXml
类时,node-soap 不会公开这些选项,https://github.com/vpulim/node-soap/blob/master/src/security/WSSecurityCert.ts#L74,并且它添加签名引用时不提供选项,请参阅 https://github.com/vpulim/node-soap/blob/master/src/security/WSSecurityCert.ts#L181。
你必须编写自己的
WSSecurityCert
类并更改这些行:
强文本第 1 部分:将包含的命名空间添加到构造函数中
this.signer = new SignedXml(options?.signerOptions?.idMode, {
inclusiveNamespacesPrefixList: 'foo bar',
});
第 2 部分:更改
additionalReferences
的添加方式
for (const name of this.additionalReferences) {
const xpath = `//*[name(.)='${name}']`;
if (!(this.signer.references.filter((ref) => ref.xpath === xpath).length > 0)) {
this.signer.addReference(
xpath, // xpath
references, // transforms
undefined, // digestAlgorithm
undefined, // uri
undefined, // digestValue
'foo bar', // inclusiveNamespacesPrefixList
);
}
}
这将产生所需的结果。