Skip to content

Instantly share code, notes, and snippets.

@sekoyo
Created July 21, 2014 13:30
Show Gist options
  • Save sekoyo/94e39847361d7e5b360d to your computer and use it in GitHub Desktop.
Save sekoyo/94e39847361d7e5b360d to your computer and use it in GitHub Desktop.
Ping Federate SSO
var Q = require('q');
var util = require('util');
var request = require('request');
var _ = require('lodash');
var sso = {};
/**
* Redirect to the SSO login page.
*/
sso.redirectToSsoPage = function () {
'use strict';
var targetResource = sso.req.query.TargetResource ?
sso.req.query.TargetResource :
'https://' + sso.req.get('host') + sso.req.url;
var ssoUrl = util.format('https://%s%s?PartnerIdpId=%s&TargetResource=%s',
process.env.SSO_PF_BASE_URL,
process.env.SSO_START_SSO_PATH,
process.env.SSO_PARTNER_IDP_ID,
targetResource
);
sso.res.redirect(307, ssoUrl);
};
/**
* Check if a client is authed.
* @return {Boolean} True if authenticated.
*/
sso.isAuthed = function () {
'use strict';
return sso.req.session && sso.req.session.attrs;
};
/**
* Retrieves auth attributes from the session or sso server.
* @return {Promise} Promise object.
*/
sso.retrieveAttributes = function () {
'use strict';
var deferred = Q.defer();
if (sso.isAuthed()) {
deferred.resolve(sso.req.session.attrs);
return deferred.promise;
}
var url = util.format('https://%s%s?REF=%s',
process.env.SSO_PF_BASE_URL,
process.env.SSO_PF_PICKUP_PATH,
sso.req.query.REF);
request.get(url, function(err, res, body) {
if (err) {
deferred.reject(err);
return;
}
sso.req.session.attrs = JSON.parse(body);
deferred.resolve(sso.req.session.attrs);
}).auth(process.env.SSO_PF_ADAPTER_USER, process.env.SSO_PF_ADAPTER_PASS);
return deferred.promise;
};
/**
* Checks `member_of` array in session to see if user has access
* to the desired domain.
* @param {String} [domain] Domain/group. Defaults to process.env.SSO_DOMAIN.
* @return {Boolean} True if the user has access.
*/
sso.checkAccess = function (domain) {
/*jshint camelcase: false */
'use strict';
domain = domain || process.env.SSO_DOMAIN;
if (!sso.req.session || !sso.req.session.attrs ||
!sso.req.session.attrs.member_of) {
return false;
}
var matches = _.filter(
sso.req.session.attrs.member_of,
function (s) {
return s.indexOf(domain) !== -1;
}
);
return !!matches.length;
};
/**
* Ensure the route is authenticated before proceeding.
* @param req
* @param res
* @param next
*/
sso.injectAuth = function (req, res, next) {
'use strict';
sso.req = req;
sso.res = res;
if (!req.query.REF && !sso.isAuthed()) {
sso.redirectToSsoPage();
} else {
sso.retrieveAttributes()
.then(function () {
if (sso.checkAccess()) {
next();
} else {
res.send(401);
}
}, function () {
res.send(500);
});
}
};
module.exports = sso;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment