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

Dav*_*rns 8 node.js saml-2.0 passport.js

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

带护照-saml的示例脚本显示如下:

app.get('/logout', function(req, res){
  req.logout();
  res.redirect('/');
});
Run Code Online (Sandbox Code Playgroud)

据我所知,这将结束本地护照会话,但它似乎没有向SAML IdP发送注销请求.当用户进行另一次登录时,它会重定向到IdP,但会立即重新定向到经过身份验证的用户.有没有办法使用IdP注销,以便用户在登录我的网站时必须再次输入密码?我见过其他使用我们IdP的网站这样做,所以我认为这是可能的.

我在passport-saml代码中注意到logout(),在passport-saml策略对象上有一个方法,似乎没有被调用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('/');
    });
});
Run Code Online (Sandbox Code Playgroud)

但是我在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)
Run Code Online (Sandbox Code Playgroud)

我没有正确地调用这种方法吗?或者我不应该直接调用此方法并调用其他方法吗?

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

  'saml:NameID' : {
    '@Format': req.user.nameIDFormat,
    '#text': req.user.nameID
  }
Run Code Online (Sandbox Code Playgroud)

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

感谢任何人都可以提供的任何帮助.

bpa*_*vot 8

是的,将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);
        }
    });
};
Run Code Online (Sandbox Code Playgroud)

编辑: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

      });
  });
Run Code Online (Sandbox Code Playgroud)
  1. 您还必须为注销回调创建一个终点:

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

在你的路线:

app.post('/auth/saml/logout/callback', passport.logoutSamlCallback);
Run Code Online (Sandbox Code Playgroud)

在您的护照配置中:

passport.logoutSamlCallback = function(req, res){
    req.logout();
    res.redirect('/');
}
Run Code Online (Sandbox Code Playgroud)

  • @DaNeSh你在stratey回调的profile参数中有它 (2认同)