This is Sample code I got from passport-saml documentation. Instead of checking email id I want to validate saml assertion, which in turn will indicate that user is authenticated at idp as well, right? Any help is greatly appreciated. Thanks...
const SamlStrategy = require('passport-saml').Strategy;
[...]
passport.use(
new SamlStrategy(
{
path: "/login/callback",
entryPoint:
"https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php",
issuer: "passport-saml",
cert: "fake cert", // cert must be provided
},
function (profile, done) {
// for signon
findByEmail(profile.email, function (err, user) {
if (err) {
return done(err);
}
return done(null, user);
});
},
function (profile, done) {
// for logout
findByNameID(profile.nameID, function (err, user) {
if (err) {
return done(err);
}
return done(null, user);
});
}
)
);
I have found this from some sources, is this the correct finding to achieve the requirement?
const SamlStrategy = require('passport-saml').Strategy;
const xmlCrypto = require('xml-crypto');
const xmlDom = require('xmldom');
passport.use(new SamlStrategy({
// SAML strategy configuration
}, function(profile, done) {
// Validate SAML signature
const isValidSignature = validateSamlSignature(profile);
if (!isValidSignature) {
return done(new Error('Invalid SAML signature'));
}
// Continue with other verification logic and user creation
// ...
if (authenticationIsSuccessful) {
// User is authenticated
const user = /* Construct user object based on SAML attributes */;
done(null, user);
} else {
// User authentication failed
done(new Error('User authentication failed'));
}
}));
function validateSamlSignature(profile) {
const signature = profile.getAssertionXml().getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Signature")[0];
const xml = profile.getSamlResponseXml();
const sig = new xmlCrypto.SignedXml();
sig.keyInfoProvider = {
getKeyInfo: function (key) {
return "<X509Data></X509Data>";
},
getKey: function (keyInfo) {
// Implement key retrieval logic based on your configuration
// For example, load IdP's public key from a file or configuration
const publicKey = '-----BEGIN CERTIFICATE-----\n... (IdP's public key) ...\n-----END CERTIFICATE-----';
return publicKey;
}
};
sig.loadSignature(signature.toString());
return sig.checkSignature(xml);
}
@node-saml/passport-saml verify among other thing signature on behalf of you during autenticate invocation (during processing of SAML autnresponse which IdP delivered via front channel HTTP POST binding). I.e. signature(s) are already verified prior your callback function is invocated.
If you are new to the SAML 2.0 consider studying it before using it at production because it has numerous pitfalls and evaluate SAML libraries capabilities against information from these documents in order to determine if those/your choice meets requirements (passport-saml lacks for example XML schema validation which would be one additional layer of security and it lacks mandatory recipient validation meaning that it is not spec compliant). Here are some good documents: