Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

0.1.13 release merge #51

Merged
merged 5 commits into from
May 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 0.1.13
--------------
Release Date: 1 May 2015
* Scrub security sensitive data in WS-Trust exchange from log messages.
* Update the version of the jws dependency to the latest release.

Version 0.1.12
--------------
Release Date: 19 February 2015
Expand Down
6 changes: 5 additions & 1 deletion lib/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,16 @@ Object.defineProperty(Logger.prototype, 'context', {
/**
* Generates a log entry
* @param {Logging.LOGGING_LEVEL} level The level of this log entry
* @param {string} message A message string to log.
* @param {string|function} message A message string, or a function that returns a message string, to log.
* @param {Error} [error] If this is a {@link Logging.LOGGING_LEVEL.ERROR|ERROR} level log entry then the caller
* should pass an error object in this parameter.
*/
Logger.prototype.log = function(level, message, error) {
if (level <= Logging.LogOptions.level) {
if (_.isFunction(message)) {
message = message();
}

var correlationId = this._logContext.correlationId || '<no correlation id>';

var formattedMessage = correlationId + ' - ' + this._componentName + ': ' + LEVEL_STRING_MAP[level] + ' ' + message;
Expand Down
55 changes: 32 additions & 23 deletions lib/wstrust-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ var Logger = require('./log').Logger;
var util = require('./util');
var WSTrustResponse = require('./wstrust-response');

var USERNAME_PLACEHOLDER = '{UsernamePlaceHolder}';
var PASSWORD_PLACEHOLDER = '{PasswordPlaceHolder}';

/**
* Creates a new instance of WSTrustRequest
* @constructor
Expand All @@ -42,22 +45,6 @@ function WSTrustRequest(callContext, wstrustEndpointUrl, appliesTo) {
this._appliesTo = appliesTo;
}

/**
* Builds the UsernameToken XML that will carry the user creds in the RST.
* @param {string} username A username
* @param {string} password The password that corresponds to the username parameter.
* @returns {string} A string containing the UsernameToken XML
*/
WSTrustRequest.prototype._buildSoapMessageCredentials = function(username, password) {
var usernameTokenXml =
'<wsse:UsernameToken wsu:Id=\'ADALUsernameToken\'>\
<wsse:Username>' + username + '</wsse:Username>\
<wsse:Password>' + password +'</wsse:Password>\
</wsse:UsernameToken>';

return usernameTokenXml;
};

/**
* Given a Date object adds the minutes parameter and returns a new Date object.
* @private
Expand All @@ -80,7 +67,7 @@ function _datePlusMinutes(date, minutes) {
* @param {string} password The passowrd that corresponds to the username parameter.
* @returns {string} A string that contains the soap security header.
*/
WSTrustRequest.prototype._buildSecurityHeader = function(username, password) {
WSTrustRequest.prototype._buildSecurityHeader = function() {
var timeNow = new Date();
var expireTime =
_datePlusMinutes(timeNow, 10);
Expand All @@ -92,13 +79,30 @@ _datePlusMinutes(timeNow, 10);
<wsu:Timestamp wsu:Id=\'_0\'>\
<wsu:Created>' + timeNowString + '</wsu:Created>\
<wsu:Expires>' + expireTimeString + '</wsu:Expires>\
</wsu:Timestamp>' +
this._buildSoapMessageCredentials(username, password) +
'</wsse:Security>';
</wsu:Timestamp>\
<wsse:UsernameToken wsu:Id=\'ADALUsernameToken\'>\
<wsse:Username>' + USERNAME_PLACEHOLDER + '</wsse:Username>\
<wsse:Password>' + PASSWORD_PLACEHOLDER + '</wsse:Password>\
</wsse:UsernameToken>\
</wsse:Security>';

return securityHeaderXml;
};

/**
* Replaces the placeholders in the RST template with the actual username and password values.
* @private
* @param {string} RSTTemplate An RST with placeholders for username and password.
* @param {string} username A username
* @param {string} password The passowrd that corresponds to the username parameter.
* @returns {string} A string containing a complete RST soap message.
*/

WSTrustRequest.prototype._populateRSTUsernamePassword = function(RSTTemplate, username, password) {
var RST = RSTTemplate.replace(USERNAME_PLACEHOLDER, username).replace(PASSWORD_PLACEHOLDER, password);
return RST;
};

/**
* Builds a WS-Trust RequestSecurityToken (RST) message using username password authentication.
* @private
Expand All @@ -109,7 +113,9 @@ _datePlusMinutes(timeNow, 10);
WSTrustRequest.prototype._buildRST = function(username, password) {
var messageID = uuid.v4();

var RST =
// Create a template RST with placeholders for the username and password so the
// the RST can be logged without the sensitive information.
var RSTTemplate =
'<s:Envelope xmlns:s=\'http://www.w3.org/2003/05/soap-envelope\' xmlns:wsa=\'http://www.w3.org/2005/08/addressing\' xmlns:wsu=\'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\'>\
<s:Header>\
<wsa:Action s:mustUnderstand=\'1\'>http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</wsa:Action>\
Expand All @@ -118,7 +124,7 @@ WSTrustRequest.prototype._buildRST = function(username, password) {
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>\
</wsa:ReplyTo>\
<wsa:To s:mustUnderstand=\'1\'>' + this._wstrustEndpointUrl + '</wsa:To>\
' + this._buildSecurityHeader(username, password) + '\
' + this._buildSecurityHeader() + '\
</s:Header>\
<s:Body>\
<wst:RequestSecurityToken xmlns:wst=\'http://docs.oasis-open.org/ws-sx/ws-trust/200512\'>\
Expand All @@ -133,6 +139,9 @@ WSTrustRequest.prototype._buildRST = function(username, password) {
</s:Body>\
</s:Envelope>';

this._log.verbose('Created RST: \n' + RSTTemplate);

var RST = this._populateRSTUsernamePassword(RSTTemplate, username, password);
return RST;
};

Expand Down Expand Up @@ -176,7 +185,7 @@ WSTrustRequest.prototype.acquireToken = function(username, password, callback) {
}
);

this._log.verbose('Sending RST to: ' + this._wstrustEndpointUrl + '\n' + RST);
this._log.verbose('Sending RST to: ' + this._wstrustEndpointUrl);

request.post(this._wstrustEndpointUrl, options, util.createRequestHandler('WS-Trust RST', this._log, callback,
function(response, body) {
Expand Down
30 changes: 29 additions & 1 deletion lib/wstrust-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,34 @@ var Logger = require('./log').Logger;
var select = xmlutil.xpathSelect;
var DOMParser = xmldom.DOMParser;

// A regular expression for finding the SAML Assertion in an RSTR. Used to remove the SAML
// assertion when logging the RSTR.
var assertionRegEx = /RequestedSecurityToken.*?((<.*?:Assertion.*?>).*<\/.*?Assertion>).*?/;

/**
* Creates a log message that contains the RSTR scrubbed of the actual SAML assertion.
* @private
* @return {string} A log message.
*/
function scrubRSTRLogMessage(RSTR) {
var scrubbedRSTR = null;

var singleLineRSTR = RSTR.replace(/(\r\n|\n|\r)/gm,'');

var matchResult = assertionRegEx.exec(singleLineRSTR);
if (null === matchResult) {
// No Assertion was matched so just return the RSTR as is.
scrubbedRSTR = singleLineRSTR;
} else {
var samlAssertion = matchResult[1];
var samlAssertionStartTag = matchResult[2];

scrubbedRSTR = singleLineRSTR.replace(samlAssertion, samlAssertionStartTag + 'ASSERTION CONTENTS REDACTED</saml:Assertion>');
}

return 'RSTR Response: ' + scrubbedRSTR;
}

/**
* Creates a new WSTrustResponse instance.
* @constructor
Expand All @@ -46,7 +74,7 @@ function WSTrustResponse(callContext, response) {
this._tokenType = null;
this._token = null;

this._log.verbose('RSTR Response: ' + this._response);
this._log.verbose(function(){return scrubRSTRLogMessage(response);});
}

/**
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
"type": "git",
"url": "https://github.com/MSOpenTech/azure-activedirectory-library-for-nodejs.git"
},
"version": "0.1.12",
"version": "0.1.13",
"description": "Windows Azure Active Directory Client Library for node",
"keywords": [ "node", "azure", "AAD", "adal", "adfs", "oauth" ],
"main": "./lib/adal.js",
"engines": { "node": ">= 0.6.15" },
"licenses": [ { "type": "Apache 2.0", "url": "http://www.apache.org/licenses/LICENSE-2.0" } ],
"dependencies": {
"date-utils": "*",
"jws": "1.x.x",
"jws": "3.x.x",
"node-uuid": "1.4.1",
"request": ">= 2.9.203",
"underscore": ">= 1.3.1",
Expand Down