代码之家  ›  专栏  ›  技术社区  ›  user68288

express/passport saml身份验证重定向到无限循环

  •  0
  • user68288  · 技术社区  · 6 年前

    尝试使用passport saml连接到adfs。

    saml响应将返回成功的状态代码。

    我们得到以下成功代码:

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

    但是我们的护照被授权总是产生错误。

    我已经列出了我们所有用于此的文件,并希望得到任何帮助。

    server.js文件:

    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'));
    });

    路由.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');
      });
      
    
    };

    配置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
            }
          }
        }
      };

    护照.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 回复  |  直到 6 年前
        1
  •  0
  •   myclues    6 年前

    我也有类似的问题。如果你看看 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;
    };
    

    我不确定它是passport还是express会话,但是一旦您进入身份验证方法,用户对象将存储在 request.session.passport.user 所以如果您愿意,可以直接验证它是否为非空,而不是使用 已验证() 方法,它似乎检查了错误的路径。

    我的代码在更改为以下代码后开始工作。

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

    (洛达斯 _.get 为了更容易地检查嵌套属性的空值)