3

下面是我今天在控制台上遇到的错误,而不是昨天相同代码运行良好的错误。

Error: SAML assertion not yet valid
        at SAML.checkTimestampsValidityError

我已经验证我从IDP收到了成功,因此应用程序被重定向到配置文件中提到的 URL 中的“/home”端点。

此外,当我提交表单时,在自动重定向后 [显示内部服务器错误]

在此处输入图像描述

我按下浏览器的刷新按钮并提交表单并达到预期的结果。

在此处输入图像描述

我的问题是,为什么这不会自动发生,或者我可以如何以及在哪里以编程方式进行此提交。

护照.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
        });
    })
  );

};

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

应用程序.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"));
    });

};
4

2 回答 2

3

如上所述,将 'acceptedClockSkewMs: -1' 添加到您的 passport-saml 策略配置可以解决错误。

例子:

const strategy = new SamlStrategy(
  {
    path: "/api/auth/callback",
    entryPoint: process.env.SAML_ENTRY_POINT, // identity provider entrypoint
    issuer: issuer,
    cert: process.env.SAML_CERT,
    acceptedClockSkewMs: -1 // SAML assertion not yet valid fix
  }, function(profile, done){...}
于 2020-03-23T02:21:39.413 回答
2

经过一番研究,我终于弄清楚了,

据我们了解,SAML 身份验证过程涉及两方,即IDPSP,因此作为合同的一部分,它们之间应该满足某些条件。一种这样的条件是TIME

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

这是我从 IDP 收到的 saml 响应中截取的一个标签,这里我的(SP 的)服务器的时间在身份验证过程中应该介于NotBeforeNotOnOrAfter之间。

因此,我需要将服务器的时钟校准几秒钟,以适应服务器的NotBeforeNotOnOrAfter时间片 。

当然,这不是应该这样做的方式,但是应该允许 IDP 端一些 +n 或 -n 分钟(重要的是 SP 和 IDP 都遵循 UTC 时间)

可以在此处找到有关此主题的更多信息,

由于时钟不同步导致的 SAML 断言 NotBefore、NotOnOrAfter 问题:解释

ADFS 不是在时间偏差之前

奖金

Base 64 转 XML 解码器

XML 美化器

编辑 :

正如下面评论中提到的,可以在任一侧(IdP > 或 SP)或两侧配置偏斜。来自 passport-saml 文档:acceptedClockSkewMs:检查 OnBefore 和 NotOnOrAfter 断言条件有效性时间戳时,客户端和服务器之间可接受的偏移时间(以毫秒为单位)。设置为 -1 将完全禁用检查这些条件。默认值为 0。

这里提到

于 2019-08-01T11:47:51.110 回答