【问题标题】:Configure nodejs as SP with passport-saml and OpenAM as IDP将 nodejs 配置为 SP,使用 passport-saml 并将 OpenAM 配置为 IDP
【发布时间】:2015-09-24 10:12:31
【问题描述】:

我部署了 OpenAM 并创建了托管 IDP。然后我想将 NodeJs 配置为 Service Provider 并使用 passport-saml 实现 SSO。为此,我必须将我的 node.js 应用程序注册为远程服务提供者。

我有两个问题:

  1. 为了将 NodeJs 应用程序注册为远程服务提供者,我必须告诉 OpenAM URL 元数据所在的位置。如何使用 passport-saml 获取元数据?

  2. 如何配置 passport-saml 以使用 OpenAM?

【问题讨论】:

    标签: node.js passport.js saml-2.0 openam


    【解决方案1】:

    我是这样配置passport-saml的:

    return new SamlStrategy(
        {
    
    entryPoint: "http://ndcdr001s:8081/OpenAM-12.0.0/saml2/jsp/idpSSOInit.jsp?"
          + "metaAlias=/idp"
          + "&spEntityID=http://ndcui.local:9000/metadata/",
    
          callbackUrl: 'http://ndcui.local:9000/login/callback/',
    
          logoutUrl: "http://ndcdr001s:8081/OpenAM-12.0.0/saml2/jsp/idpSingleLogoutInit.jsp?"
          + "binding=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
          + "&RelayState=http://ndcui.local:9000/saml/logout/callback",
    
          issuer: 'http://ndcui.local:9000/'
        },
        function (profile, done) {
    
          return done(null,
            {
              id: profile.id,
              email: profile.email,
             // displayName: profile.cn,
            //  firstName: profile.givenName,
             // lastName: profile.sn,
              sessionIndex: profile.sessionIndex,
              saml: {
                nameID: profile.nameID,
                nameIDFormat: profile.nameIDFormat,
                token:profile.getAssertionXml()
              }
            });
        });    
    

    然后我在 OpenAM 中将“http://ndcui.local:9000/metadata/”注册为 SP。

    我像这样手动为 SP 创建了元数据:并放在此链接下“http://ndcui.local:9000/metadata/

    <EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://ndcui.local:9000/metadata/">
      <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    
        <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"  Location="http://ndcui.local:9000/logout"  Response_Location="http://ndcui.local:9000/saml/logout/callback"/>
    
        <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://ndcui.local:9000/login/callback" index="0"/>
        <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="http://ndcui.local:9000/login/callback" index="1"/>
        <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://ndcui.local:9000/login/callback" index="2"/>
        <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="http://ndcui.local:9000/login/callback" index="3"/>
        <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser" Location="http://ndcui.local:9000/login/callback" index="4"/>
       </SPSSODescriptor>
      <ContactPerson contactType="technical">
        <GivenName>Administrator</GivenName>
        <EmailAddress>noreply@example.org</EmailAddress>
      </ContactPerson>
    </EntityDescriptor>
    

    还有我的路线:

    app.get('/metadata', function (req, res) {
    
     //Send custom metadata
          res.type('application/xml');
          res.sendfile(__dirname + "/metadata.xml");
        }
      );
    
    app.get("/login", passport.authenticate('saml',
          {
            successRedirect: "/",
            failureRedirect: "/login",
          })
      );
    
    app.post('/login/callback', passport.authenticate('saml',
          {
            failureRedirect: '/',
            failureFlash: true
          }),
        function (req, res) {
          res.redirect('/');
        }
      );
    
    app.get('/logout', auth.requiresLogin, function (req, res) {
    
        req.user.nameID = req.user.saml.nameID;
    
        req.user.nameIDFormat = req.user.saml.nameIDFormat;
    
        samlStrategy.logout(req, function (err, request) {
          if (!err) {
            res.redirect(request);
          }
        });
    
      });
    
    app.get('/saml/logout/callback', auth.requiresLogin, function (req, res) {
        //Logout user
        req.logout();
        res.redirect('/');
    
      });
    

    完整实施的链接(您需要谷歌翻译该页面)

    https://qiita.com/nsp01/items/d1b328e5698f6ffd8345

    【讨论】:

    • 策略中不用过证书?
    • 在那种情况下我没有使用证书。
    • ok 登录部分对我有用,但它说 samlStrategy.logout 不是一个函数,你能详细说明一下这个 samlStrategy 变量声明吗?它被声明为:var samlStrategy = require('passport-saml').Strategy;
    • 你必须在你的模块中导出“return new SamlStrategy....”这部分代码并在你需要的地方调用它。
    • '使用严格'; var SamlStrategy = require('passport-saml').Strategy; module.exports = function () { return new SamlStrategy(... }
    【解决方案2】:

    如果您的 SP 不提供任何元数据,那么您可以使用 ssoadm create-metadata-templ 命令生成元数据,该命令应该为您创建一个不错的元数据模板,您应该能够根据需要对其进行自定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      • 2021-06-10
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多