Экспресс / паспорт SAML Аутентификация перенаправляет на бесконечный цикл - PullRequest
0 голосов
/ 19 октября 2018

Попытка использовать passport-saml для подключения к ADFS.

Ответ SAML возвращается с успешными кодами состояния.

Мы получаем следующий код успеха:

"<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status>"

Но наш Passport IsAuthenicated всегда генерирует ложное значение.

Я перечислил все наши файлы, использованные для этогониже и будем благодарны за любую помощь.

server.js file:

const express = require('express');
const http = require('http');
const path = require('path');
const passport = require('passport');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');

const session = require('express-session');
const errorhandler = require('errorhandler');

var env = process.env.NODE_ENV || 'development';

const config = require('./config/config')[env];

console.log('Using configuration', config);

require('./config/passport')(passport, config);

var app = express();

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(cookieParser());
app.enable('trust proxy'); // add this line
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(session(
  {
    resave: true,
    saveUninitialized: true,
    secret: 'default',
    proxy: true // add this line
  }));
app.use(passport.initialize());
app.use(passport.session());
app.use(morgan('combined'));

function ensureAuthenticated(req, res, next) {
  if (//req.isAuthenticated()
	  true
	  ) { 
  console.log('req.isAuthenticated = ' + req.isAuthenticated());
  return next(); }
  else{
	console.log('req.isAuthenticated = ' + req.isAuthenticated());
    res.redirect('/login');
  }
}


app.set('port', config.app.port);

require('./config/routes')(app, config, passport);

//ensure that ensureAuthenticated is in the get function call before master build
//ie app.get('/*', ensureAuthenticated, (req, res)
app.use(express.static(path.join(__dirname, 'public')));
app.get('/*', ensureAuthenticated, (req, res) => {
      res.sendFile(path.join(__dirname, 'public/index.html'));
});

app.listen(app.get('port'), function () {
  console.log('Express server listening on port ' + app.get('port'));
});

rout.js

module.exports = function (app, config, passport) {

  app.get('/', function (req, res) {
      res.redirect('/home')
  });

  app.get('/login',
    passport.authenticate(config.passport.strategy,
      {
        successRedirect: '/',
        failureRedirect: '/login'
      })
  );

  app.post('/',
    passport.authenticate(config.passport.strategy,
      {
        failureRedirect: '/',
        failureFlash: true
      }),
    function (req, res) {
      res.redirect('/');
    }
  );

  app.get('/logout', function (req, res) {
    req.logout();
    // TODO: invalidate session on IP
    res.redirect('https://redrectsite.com/?wa=signout1.0');
  });
  

};

config.js

module.exports = {
    development: {
      app: {
        name: 'Passport SAML strategy example',
        port: process.env.PORT || 80
      },
      passport: {
        strategy: 'saml',
        saml: {
          callbackUrl: process.env.SAML_CALLBACK_URL || 'https://oursite.com',
          entryPoint: process.env.SAML_ENTRY_POINT || 'https://oursite.com/adfs/ls/idpinitiatedsignon',
          issuer: process.env.SAML_ISSUER || 'https://oursite.com',
          identifierFormat: null,
		  signatureAlgorithm: 'sha256',
		  authnContext: 'http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/windows',
		  disableRequestedAuthnContext: true
          //cert: process.env.SAML_CERT || null
        }
      }
    }
  };

passport.js

const SamlStrategy = require('passport-saml').Strategy;

module.exports = function (passport, config) {

  passport.serializeUser(function (user, done) {
    done(null, user);
  });

  passport.deserializeUser(function (user, done) {
    done(null, user);
  });

  passport.use(new SamlStrategy(
    {
      callbackUrl: config.passport.saml.callbackUrl,
      entryPoint: config.passport.saml.entryPoint,
      issuer: config.passport.saml.issuer,
      cert: config.passport.saml.cert,
      identifierFormat: config.passport.saml.identifierFormat,
	  signatureAlgorithm: config.passport.saml.signatureAlgorithm,
	  authnContext: config.passport.saml.authnContext,
	  disableRequestedAuthnContext: config.passport.saml.disableRequestedAuthnContext

    },
    function (profile, done) {
      return done(null,
        {
          id: profile.uid,
          email: profile.email,
          displayName: profile.cn,
          firstName: profile.givenName,
          lastName: profile.sn
        });
    })
  );

};

1 Ответ

0 голосов
/ 06 декабря 2018

У меня была похожая проблема.Если вы посмотрите на то, что делает isAuthenticated(), это на самом деле просто проверка свойства внутри объекта request.session.

https://github.com/jaredhanson/passport/blob/2327a36e7c005ccc7134ad157b2f258b57aa0912/lib/http/request.js#L86

req.isAuthenticated = function() {
  var property = 'user';
  if (this._passport && this._passport.instance) {
    property = this._passport.instance._userProperty || 'user';
  }

  return (this[property]) ? true : false;
};

Я не уверен, что это паспорт илиexpress-session, но как только вы доберетесь до метода аутентификации, пользовательский объект будет храниться в request.session.passport.user, поэтому, если хотите, вы можете напрямую проверить, что он не нулевой, вместо использования упакованного метода isAuthenticated(), который, кажется, проверяетнеправильный путь.

Мой код начал работать после замены его на следующее.

if (_.get(req, 'session.passport.user', null)) {
    return next();
}

(lodash _.get для упрощения проверки вложенных свойств на ноль)

...