node.js - 使用 passport-saml : req. logout() 或 Strategy.logout() 或两者注销?

标签 node.js passport.js saml-2.0

我对使用 passport-saml 进行身份验证时注销用户的正确方法有疑问。

带有 passport-saml 的示例脚本显示注销如下:

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

据我所知,这将结束本地 Passport session ,但它似乎不会向 SAML IdP 发送注销请求。当用户再次登录时,它会重定向到 IdP,但会立即重定向回经过身份验证的用户。有没有一种方法可以使用 IdP 注销,以便用户在登录我的网站时必须再次输入密码?我已经看到其他使用我们的 IdP 的网站这样做,所以我认为这是可能的。

我确实在 passport-saml 代码中注意到 passport-saml 策略对象上有一个 logout() 方法,它似乎没有被 req.logout 调用()。所以我尝试将代码切换为:

app.get('/logout', function(req, res) {
    //strategy is a ref to passport-saml Strategy instance 
    strategy.logout(req, function(){
        req.logout();
        res.redirect('/');
    });
});

但我在 XMLNode.js 中遇到了这个错误

Error: Could not create any elements with: [object Object]
   at XMLElement.module.exports.XMLNode.element (/.../node_modules/passport-saml/node_modules/xmlbuilder/lib/XMLNode.js:74:15)
   at XMLElement.module.exports.XMLNode.element (/.../node_modules/passport-saml/node_modules/xmlbuilder/lib/XMLNode.js:54:25)
   at XMLElement.module.exports.XMLNode.element (/.../node_modules/passport-saml/node_modules/xmlbuilder/lib/XMLNode.js:54:25)
   at new XMLBuilder (/.../node_modules/passport-saml/node_modules/xmlbuilder/lib/XMLBuilder.js:27:19)
   at Object.module.exports.create (/.../node_modules/passport-saml/node_modules/xmlbuilder/lib/index.js:11:12)
   at SAML.generateLogoutRequest (/.../node_modules/passport-saml/lib/passport-saml/saml.js:169:21)

我没有正确调用这个方法吗?还是我不应该直接调用此方法,而是调用其他方法?

我在 generateLogoutRequest() 中看到它指的是 req.user 上的两个我不确定是否存在的属性:

  'saml:NameID' : {
    '@Format': req.user.nameIDFormat,
    '#text': req.user.nameID
  }

如果没有这些属性,会不会导致这个错误?如果是这样,我假设我可能需要确保将这些属性添加到从验证回调函数返回的用户对象中?

感谢任何人在这方面可能提供的任何帮助。

最佳答案

是的,向用户添加 nameIDFormat 和 nameID 将解决问题。

  1. 要启用注销,您应该在策略中配置 logoutURL 选项

logoutUrl: 'http://example.org/simplesaml/saml2/idp/SingleLogoutService.php',

策略中的注销方法实际上并没有发送任何请求。以请求作为参数调用回调函数。

要启动注销过程:

passport.logoutSaml = function(req, res) {
    //Here add the nameID and nameIDFormat to the user if you stored it someplace.
    req.user.nameID = req.user.saml.nameID;
    req.user.nameIDFormat = req.user.saml.nameIDFormat;


    samlStrategy.logout(req, function(err, request){
        if(!err){
            //redirect to the IdP Logout URL
            res.redirect(request);
        }
    });
};

编辑:nameId 和 nameIdFormat 必须在成功登录时保存在某处

var samlStrategy = new SamlStrategy(
  {
    callbackUrl: 'https://mydomain/auth/saml/callback',
    entryPoint: 'https://authprovider/endpoint',
    logoutUrl: 'https://authprovider/logoutEndPoint',
    issuer: 'passport-saml'
  },
  function(profile, done) {

      //Here save the nameId and nameIDFormat somewhere
      user.saml = {};
      user.saml.nameID = profile.nameID;
      user.saml.nameIDFormat = profile.nameIDFormat;

      //Do save

      });
  });
  1. 您还必须为注销回调创建一个端点:

此 URL 应在您的 IdP 配置中的 SP 元数据中配置。注销完成后,IdP 将重定向到该 URL。

在你的 route :

app.post('/auth/saml/logout/callback', passport.logoutSamlCallback);

在您的 Passport 配置中:

passport.logoutSamlCallback = function(req, res){
    req.logout();
    res.redirect('/');
}

关于node.js - 使用 passport-saml : req. logout() 或 Strategy.logout() 或两者注销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25271072/

相关文章:

spring-security - 将 SAML 断言响应/安全上下文传播到下游服务/应用程序

php - Apache 2.4 的 SAML 插件

node.js - Telegram 机器人 - telegraf vs telebot

typescript - 即使在经过身份验证的中间件后面,Express req.user 也是可选的

single-sign-on - 如何使用私钥和公钥创建自签名 x509 证书?

reactjs - 如何设置等同于 fetch 的 { credentials : "include" } in Redux Toolkit's createApi?

node.js - 模仿 Passport 身份验证行为

javascript - 使用 Express API 和 ReactJS SPA 进行路由

node.js - 获取nodeJS中所有用户的流列表

javascript - 如何在 Mongoose 中排除 "upsert-ed"字段?