WSO2IS + node.js passport-saml 集成错误
Posted
技术标签:
【中文标题】WSO2IS + node.js passport-saml 集成错误【英文标题】:WSO2IS + node.js passport-saml integration error 【发布时间】:2014-08-05 19:15:41 【问题描述】:我现在正在尝试使用 wso2is 服务器和 node.js passport-saml 模块来测试 SAML2 集成。 但它认为在 wso2 方面不起作用。
node.js 服务器重定向到带有 SAML 断言的 wso2 服务器。 这是解码的 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>
在我将用户 ID/密码输入 wso2 登录屏幕后。 我有一个错误
基于 SAML 2.0 的单点登录
处理认证请求时出错!
有人可以对此发表意见吗?
在 wso2is 配置中
SP 已注册,我只设置入站身份验证配置 > SAML2 Web SSO 配置 > 颁发者:passport-saml。 断言消费者 URL:http://localhost:3000/login/callback
这里是 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')
附加评论。 在我修复了 node.js 代码之后。 护照.use(新的 SamlStrategy(
path: '/login/callback',
entryPoint: 'https://localhost:9443/samlsso',
issuer: 'passport-saml',
protocol: 'http://'
wso2 (idp) 对 node.js passport-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>
但我从护照-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"
奇怪的是,在 WSO2 中是服务器 SAML 断言响应。
<saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">localhost</saml2:Issuer>
我将 Issuer 编码为“passport-saml”,但在 SAML 响应中它已更改为 localhost 你对此有什么想法吗?
添加评论。 元素中缺少 SAML 响应属性“格式”。
<saml2:NameID>admin</saml2:NameID>
所以我更改了 WSO2 SAML 配置中的配置。 我用“urn:oasis:names:tc:SAML:2.0:nameid-format:entity”添加了“NameID 格式” 在那之后它似乎有效。 此外,在 SAML 响应中,它不会在 SAML 响应断言中发送“电子邮件”,我做了如下的小代码更改。 (而不是使用电子邮件,它使用用户 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);
)
);
));
但我仍然在护照 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)
【问题讨论】:
【参考方案1】:我可以回答为什么主题名称需要格式属性的部分——这是一个错误,我已在https://github.com/bergie/passport-saml/issues/40 提交。
很高兴听到您成功了!
【讨论】:
【参考方案2】:我解决了问题。 将“passport-debug”模块替换为“passport”模块后,它可以工作 完整的源代码是https://github.com/bwcho75/node.js_study/tree/master/WSO2SAML2 享受
【讨论】:
以上是关于WSO2IS + node.js passport-saml 集成错误的主要内容,如果未能解决你的问题,请参考以下文章
Node.js 和 Passport 对象没有方法 validPassword
Express Passport (node.js) 错误处理
使用 Sails.JS 框架的 Node.JS -- Passport:没有在名称下注册策略:facebook
为移动应用程序进行 facebook 登录的正确方法是啥(使用 node.js/passport.js 服务器)