Created
July 21, 2014 13:30
-
-
Save sekoyo/94e39847361d7e5b360d to your computer and use it in GitHub Desktop.
Ping Federate SSO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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