Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mikedevita
Created October 27, 2017 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikedevita/80495d0bbe25232874922a7c802f228f to your computer and use it in GitHub Desktop.
Save mikedevita/80495d0bbe25232874922a7c802f228f to your computer and use it in GitHub Desktop.
SailsJs + passport + passport-activedirectory - with ghaiklor/sails-generator-rest-api
"use strict";
/**
* AuthController
* @description :: Server-side logic for manage users' authorization
*/
const _ = require('lodash');
const passport = require('passport');
module.exports = {
/**
* Sign in by email\password
* @param req
* @param res
*/
login(req, res) {
passport.authenticate('ActiveDirectory', _.partial(sails.config.passport.onPassportAuth, req, res))(req, res);
},
/**
* Accept JSON Web Token and updates with new one
* @param req
* @param res
*/
refresh_token(req, res) {
if (!req.param('token')) return res.badRequest(null, {message: 'You must provide token parameter'});
const oldDecoded = CipherService.jwt.decodeSync(req.param('token'));
res.ok({
token: CipherService.jwt.encodeSync({id: oldDecoded.id})
});
}
};
"use strict";
/**
* Passport configuration file where you should configure all your strategies
* @description :: Configuration file where you configure your passport authentication
*/
const _ = require('lodash');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const ADStrategy = require('passport-activedirectory')
/**
* Configuration object for local strategy
* @type {Object}
* @private
*/
const LOCAL_STRATEGY_CONFIG = {
usernameField: 'email',
passwordField: 'password',
session: false,
passReqToCallback: true
};
/**
* Configuration object for JWT strategy
* @type {Object}
* @private
*/
const JWT_STRATEGY_CONFIG = {
secretOrKey: 'DEFAULT_SECRET_KEY',
jwtFromRequest: ExtractJwt.versionOneCompatibility({authScheme: 'Bearer', tokenBodyField: 'access_token'}),
tokenQueryParameterName: 'access_token',
session: false,
passReqToCallback: true
};
/**
* Configuration object for social strategies
* @type {Object}
* @private
*/
const AD_STRATEGY_CONFIG = {
integrated: false,
passReqToCallback: true,
allowedGroup: 'LinuxAdmins',
ldap: {
url: 'ldap://example.com',
baseDN: 'DC=example,DC=com',
username: 'foo@dexample.com',
password: 'password1234'
}
};
/**
* Triggers when user authenticates via local strategy
* @param {Object} req Request object
* @param {String} username Username from body field in request
* @param {String} password Password from body field in request
* @param {Function} next Callback
* @private
*/
const _onLocalStrategyAuth = (req, username, password, next) => {
User
.findOne({[LOCAL_STRATEGY_CONFIG.usernameField]: username})
.then(user => {
if (!user) return next(null, null, sails.config.errors.USER_NOT_FOUND);
if (!HashService.bcrypt.compareSync(password, user.password)) return next(null, null, sails.config.errors.USER_NOT_FOUND);
return next(null, user, {});
})
.catch(next);
};
/**
* Triggers when user authenticates via JWT strategy
* @param {Object} req Request object
* @param {Object} payload Decoded payload from JWT
* @param {Function} next Callback
* @private
*/
const _onJwtStrategyAuth = (req, payload, next) => {
User
.findOne({id: payload.id})
.then(user => {
if (!user) return next(null, null, sails.config.errors.USER_NOT_FOUND);
return next(null, user, {});
})
.catch(next);
};
const _onADStrategyAuth = (req, profile, ad, next) => {
ad.isUserMemberOf(profile._json.dn, AD_STRATEGY_CONFIG.allowedGroup, function (err, isMember) {
if (err) return next(err)
User.findOrCreate({
username: profile._json.sAMAccountName
}, {
username: profile._json.sAMAccountName,
email: profile._json.mail,
firstName: profile.name.givenName,
lastName: profile.name.familyName
})
.then((user) => {
return next(null, user)
})
.catch(next)
})
};
module.exports = {
passport: {
/**
* Triggers when all Passport steps is done and user profile is parsed
* @param {Object} req Request object
* @param {Object} res Response object
* @param {Object} error Object with error info
* @param {Object} user User object
* @param {Object} info Information object
* @returns {*}
* @private
*/
onPassportAuth(req, res, error, user, info) {
if (error || !user) return res.negotiate(error || info);
return res.ok({
token: CipherService.jwt.encodeSync({id: user.id}),
user: user
});
}
}
};
passport.use(new LocalStrategy(_.assign({}, LOCAL_STRATEGY_CONFIG), _onLocalStrategyAuth));
passport.use(new JwtStrategy(_.assign({}, JWT_STRATEGY_CONFIG), _onJwtStrategyAuth));
passport.use(new ADStrategy(_.assign({}, AD_STRATEGY_CONFIG), _onADStrategyAuth));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment