зеркало из
1
0
Форкнуть 0

Google Apps / GSuite authentication support

Supports using Google Authentication with a specific GSuite domain
as opposed to using Azure Active Directory.
This commit is contained in:
Jeff Wilcox 2017-06-01 14:35:41 -07:00
Родитель 538e28989a
Коммит 21faa74775
5 изменённых файлов: 69 добавлений и 14 удалений

Просмотреть файл

@ -0,0 +1,6 @@
{
"clientId": "env://AUTH_GOOGLE_CLIENT_ID",
"clientSecret": "env://AUTH_GOOGLE_CLIENT_SECRET",
"domain": "env://AUTH_GOOGLE_DOMAIN",
"redirectUrl": "env://AUTH_GOOGLE_REDIRECT_URL"
}

Просмотреть файл

@ -9,8 +9,7 @@ const passport = require('passport');
const serializer = require('./passport/serializer');
const GitHubStrategy = require('../thirdparty/passport-github').Strategy;
const OIDCStrategy = require('passport-azure-ad').OIDCStrategy;
// FYI: GitHub does not provide refresh tokens
const GoogleStrategy = require('passport-google-oauth20').Strategy;
function githubResponseToSubset(accessToken, refreshToken, profile, done) {
let subset = {
@ -61,12 +60,29 @@ function activeDirectorySubset(iss, sub, profile, done) {
module.exports = function (app, config) {
if (!config.authentication.scheme) {
config.authentication.scheme = 'github';
config.authentication.scheme = 'aad';
}
if (config.authentication.scheme !== 'github' && config.authentication.scheme !== 'aad') {
if (config.authentication.scheme !== 'github'
&& config.authentication.scheme !== 'aad'
&& config.authentication.scheme !== 'google') {
throw new Error(`Unsupported primary authentication scheme type "${config.authentication.scheme}"`);
}
function googleSubset(accessToken, refreshToken, profile, callback) {
const json = profile._json;
let domain = json && json.domain ? json.domain : null;
let expectedDomain = config.authentication.google && config.authentication.google.domain ? config.authentication.google.domain : null;
if (!expectedDomain) {
return callback(new Error('The Google Authentication provider must be configured with the expected Google Apps domain name. None has been configured.'));
}
if (domain !== expectedDomain) {
return callback(new Error(`You must be a member of the ${expectedDomain} domain to use this app`));
}
return callback(null, profile);
}
// ----------------------------------------------------------------------------
// GitHub Passport session setup.
// ----------------------------------------------------------------------------
@ -79,6 +95,7 @@ module.exports = function (app, config) {
userAgent: 'passport-azure-oss-portal-for-github' // CONSIDER: User agent should be configured.
};
let githubPassportStrategy = new GitHubStrategy(githubOptions, githubResponseToSubset);
let aadStrategy = new OIDCStrategy({
redirectUrl: config.activeDirectory.redirectUrl,
allowHttpForRedirectUrl: config.webServer.allowHttp,
@ -92,6 +109,16 @@ module.exports = function (app, config) {
validateIssuer: true,
}, activeDirectorySubset);
let googleStrategy = null;
if (config.authentication && config.authentication.google) {
googleStrategy = new GoogleStrategy({
clientID: config.authentication.google.clientId,
clientSecret: config.authentication.google.clientSecret,
callbackURL: config.authentication.google.redierctUrl,
scope: ['email'],
}, googleSubset);
}
// Validate the borrow some parameters from the GitHub passport library
if (githubPassportStrategy._oauth2 && githubPassportStrategy._oauth2._authorizeUrl) {
app.set('runtime/passport/github/authorizeUrl', githubPassportStrategy._oauth2._authorizeUrl);
@ -105,7 +132,8 @@ module.exports = function (app, config) {
}
passport.use('github', githubPassportStrategy);
passport.use('azure-active-directory', aadStrategy);
//passport.use('azure-active-directory', aadStrategy);
passport.use('google', googleStrategy);
// ----------------------------------------------------------------------------
// Expanded OAuth-scope GitHub access for org membership writes.

Просмотреть файл

@ -179,17 +179,35 @@ module.exports = function configurePassport(app, passport, initialConfig) {
// ----------------------------------------------------------------------------
// passport integration with Azure Active Directory
// ----------------------------------------------------------------------------
var aadMiddleware = initialConfig.authentication.scheme === 'github' ? passport.authorize('azure-active-directory') : passport.authenticate('azure-active-directory');
const hasAAD = false;
if (hasAAD) {
var aadMiddleware = initialConfig.authentication.scheme === 'github' ? passport.authorize('azure-active-directory') : passport.authenticate('azure-active-directory');
app.get('/auth/azure', aadMiddleware);
app.get('/auth/azure', aadMiddleware);
app.post('/auth/azure/callback', aadMiddleware, authenticationCallback.bind(null, 'aad', 'azure'));
app.post('/auth/azure/callback', aadMiddleware, authenticationCallback.bind(null, 'aad', 'azure'));
app.get('/signin/azure', function (req, res) {
utils.storeReferrer(req, res, '/auth/azure', 'request for the /signin/azure page, need to authenticate');
});
app.get('/signin/azure', function (req, res) {
utils.storeReferrer(req, res, '/auth/azure', 'request for the /signin/azure page, need to authenticate');
});
app.get('/signout/azure', processSignout.bind(null, 'aad', 'azure'));
app.get('/signout/azure', processSignout.bind(null, 'aad', 'azure'));
}
const hasGoogle = true;
if (hasGoogle) {
const googleMiddleware = passport.authenticate('google');
app.get('/auth/google', googleMiddleware);
app.get('/auth/google/callback', googleMiddleware, authenticationCallback.bind(null, 'google', 'google'));
app.get('/signin/google', function (req, res) {
utils.storeReferrer(req, res, '/auth/google', 'request for the /signin/google page, need to authenticate');
});
app.get('/signout/google', processSignout.bind(null, 'aad', 'azure'));
}
};

Просмотреть файл

@ -63,6 +63,7 @@
"painless-config-resolver": "1.0.0",
"passport": "^0.3.2",
"passport-azure-ad": "^3.0.5",
"passport-google-oauth20": "^1.0.0",
"passport-strategy": "1.x.x",
"pug": "=2.0.0-beta4",
"q": "^1.5.0",

Просмотреть файл

@ -20,8 +20,10 @@ const utils = require('../utils');
router.use(function (req, res, next) {
var config = req.app.settings.runtimeConfig;
const authType = 'google'; // 'azure'
const redirectType = 'google'; // 'azure'
if (req.isAuthenticated()) {
var expectedAuthenticationProperty = config.authentication.scheme === 'github' ? 'github' : 'azure';
var expectedAuthenticationProperty = config.authentication.scheme === 'github' ? 'github' : authType;
if (req.user && !req.user[expectedAuthenticationProperty]) {
console.warn(`A user session was authenticated but did not have present the property "${expectedAuthenticationProperty}" expected for this type of authentication. Signing them out.`);
return res.redirect('/signout');
@ -32,7 +34,7 @@ router.use(function (req, res, next) {
}
return next();
}
utils.storeOriginalUrlAsReferrer(req, res, config.authentication.scheme === 'github' ? '/auth/github' : '/auth/azure', 'user is not authenticated and needs to authenticate');
utils.storeOriginalUrlAsReferrer(req, res, config.authentication.scheme === 'github' ? '/auth/github' : '/auth/' + redirectType, 'user is not authenticated and needs to authenticate');
});
router.use((req, res, next) => {