passport-saml - express - redirected url not submitting form gives SAML assertion not yet valid

五迷三道 提交于 2019-12-13 18:02:00

问题


Below is the error that I am getting on my console today as opposed to yesterday when the same code was working fine.

Error: SAML assertion not yet valid
        at SAML.checkTimestampsValidityError

I have verified that I receive a success from the IDP and hence the application gets redirected to the '/home' endpoint in the URL which has been mentioned in the config file.

Additionally, when I submit the form, after an auto redirection [which shows me Internal Server Error]

I press refresh button of the browser and a form submission happens and the expected result is achieved.

My problem is, why doesn't this happens automatically or how and where can I do this submission programatically.

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(
    {
      entryPoint: config.passport.saml.entryPoint,
      issuer: config.passport.saml.issuer,
      cert: config.passport.saml.cert,
      path: config.passport.saml.path,
      identifierFormat: config.passport.saml.identifierFormat
    },
    function (profile, done) {

      debugger;
      return done(null,
        {
          sessionIndex: profile.sessionIndex,
          nameID: profile.nameID,
          lastName: profile.lastName,
          firstName: profile.firstName,
          gid: profile.gid,
          county: profile.county,
          mail: profile.mail,
          companyUnit: profile.companyUnit,
          preferredLanguage: profile.preferredLanguage,
          orgCode: profile.orgCode,
          email: profile.email
        });
    })
  );

};

config.js

module.exports = {
      passport: {
        strategy: 'saml',
        saml: {
          callbackUrl: '/home',
          path: '/home',
          entryPoint: 'https://.../GetAccess/Saml/IDP/SSO/Unsolicited?GA_SAML_SP=APP',
          issuer: '...',
          cert: '...',
          identifierFormat: null
        }
      }
  };

app.js

import express from 'express';
import helmet from 'helmet';
import cookieParser from 'cookie-parser';
import bodyparser from 'body-parser';
import path from 'path';
import logger from 'morgan';
import cors from 'cors';
import passport from 'passport';
import session from 'cookie-session';

const config = require('./config.js');
require('./passport')(passport, config);
var app = express();
app.use(logger('dev'));
app.use(cookieParser());
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: false }));
app.use('/public', express.static(path.join(__dirname, '../public')));
app.use('/data', express.static(path.join(__dirname, '../uploads/')));
app.use(session(
  {
    resave: true,
    saveUninitialized: true,
    secret: 'secret value'
  }));
app.use(passport.initialize());
app.use(passport.session());
app.use(helmet());
app.use(cors());

require('../router/routeConfig')(app, config, passport);

module.exports = app;

routeConfig.js

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


  app.get('/', passport.authenticate(config.passport.strategy, {
    successRedirect: '/home',
    failureRedirect: 'https://.../GetAccess/Saml/IDP/SSO/Unsolicited?GA_SAML_SP=APP'
  }));

  app.get('/app', passport.authenticate(config.passport.strategy, {
    successRedirect: '/home',
    failureRedirect: 'https://.../GetAccess/Saml/IDP/SSO/Unsolicited?GA_SAML_SP=APP'
  }));

  app.post(config.passport.saml.path,
    passport.authenticate(config.passport.strategy,
      {
        failureRedirect: 'https://.../GetAccess/Saml/IDP/SSO/Unsolicited?GA_SAML_SP=APP',
        failureFlash: true
      }),
    function (req, res) {
      debugger;
      res.sendFile(path.join(__dirname, "../public/index.html"));
    });

};

回答1:


Finally I have figured this out after some research,

As we understand that there are two parties involved in the SAML Authentication Process i.e. IDP and SP, therefore there are certain conditions between these which are supposed to be met, as part of the contract. One such condition is the TIME.

<saml:Conditions NotBefore="2019-08-01T11:02:49Z" NotOnOrAfter="2019-08-01T11:03:59Z">

This is a tag that I have clipped from the saml response received from the IDP, here the time of my(SP's) server should be between NotBefore and NotOnOrAfter during the process of authentication.

Therefore, I need to calibrate the clock of my server by a few seconds so that I fit in the time-slice of NotBefore and NotOnOrAfter of the server.

Of course that is not the way this should be done, but some +n or -n minutes should be allowed from the IDP side (importantly both SP and IDP to follow UTC times).

More on this topic can be found here,

SAML Assertion NotBefore,NotOnOrAfter problem due to unsynced clocks : Explained

ADFS Not Before Time Skew

Bonus

Base 64 to XML Decoder

XML Prettifier

Edit :

As mentioned in the comment below, The skew can be configured on either side (IdP > or SP) or both sides. From passport-saml docs: acceptedClockSkewMs: Time in milliseconds of skew that is acceptable between client and server when checking OnBefore and NotOnOrAfter assertion condition validity timestamps. Setting to -1 will disable checking these conditions entirely. Default is 0.

Mentioned Here



来源:https://stackoverflow.com/questions/57290983/passport-saml-express-redirected-url-not-submitting-form-gives-saml-assertio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!