简体   繁体   中英

Probleme Authentification with nodejs and soap

I consume a SOAP who use a PasswordDigest authentification. I use with succes this library: https://github.com/vpulim/node-soap

I run this code on Debian with nodejs version v0.10.29 and it's work.

Now i need to make it run on a windows computer with nodejs v6.6.0, and its not working anymore.

I have the following messages:

The security token could not be authenticated or authorized

I suspect a problem with the crypto lib, this code maybe:

"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');
};

From https://github.com/vpulim/node-soap/blob/master/lib/utils.js

Ok, so here's the way I've worked around it:

The SOAP library has a function for building the WSSE security header, which is placed in soap/lib/security/templates/WSSecurity.js.

The problem for me that the UsernameToken it was placing in the header was inconsistent with the one that soapUI was using and actually getting results (in my example).

Orignal code:

 "<wsse:UsernameToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"SecurityToken-" + created + "\">

While what I needed was:

<wsse:UsernameToken wsu:Id="UsernameToken-<token>">

To get the proper token I've used WSSE library from npm ( https://www.npmjs.com/package/wsse ).

All I had to do was include the package, define the token as in the readme:

const wsse = require('wsse');
const token = wsse({ username: '<username>', password: '<password>' })

Then call token.getNonce() for the proper token and token.getPasswordDigest() for the EncodingType property in the header.

After that everything works as intended.

Hope that helps!

I have pushed module using @MTM answer. Please have a look

https://www.npmjs.com/package/wssecurity-soap

Code for fixing it, in case anyone wants to review (its same as soap wssecurity auth implementation including fix)

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM