ExpressJS / Passport-SAML单一注销直接重新登录

当前,我正在我们的NodeJS应用程序中从事护照护照的实施。 这样做的原因是使我们的客户可以连接到他们的AD FS系统并利用SingleSignOn(SSO)。

由于我们还希望提供注销功能,因此我正在研究该逻辑。但是,我似乎无法使这个简单的功能起作用。我已经在Google上搜索了很多,尝试了许多变体和配置,但不幸的是,它不起作用。

我希望为我们的客户提供同时受SP和IdP驱动的SingleLogOut(SLO)的可能性。这是我的出发点。在调试和开发过程中,我已经退后一步,尝试终止本地会话,但看来这是不可能的。

这是我为SAML配置的路由中的相关代码:

const isAuthenticated = (req,res,next) => {
    if (req.isAuthenticated()) {
      // User logged in,pass on to next middleware
      console.info('User authenticated');
      return next();
    }
    // User not logged in,redirect to login page
    console.info('User not authenticated');
    return res.redirect('/login');
  };

// GET-routes
  app.get('/',isAuthenticated,(req,res) => {
      res.send('Authenticated');
    });

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

  app.get('/logout',res) => {
      passport._strategy('saml').logout(req,(err,url) => {
        return res.redirect(url);
      });
    });

// POST-routes
  app.post('/adfs/callback',next) => {
      passport.authenticate('saml',user) => {
        // If error occurred redirect to failure URL
        if (err) return res.redirect('/login/fail');
        // If no user could be found,redirect to failure URL
        if (!user) return res.redirect('/login/fail');
        // User found,handle registration of user on request
        req.logIn(user,(loginErr) => {
          if (loginErr) return res.status(400).send(err);
          // Request session set,put in store
          store.set(req.sessionID,req.session,(storeErr) => {
            if (storeErr) return res.status(400).send(storeErr);
            return res.redirect('/');
          });
        });
      })(req,next);
    });

  app.post('/logout/callback',res) => {
    // Destroy session and cookie
    store.destroy(req.sessionID,async (err) => {
      req.logout();
      return res.redirect('/');
    });
  });

可以看出,我控制了会话存储的处理(设置和销毁会话,但是如果这样做不明智,请告知)。 实现的会话存储是MemoryStore(https://www.npmjs.com/package/memorystore)。

发生的事情是,当用户登录时,一切正常。 然后将请求发送到路由/登出,并且发生了一些事情,我可以看到会话发生了变化,会话ID发生了更改,以及passport-saml的相关参数(nameID,sessionIndex),然后将用户重新路由到了'/ '。

但是,随后该用户被视为未通过身份验证,并被重新路由到'/ login'。有人会说它到此为止,因为必须重新输入凭据。 情况并非如此,因为用户可以直接登录而无需重新输入凭据,而且我不知道如何防止这种情况。

我确实希望任何人都知道发生了什么事:) 如果需要其他信息,我很高兴听到。

SophiaBJ 回答:ExpressJS / Passport-SAML单一注销直接重新登录

因此,经过大量研究和调查,我确实找到了解决此问题的方法。 诀窍在于定义了password-saml软件包,尤其是authncontext参数。

所以以前我将SamlStrategy选项定义为:

{
  // URL that should be configured inside the AD FS as return URL for authentication requests
  callbackUrl: `<URL>`,// URL on which the AD FS should be reached
  entryPoint: <URL>,// Identifier for the CIR-COO application in the AD FS
  issuer: <identifier>,identifierFormat: null,// CIR-COO private certificate
  privateCert: <private_cert_path>,// Identity Provider's public key
  cert: <cert_path>,authnContext: ["urn:federation:authentication:windows"],// AD FS signature hash algorithm with which the response is encrypted
  signatureAlgorithm: <algorithm>,// Single Log Out URL AD FS
  logoutUrl: <URL>,// Single Log Out callback URL
  logoutCallbackUrl: `<URL>`,}

但是经过大量研究,我意识到此authentication:windows选项是罪魁祸首,所以我将其更改为:

{
  // URL that should be configured inside the AD FS as return URL for authentication requests
  callbackUrl: `<URL>`,authnContext: ["urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport","urn:federation:authentication:windows"],},

这基本上意味着它不会检索默认情况下登录到系统的用户的Windows凭据,从而重定向到ADFS服务器的登录屏幕。

,

在会话设置中使用authnContext:[“ urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”]注销后将再次显示用户名和密码页面。

注销已实现https:// adfs-url / adfs / ls /?wa = wsignout1.0。

再次登录后,会创建一个新的会话ID。

本文链接:https://www.f2er.com/2970654.html

大家都在问