为什么我的SAML断言验证总是报签名无效错误?
我在做第三方SAML登录集成时,用passport-saml解析断言时一直报”Signature validation failed”。已经确认用对方提供的cert文件了,甚至把断言里的证书内容复制到配置里都没用。
尝试过把signatureAlgorithm改成SHA256,但还是不行。这是我的配置片段:
const samlStrategy = new SamlStrategy({
issuer: 'myapp',
cert: fs.readFileSync('idp-cert.pem', 'utf8'),
signatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
}, (profile, done) => {...});
看抓包工具显示断言里确实有<ds:Signature>标签,但验证时总说签名无效。是不是哪里配置漏了?
-----BEGIN CERTIFICATE-----头尾,只留纯Base64内容。把对方证书从断言里拷出来那段Base64粘进配置就行,像这样:
搞定。
先说你的配置,
signatureAlgorithm这个参数其实有点误导人。它只是告诉库你期望用什么算法验证,并不会自动调整对方发过来的签名算法。所以就算你改成了SHA256,如果IDP那边用的是SHA1,还是会失败。重点来了,
cert这块你确认没问题吗?很多人以为IDP给的证书就是对的,但其实有时候它们提供的可能是公钥而不是完整的证书链。你可以试试用OpenSSL把证书内容转成PEM格式再读取:另外,抓包工具看到的
<ds:Signature>标签虽然有,但要确保它的值和证书匹配。最简单的方法是找个在线的XML Signature Validator工具,手动测试一下断言和证书是否能通过。最后提醒一下,有些IDP会搞一套默认的签名算法(比如SHA1),而现代库一般默认支持SHA256以上。这种情况下,最好让对方明确你们双方都支持的算法,然后在配置里写死:
如果还是不行,建议直接打印出解析后的完整断言内容,看看里面有没有隐藏问题。相信我,折腾几次你就明白哪里可能出错了。