Passport is authentication middleware for Node.js. Extremely flexible and modular, Passport can be unobtrusively dropped into any Express-based web application. Password also have a collection of authentication strategies, one of which provides a SAML2 authentication provider which is the main focus of this blog post based on the following components:
6.4.x
11
Apereo CAS can be configured to act as a standalone SAML2 identity provider to integrate with and support SAML2 service providers such as our to-be-developed Node.js application via appropriate SAML2 metadata exchanges to establish mutual trust. This metadata exchange and the registration step is done with CAS using the following JSON snippet:
{
"@class": "org.apereo.cas.support.saml.services.SamlRegisteredService",
"serviceId": "passport-saml",
"name": "SAML",
"id": 1,
"evaluationOrder": 1,
"metadataLocation": "http://localhost:3000/metadata",
"attributeReleasePolicy" : {
"@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
}
}
Do note that,
metadataLocation
.passport-saml
.If you are well-versed in the ways of Node.js, you should be able to put together an Express-js web application fairly quickly and put Passport-SAML inside it. In this section, I will only highlight the specifics of the integration and things that should be of note.
To set up the SAML2 service provider configuration, you will need to generate a pair of keys:
cd ./credentials
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout sp.key -out sp.crt
You will be using the generated private key, along with the identity provider’s entry point and SAML2 signing certificate to set up the service provider configuration:
passport: {
strategy: 'saml',
saml: {
callbackUrl: 'http://localhost:3000/login/callback',
path: '/login/callback',
entryPoint: 'https://sso.example.org/cas/idp/profile/SAML2/Redirect/SSO',
issuer: 'passport-saml',
cert: fs.readFileSync('/path/to/idp-signing.crt', 'utf-8'),
decryptionPvk: fs.readFileSync('./credentials/sp.key', 'utf-8'),
}
}
Note the issuer
here represents the SAML2 entity id of the Node.js application.
The SamlStrategy
strategy should now be created via Passport-SAML as the effective and active authentication provider:
const strategy = (passport, config) => {
let strategy = new SamlStrategy(
config.passport.saml,
function (profile, done) {
return done(null,
{
id: profile.uid,
email: profile.email,
profile: profile.profile,
name: profile.name,
username: profile.username
});
});
passport.use(strategy);
return strategy;
};
Note the mappings and extraction of identity provider attributes from the profile that are released to the service provider. Such attributes can then be used in the authenticated session to display user data.
We’ll need to put together a URL that exposes our SAML2 service provider configuration. Passport-SAML does not automatically generate or store SAML2 service provider metadata, but exposes options for one to create it on the fly:
app.get('/metadata',
function(req, res) {
const cert = fs.readFileSync('./credentials/sp.crt', 'utf-8');
res.type('application/xml');
// strategy is `SamlStrategy`
res.send(strategy.generateServiceProviderMetadata(cert));
}
);
To start, this would be our humble home page for the Node.js application:
We can visit the /metadata
URL to take a look at our SAML2 service provider metadata:
Once after a successful authentication attempt with CAS as a SAML2 identity provider, we can retrieve and display user profile data:
If you have questions about the contents and the topic of this blog post, or if you need additional guidance and support, feel free to send us a note and ask about consulting and support services.
I hope this review was of some help to you and I am sure that both this post as well as the functionality it attempts to explain can be improved in any number of ways. Please feel free to engage and contribute as best as you can.
Happy Coding,
Monday-Friday
9am-6pm, Central European Time
7am-1pm, U.S. Eastern Time
Monday-Friday
9am-6pm, Central European Time