Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/oauth2 generic #2

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const google = require('./providers/google');
const github = require('./providers/github');
const twitter = require('./providers/twitter');
const facebook = require('./providers/facebook');
const oauth2 = require('./providers/oauth2');
const utils = require('./providers/utils');

// Use default options, see https://www.npmjs.com/package/session-file-store
Expand Down Expand Up @@ -93,6 +94,7 @@ app.initApp = function (callback) {
app.use(basePath + '/github', github);
app.use(basePath + '/twitter', twitter);
app.use(basePath + '/facebook', facebook);
app.use(basePath + '/oauth2', oauth2);

// CORS enable this end point
app.get(basePath + '/profile', utils.cors(), function (req, res, next) {
Expand Down
2 changes: 2 additions & 0 deletions bin/auth-passport
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const google = require('../providers/google');
const github = require('../providers/github');
const twitter = require('../providers/twitter');
const facebook = require('../providers/facebook');
const oauth2 = require('../providers/oauth2');

/**
* Create HTTP server.
Expand Down Expand Up @@ -62,6 +63,7 @@ async.series({
github.init(app, app.authConfig);
twitter.init(app, app.authConfig);
facebook.init(app, app.authConfig);
oauth2.init(app, app.authConfig);

// Simplest kind of serialization and deserialization
passport.serializeUser(function (user, done) {
Expand Down
42 changes: 25 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
"wicked",
"apim",
"api",
"management"
"management",
"google",
"github",
"facebook",
"twitter",
"adfs",
"oauth2"
],
"author": "Martin Danielsson <[email protected]>",
"license": "Apache-2.0",
Expand All @@ -27,23 +33,25 @@
},
"homepage": "https://github.com/Haufe-Lexware/wicked.auth-passport#readme",
"dependencies": {
"async": "2.0.1",
"body-parser": "1.15.2",
"cookie-parser": "1.4.3",
"cors": "2.7.1",
"debug": "2.2.0",
"express": "4.14.0",
"express-session": "1.14.2",
"jade": "1.11.0",
"morgan": "1.7.0",
"passport": "0.3.2",
"async": "^2.6.0",
"body-parser": "^1.18.2",
"cookie-parser": "^1.4.3",
"cors": "^2.8.4",
"debug": "^2.6.9",
"express": "^4.16.2",
"express-session": "^1.15.6",
"jade": "^1.11.0",
"jsonwebtoken": "^5.7.0",
"morgan": "^1.9.0",
"passport": "^0.3.2",
"passport-facebook": "^2.1.1",
"passport-github2": "0.1.10",
"passport-google-oauth20": "1.0.0",
"passport-twitter": "1.0.4",
"request": "2.74.0",
"session-file-store": "0.2.2",
"wicked-sdk": "^0.11.1"
"passport-github2": "^0.1.11",
"passport-google-oauth20": "^1.0.0",
"passport-oauth": "^1.0.0",
"passport-twitter": "^1.0.4",
"request": "^2.83.0",
"session-file-store": "^0.2.2",
"wicked-sdk": "^0.11.4"
},
"jshintConfig": {
"node": true,
Expand Down
91 changes: 91 additions & 0 deletions providers/oauth2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'use strict';

const request = require('request');
const passport = require('passport');
const OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
const wicked = require('wicked-sdk');
const debug = require('debug')('auth-passport:oauth2');
const jwt = require('jsonwebtoken');

const utils = require('./utils');

const oauth2 = require('express').Router();

oauth2.authenticateSettings = {
failureRedirect: '/auth-server/failure'
};

oauth2.init = function (app, authConfig) {
debug('init()');
oauth2.authServerName = app.get('server_name');
oauth2.basePath = app.get('base_path');
if (!authConfig.oauth2) {
debug('Not configuring oauth2 authentication.');
return;
}

oauth2.authenticateSettings.failureRedirect = oauth2.basePath + '/failure';

if (!authConfig.oauth2.clientId)
throw new Error('In auth-server configuration, property "oauth2", the property "clientId" is missing.');
if (!authConfig.oauth2.clientSecret)
throw new Error('In auth-server configuration, property "oauth2", the property "clientSecret" is missing.');
if (!authConfig.oauth2.callbackUrl)
throw new Error('In auth-server configuration, property "oauth2", the property "callbackUrl" is missing.');
if (!authConfig.oauth2.authorizationURL)
throw new Error('In auth-server configuration, property "oauth2", the property "authorizationURL" is missing.');
if (!authConfig.oauth2.tokenURL)
throw new Error('In auth-server configuration, property "oauth2", the property "tokenURL" is missing.');

passport.use(new OAuth2Strategy({
clientID: authConfig.oauth2.clientId,
clientSecret: authConfig.oauth2.clientSecret,
callbackURL: authConfig.oauth2.callbackUrl,
authorizationURL: authConfig.oauth2.authorizationURL,
tokenURL: authConfig.oauth2.tokenURL,
passReqToCallback: true
}, function (req, accessToken, refreshToken, profile, done) {
debug('Oauth2 Authenticate succeeded.' + ' ' + accessToken + ' ' + refreshToken + ' ' + profile);
normalizeProfile(profile, accessToken, authConfig, function (err, userProfile) {
debug('callback normalizeProfile()');
if (err) {
debug('But normalizeProfile failed.');
console.error(err);
console.error(err.stack);
return done(err);
}
debug('Normalized Profile:');
debug(userProfile);
done(null, userProfile);
});
}));

const authenticateWithOauth2 = passport.authenticate('oauth2', { scope: ['user:email'] });
const authenticateCallback = passport.authenticate('oauth2', oauth2.authenticateSettings);

oauth2.get('/api/:apiId', utils.verifyClientAndAuthenticate('oauth2', authenticateWithOauth2));
oauth2.get('/callback', authenticateCallback, utils.authorizeAndRedirect('oauth2', oauth2.authServerName));

debug('Configured oauth2 authentication.');
};

function normalizeProfile(profile, accessToken, authConfig, callback) {
debug('normalizeProfile(): ' + accessToken);
var decodedProfile = jwt.decode(accessToken);
var defaultGroups = [];
if(decodedProfile['group']){
defaultGroups = decodedProfile['group'];
}
const userProfile = {
id: "oauth2:"+decodedProfile[authConfig.oauth2.customIdField],
sub: "oauth2:"+decodedProfile[authConfig.oauth2.customIdField],
firstName: decodedProfile[authConfig.oauth2.firstNameField],
lastName: decodedProfile[authConfig.oauth2.lastNameField],
validated: true, // In Oauth2 we trust
groups: defaultGroups,
email: decodedProfile[authConfig.oauth2.emailField]
};
return callback(null, userProfile);
}

module.exports = oauth2;