我使用了使用PasswordDigest身份验证的SOAP。 我使用了这个库:https://github.com/vpulim/node-soap
我使用nodejs版本v0.10.29在Debian上运行此代码并且它正常工作。
现在我需要让它在运行nodejs v6.6.0的Windows计算机上运行,而且它不再工作了。
我有以下消息:
无法对安全令牌进行身份验证或授权
我怀疑加密lib有问题,这段代码可能是:
"use strict";
var crypto = require('crypto');
exports.passwordDigest = function passwordDigest(nonce, created, password) {
// digest = base64 ( sha1 ( nonce + created + password ) )
var pwHash = crypto.createHash('sha1');
var rawNonce = new Buffer(nonce || '', 'base64').toString('binary');
pwHash.update(rawNonce + created + password);
return pwHash.digest('base64');
};
来自https://github.com/vpulim/node-soap/blob/master/lib/utils.js
答案 0 :(得分:1)
好的,所以这就是我解决它的方式:
SOAP库具有构建WSSE安全头的功能,该头位于soap / lib / security / templates / WSSecurity.js中。
问题是它放在标题中的UsernameToken与soapUI正在使用的实际结果(在我的示例中)不一致。
原始代码:
"<wsse:UsernameToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"SecurityToken-" + created + "\">
虽然我需要的是:
<wsse:UsernameToken wsu:Id="UsernameToken-<token>">
为了获得正确的令牌,我使用了来自npm(https://www.npmjs.com/package/wsse)的WSSE库。
我所要做的就是包括包,在自述文件中定义令牌:
const wsse = require('wsse');
const token = wsse({ username: '<username>', password: '<password>' })
然后为标题中的EncodingType属性调用token.getNonce()以获取正确的标记和token.getPasswordDigest()。
之后一切都按预期工作。
希望有所帮助!
答案 1 :(得分:-2)
我使用@MTM回答推送模块。 请看看
https://www.npmjs.com/package/wssecurity-soap
修复它的代码,以防任何人想要审查(与soap wssecurity auth实现包括修复相同)
var crypto = require('crypto');
var wsse = require('wsse');
var validPasswordTypes = ['PasswordDigest', 'PasswordText'];
function WSSecurity(username, password, options) {
options = options || {};
this._username = username;
this._password = password;
if (typeof options === 'string') {
this._passwordType = options ?
options :
'PasswordText';
options = {};
} else {
this._passwordType = options.passwordType ?
options.passwordType :
'PasswordText';
}
if (validPasswordTypes.indexOf(this._passwordType) === -1) {
this._passwordType = 'PasswordText';
}
this._hasTimeStamp = options.hasTimeStamp || typeof options.hasTimeStamp === 'boolean' ? !!options.hasTimeStamp : true;
if (options.hasNonce != null) {
this._hasNonce = !!options.hasNonce;
}
this._hasTokenCreated = options.hasTokenCreated || typeof options.hasTokenCreated === 'boolean' ? !!options.hasTokenCreated : true;
if (options.actor != null) {
this._actor = options.actor;
}
if (options.mustUnderstand != null) {
this._mustUnderstand = !!options.mustUnderstand;
}
}
WSSecurity.prototype.toXML = function() {
this._token = wsse({
username: this._username,
password: this._password
})
function getDate(d) {
function pad(n) {
return n < 10 ? '0' + n : n;
}
return d.getUTCFullYear() + '-'
+ pad(d.getUTCMonth() + 1) + '-'
+ pad(d.getUTCDate()) + 'T'
+ pad(d.getUTCHours()) + ':'
+ pad(d.getUTCMinutes()) + ':'
+ pad(d.getUTCSeconds()) + 'Z';
}
var now = new Date(this._token.getCreated());
var created = this._token.getCreated() ;
var timeStampXml = '';
if (this._hasTimeStamp) {
var expires = getDate( new Date(now.getTime() + (1000 * 600)) );
timeStampXml = "<wsu:Timestamp wsu:Id=\"Timestamp-"+created+"\">" +
"<wsu:Created>"+created+"</wsu:Created>" +
"<wsu:Expires>"+expires+"</wsu:Expires>" +
"</wsu:Timestamp>";
}
var password, nonce;
if (this._hasNonce || this._passwordType !== 'PasswordText') {
var nHash = crypto.createHash('sha1');
nHash.update(created + Math.random());
nonce = nHash.digest('base64');
}
if (this._passwordType === 'PasswordText') {
password = "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" + this._password + "</wsse:Password>";
if (nonce) {
password += "<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" + nonce + "</wsse:Nonce>";
}
} else {
password = "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">" + this._token.getPasswordDigest() + "</wsse:Password>" +
"<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" + this._token.getNonceBase64() + "</wsse:Nonce>";
}
return "<wsse:Security " + (this._actor ? "soap:actor=\"" + this._actor + "\" " : "") +
(this._mustUnderstand ? "soap:mustUnderstand=\"1\" " : "") +
"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\">" +
timeStampXml +
"<wsse:UsernameToken wsu:Id=\"UsernameToken-" + created +"\">"+
"<wsse:Username>" + this._username + "</wsse:Username>" +
password +
(this._hasTokenCreated ? "<wsu:Created>" + created + "</wsu:Created>" : "") +
"</wsse:UsernameToken>" +
"</wsse:Security>";
};
module.exports = WSSecurity;