loopback + passport + openID

时间:2018-06-18 09:08:09

标签: passport.js openid openid-connect strongloop loopback

从有关护照集成的现有环回示例开始 环回-例如护照 我尝试集成基于openId的外部IDP,在我的案例中是KeyCloak。

这里是示例原始server.js代码

'use strict';

var loopback = require('loopback');
var boot = require('loopback-boot');
var app = module.exports = loopback();
var cookieParser = require('cookie-parser');
var session = require('express-session');

// Passport configurators..
var loopbackPassport = require('loopback-component-passport');
var PassportConfigurator = loopbackPassport.PassportConfigurator;
var passportConfigurator = new PassportConfigurator(app);

/*
 * body-parser is a piece of express middleware that
 *   reads a form's input and stores it as a javascript
 *   object accessible through `req.body`
 *
 */
var bodyParser = require('body-parser');

/**
 * Flash messages for passport
 *
 * Setting the failureFlash option to true instructs Passport to flash an
 * error message using the message given by the strategy's verify callback,
 * if any. This is often the best approach, because the verify callback
 * can make the most accurate determination of why authentication failed.
 */
var flash      = require('express-flash');

// attempt to build the providers/passport config
var config = {};
try {
  config = require('../providers.json');
} catch (err) {
  console.trace(err);
  process.exit(1); // fatal
}

// -- Add your pre-processing middleware here --

// Setup the view engine (jade)
var path = require('path');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// boot scripts mount components like REST API
boot(app, __dirname);

// to support JSON-encoded bodies
app.middleware('parse', bodyParser.json());
// to support URL-encoded bodies
app.middleware('parse', bodyParser.urlencoded({
  extended: true,
}));

// The access token is only available after boot
app.middleware('auth', loopback.token({
  model: app.models.accessToken,
}));

app.middleware('session:before', cookieParser(app.get('cookieSecret')));
app.middleware('session', session({
  secret: 'kitty',
  saveUninitialized: true,
  resave: true,
}));
passportConfigurator.init();

// We need flash messages to see passport errors
app.use(flash());

passportConfigurator.setupModels({
  userModel: app.models.user,
  userIdentityModel: app.models.userIdentity,
  userCredentialModel: app.models.userCredential,
});
for (var s in config) {
  var c = config[s];
  c.session = c.session !== false;
  passportConfigurator.configureProvider(s, c);
}
var ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn;

app.get('/', function(req, res, next) {
  console.debug("Passo di qui");
  res.render('pages/index', {user:
    req.user,
    url: req.url,
  });
});

app.get('/auth/account', ensureLoggedIn('/login'), function(req, res, next) {
  res.render('pages/loginProfiles', {
    user: req.user,
    url: req.url,
  });
});

app.get('/local', function(req, res, next) {
  res.render('pages/local', {
    user: req.user,
    url: req.url,
  });
});

app.get('/ldap', function(req, res, next) {
  res.render('pages/ldap', {
    user: req.user,
    url: req.url,
  });
});

app.get('/signup', function(req, res, next) {
  res.render('pages/signup', {
    user: req.user,
    url: req.url,
  });
});

app.post('/signup', function(req, res, next) {
  var User = app.models.user;

  var newUser = {};
  newUser.email = req.body.email.toLowerCase();
  newUser.username = req.body.username.trim();
  newUser.password = req.body.password;

  User.create(newUser, function(err, user) {
    if (err) {
      req.flash('error', err.message);
      return res.redirect('back');
    } else {
      // Passport exposes a login() function on req (also aliased as logIn())
      // that can be used to establish a login session. This function is
      // primarily used when users sign up, during which req.login() can
      // be invoked to log in the newly registered user.
      req.login(user, function(err) {
        if (err) {
          req.flash('error', err.message);
          return res.redirect('back');
        }
        return res.redirect('/auth/account');
      });
    }
  });
});

app.get('/login', function(req, res, next) {
  res.render('pages/login', {
    user: req.user,
    url: req.url,
  });
});

app.get('/auth/logout', function(req, res, next) {
  req.logout();
  res.redirect('/');
});

app.start = function() {
  // start the web server
  return app.listen(function() {
    app.emit('started');
    var baseUrl = app.get('url').replace(/\/$/, '');
    console.log('Web server listening at: %s', baseUrl);
    if (app.get('loopback-component-explorer')) {
      var explorerPath = app.get('loopback-component-explorer').mountPath;
      console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
    }
  });
};

// start the server if `$ node server.js`
if (require.main === module) {
  app.start();
}

这里是我的providers.json定义

{
  "local": {
    "provider": "local",
    "module": "passport-local",
    "usernameField": "username",
    "passwordField": "password",
    "authPath": "/auth/local",
    "successRedirect": "/auth/account",
    "failureRedirect": "/local",
    "failureFlash": true
  },
  "keycloak": {
    "provider": "keycloak",
    "module": "passport-openid-connect",
    "authScheme": "openid connect",
    "scope": "openid",
    "passReqToCallback":true,
    "session": true,
    "issuerHost": "https://[my host]/auth/realms/[my realm]",
    "client_id": "[my client id]",
    "client_secret": "[my client secret]",
    "redirect_uri": "http://localhost:3000/auth/account",
    "authPath": "/auth/keycloak",
    "callbackPath": "/auth/keycloak/callback",
    "response_type":"code",
    "usePKCE": false,
    "link":true
  }
}

测试idp我能够被重定向,登录并返回,但我从未记录过,并且req.user总是未定义的。什么遗失?

1 个答案:

答案 0 :(得分:1)

一个人解决,希望可以帮助别人。 我使用了另一个通行证组件,而非通行证-openid-connect通行证。

这是添加到loopback-passport-example的提供程序

    "openid": {
        "provider": "openid",
        "module": "passport-openidconnect",
        "issuer": "https://[my idp]/auth/realms/[my realm]",
        "session": "true",
        "clientID": "[my client id]", 
        "clientSecret": "[my client secret]", 
        "callbackURL": "/auth/openid/callback", 
        "authorizationURL": "[auth url]", 
        "tokenURL": "[token url]", 
        "userInfoURL": "[user info url]", 
        "scope": "auth_web openid profile email",
        "authPath": "/auth/openid",
        "callbackPath": "/auth/openid/callback",
        "successRedirect": "/auth/account",
        "failureRedirect": "/login",
        "failureFlash": true
     }

请记住将/ auth / openid添加到示例登录页面。