简体   繁体   English

WSO2IS + node.js护照-saml集成错误

[英]WSO2IS + node.js passport-saml integration error

i'm now trying to test SAML2 integration by using wso2is server and node.js passport-saml module. 我现在正尝试使用wso2is服务器和node.js护照-saml模块来测试SAML2集成。 But it sees not working in wso2 side. 但它在wso2端无法正常工作。

node.js server redirect to wso2 server with SAML assertion. 使用SAML断言将node.js服务器重定向到wso2服务器。 here is decoded SAML request assestion 这是解码的SAML请求评估

<?xml version="1.0" encoding="UTF-8"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_e62f87ab1740cab74c67" Version="2.0" IssueInstant="2014-06-16T01:16:54.199Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="https://localhost:3000/login/callback" Destination="https://localhost:9443/samlsso">
   <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">passport-saml</saml:Issuer>
   <samlp:RequestedAuthnContext Comparison="exact">
      <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
   </samlp:RequestedAuthnContext>
   <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true" />
</samlp:AuthnRequest>

after i put user id/password in wso2 log in screen. 在将用户ID /密码放入wso2后,登录屏幕。 i got a error 我有一个错误

SAML 2.0 based Single Sign-On 基于SAML 2.0的单一登录

Error when processing the authentication request! 处理身份验证请求时出错!

Does anybody can give an opinion about this? 有人可以对此发表意见吗?

in wso2is configuration 在wso2is配置中

SP is registered and i only set up Inbound authentication configuration > SAML2 Web SSO Configuration > Issuer : passport-saml. 已注册SP,并且我仅设置“入站身份验证配置”>“ SAML2 Web SSO配置”>“颁发者:passport-saml”。 Assertion consumer URL : http: //localhost:3000/login/callback 断言使用者URL:http://:// localhost:3000 / login / callback

Here is node.js code 这是node.js代码

var express = require('express')
  , passport = require('passport-debug')
  , util = require('util')
  , SamlStrategy = require('../../lib/passport-saml/index').Strategy
  , fs = require('fs');


var users = [
    { id: 1, givenName: 'bob', email: 'bob@example.com' }
  , { id: 2, givenName: 'joe', email: 'joe@example.com' }
];

function findByEmail(email, fn) {
  for (var i = 0, len = users.length; i < len; i++) {
    var user = users[i];
    if (user.email === email) {
      return fn(null, user);
    }
  }
  return fn(null, null);
}


// Passport session setup.
//   To support persistent login sessions, Passport needs to be able to
//   serialize users into and deserialize users out of the session.  Typically,
//   this will be as simple as storing the user ID when serializing, and finding
//   the user by ID when deserializing.
passport.serializeUser(function(user, done) {
  done(null, user.email);
});

passport.deserializeUser(function(id, done) {
  findByEmail(id, function (err, user) {
    done(err, user);
  });
});

passport.use(new SamlStrategy(
  {
    path: '/login/callback',
    entryPoint: 'https://localhost:9443/samlsso',
    issuer: 'passport-saml',

    //protocol: 'http://',
    //cert: 'MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w=='/*,
    //privateCert: fs.readFileSync('./cert.pem', 'utf-8')*/
  },
  function(profile, done) {
    console.log("Auth with", profile);
    if (!profile.email) {
      return done(new Error("No email found"), null);
    }
    // asynchronous verification, for effect...
    process.nextTick(function () {
      findByEmail(profile.email, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          // "Auto-registration"
          users.push(profile);
          return done(null, profile);
        }
        return done(null, user);
      })
    });
  }
));

var app = express.createServer();

// configure Express
app.configure(function() {
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.logger());
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.session({ secret: 'keyboard cat' }));
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
  app.use(express.static(__dirname + '/../../public'));
});


app.get('/', function(req, res){
  res.render('index', { user: req.user });
});

app.get('/account', ensureAuthenticated, function(req, res){
  res.render('account', { user: req.user });
});

app.get('/login',
  passport.authenticate('saml', { failureRedirect: '/error', failureFlash: true,samlFallback:'login-request' }),
  function(req, res) {
    res.redirect('/idc');
  }
);

app.post('/login/callback',
  passport.authenticate('saml', { failureRedirect: '/', failureFlash: true }),
  function(req, res) {
    res.redirect('/idc');
  }
);

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

app.listen(3000, function () {
  console.log("Server listening in http://localhost:3000");
});

// Simple route middleware to ensure user is authenticated.
//   Use this route middleware on any resource that needs to be protected.  If
//   the request is authenticated (typically via a persistent login session),
//   the request will proceed.  Otherwise, the user will be redirected to the
//   login page.
function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) { return next(); }
  res.redirect('/login')
}

additional comment. 附加评论。 After i fixed node.js code. 在我修复了node.js代码之后。 passport.use(new SamlStrategy( 护照使用(新SamlStrategy(

  {
    path: '/login/callback',
    entryPoint: 'https://localhost:9443/samlsso',
    issuer: 'passport-saml',
    protocol: 'http://'

wso2 (idp) response SAML response assertion to node.js passport-saml callback module Here is SAML response assertion from wso2 wso2(idp)响应到node.js护照-saml回调模块的SAML响应声明这是wso2的SAML响应声明

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:3000/login/callback" ID="nnjiingggcmkbagmbndjpcaignnlkcickjadcomp" InResponseTo="_4ca6c18350670c605fa7" IssueInstant="2014-06-16T01:55:28.312Z" Version="2.0">
   <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">localhost</saml2:Issuer>
   <saml2p:Status>
      <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
   </saml2p:Status>
   <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="bpplnakjbmabobeeimjihmelgdebhgcinikjfped" IssueInstant="2014-06-16T01:55:28.312Z" Version="2.0">
      <saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">localhost</saml2:Issuer>
      <saml2:Subject>
         <saml2:NameID>admin</saml2:NameID>
         <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <saml2:SubjectConfirmationData InResponseTo="_4ca6c18350670c605fa7" NotOnOrAfter="2014-06-16T02:00:28.312Z" Recipient="http://localhost:3000/login/callback" />
         </saml2:SubjectConfirmation>
      </saml2:Subject>
      <saml2:Conditions NotBefore="2014-06-16T01:55:28.312Z" NotOnOrAfter="2014-06-16T02:00:28.312Z">
         <saml2:AudienceRestriction>
            <saml2:Audience>passport-saml</saml2:Audience>
         </saml2:AudienceRestriction>
      </saml2:Conditions>
      <saml2:AuthnStatement AuthnInstant="2014-06-16T01:55:28.312Z">
         <saml2:AuthnContext>
            <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef>
         </saml2:AuthnContext>
      </saml2:AuthnStatement>
   </saml2:Assertion>
</saml2p:Response>

but i got a error from passport-saml side like this 但是我像这样从护照saml方面得到了一个错误

127.0.0.1 - - [Mon, 16 Jun 2014 01:55:28 GMT] "GET /login HTTP/1.1" 302 1282 "-"
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chr
ome/35.0.1916.114 Safari/537.36"
SAML:authentication has benn called
SAML:authenticate:error:[object Object]
SAML:authenticate:error:[object Object]
SAML authenticate:PostResponse[object Object]
TypeError: Cannot read property 'Format' of undefined
    at C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passport-saml\lib\passpo
rt-saml\saml.js:425:24
    at Parser.<anonymous> (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\pass
port-saml\node_modules\xml2js\lib\xml2js.js:384:20)
    at Parser.EventEmitter.emit (events.js:95:17)
    at Object.onclosetag (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passp
ort-saml\node_modules\xml2js\lib\xml2js.js:348:26)
    at emit (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passport-saml\node
_modules\xml2js\node_modules\sax\lib\sax.js:615:33)
    at emitNode (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passport-saml\
node_modules\xml2js\node_modules\sax\lib\sax.js:620:3)
    at closeTag (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passport-saml\
node_modules\xml2js\node_modules\sax\lib\sax.js:861:5)
    at Object.write (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passport-s
aml\node_modules\xml2js\node_modules\sax\lib\sax.js:1294:29)
    at Parser.exports.Parser.Parser.parseString (C:\Users\bw.cho\AppData\Roaming
\npm\node_modules\passport-saml\node_modules\xml2js\lib\xml2js.js:403:31)
    at Parser.parseString (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\pass
port-saml\node_modules\xml2js\lib\xml2js.js:6:61)
127.0.0.1 - - [Mon, 16 Jun 2014 01:55:28 GMT] "POST /login/callback HTTP/1.1" 50
0 1310 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/35.0.1916.114 Safari/537.36"

It is little weired that, in WSO2is server SAML assertion response. 有点奇怪,在WSO2中是服务器SAML断言响应。

<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">localhost</saml2:Issuer>

I coded Issuer as "passport-saml" but in the SAML response it has been changed to localhost do u have any idea on this? 我将Issuer编码为“ passport-saml”,但是在SAML响应中,它已更改为localhost,您对此有任何想法吗?

wso2IS配置


added comment. 添加了评论。 in SAML Response attribue "Format" was missing in element. SAML响应属性中缺少元素“格式”。

<saml2:NameID>admin</saml2:NameID>

So i changed configuration in WSO2 SAML configuration. 所以我更改了WSO2 SAML配置中的配置。 I added "NameID format" with "urn:oasis:names:tc:SAML:2.0:nameid-format:entity" After that it seems works. 我用“ urn:oasis:names:tc:SAML:2.0:nameid-format:entity”添加了“ NameID格式”,这似乎可行。 In addition, in SAML response, it doesn't send "email" in SAML response assertion, i did small code change like below. 此外,在SAML响应中,它不会在SAML响应断言中发送“电子邮件”,我做了一些小的代码更改,如下所示。 (instead of using email, it uses user id) (而不是使用电子邮件,而是使用用户ID)

passport.use(new SamlStrategy(
  {
    path: '/login/callback',
    entryPoint: 'https://localhost:9443/samlsso',
    issuer: 'passport-saml',
    protocol: 'http://',
    //identifierFormat :'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'
    identifierFormat :'urn:oasis:names:tc:SAML:2.0:nameid-format:entity'
    //cert: 'MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w=='/*,
    //privateCert: fs.readFileSync('./cert.pem', 'utf-8')*/
  },
  function(profile, done) {
    console.log("Auth with", profile);
    console.log('Name Id',profile.nameID);
    if (!profile.nameID) {
      return done(new Error("No nameId found"), null);
    }
    // asynchronous verification, for effect...
    process.nextTick(function () {
      findByEmail(profile.nameID, function(err, user) {
            console.log('User ',user);
        if (err) {
          return done(err);
        }
        if (!user) {
          // "Auto-registration"
          users.push(profile);
          return done(null, profile);
        }
        return done(null, user);
      })
    });
  }
));

but i still got a error in passport-SAML 但是我的护照SAML仍然有错误

127.0.0.1 - - [Mon, 16 Jun 2014 02:38:05 GMT] "GET /login HTTP/1.1" 302 1322 "-"
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chr
ome/35.0.1916.114 Safari/537.36"
SAML:authentication has benn called
SAML:authenticate:error:[object Object]
SAML:authenticate:error:[object Object]
SAML authenticate:PostResponse[object Object]
SAML:authenticate:errornull
Auth with { issuer:
   { _: 'localhost',
     '$': { Format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity' } },
  nameID: 'admin',
  nameIDFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity' }
Name Id admin
User  { id: 1, givenName: 'bob', email: 'admin' }

TypeError: object is not a function
    at pass (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passport-debug\lib
\passport\index.js:249:14)
    at Passport.serializeUser (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\
passport-debug\lib\passport\index.js:251:5)
    at IncomingMessage.req.login.req.logIn (C:\Users\bw.cho\AppData\Roaming\npm\
node_modules\passport-saml\node_modules\passport\lib\http\request.js:48:29)
    at Context.delegate.success (C:\Users\bw.cho\AppData\Roaming\npm\node_module
s\passport-debug\lib\passport\middleware\authenticate.js:194:13)
    at Context.actions.success (C:\Users\bw.cho\AppData\Roaming\npm\node_modules
\passport-debug\lib\passport\context\http\actions.js:21:25)
    at verified (C:\Users\bw.cho\AppData\Roaming\npm\node_modules\passport-saml\
lib\passport-saml\strategy.js:55:14)
    at C:\dev\workspaces\node_js\SAML2\app.js:68:16
    at findByEmail (C:\dev\workspaces\node_js\SAML2\app.js:17:14)
    at C:\dev\workspaces\node_js\SAML2\app.js:58:7
    at process._tickCallback (node.js:415:13)

I resolved problem. 我解决了问题。 After replace "passport-debug" module to "passport" module, it works full source code is https://github.com/bwcho75/node.js_study/tree/master/WSO2SAML2 enjoy 将“ passport-debug”模块替换为“ passport”模块后,它的完整源代码是https://github.com/bwcho75/node.js_study/tree/master/WSO2SAML2享受

I can answer the part about why the format attribute was required on the subject name -- it's a bug, which I've filed at https://github.com/bergie/passport-saml/issues/40 . 我可以回答有关为何在主题名称上需要format属性的部分-这是一个错误,我已将其提交到https://github.com/bergie/passport-saml/issues/40

Glad to hear you got it working! 很高兴听到您开始使用它!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM