SAML SSO with Gluu Shibboleth: SP Initiated Flow - kdhttps/node-passport GitHub Wiki
SAML SSO
In this blog, I am going to describe to you about SAML SSO SP(Service Provider) Initiated flow, SAML configuration in Gluu CE(Shibboleth SAML IDP), and Configure your Node Application as a Service Provider(SP).
Prerequisite
- Node JS >= v12.x.x
- NPM >= v6.x.x
- Clone or download node-passport for quick SP configuration. You can make your own also.
- Gluu CE with Shibboleth SAML IDP >= 4.x.x, during Gluu CE installation it will ask you
Install Shibboleth SAML IDPand you need to install SAML IDP into your Gluu CE. Check here for more details about Gluu Server
Terminology
1. IDP
It stand for Identity Provider. It is just a SAML server that follows the SAML Open Standard and provides authentication and authorization facilities.
For Example: Shibboleth SAML IDP which comes with Gluu CE. During the installation of Gluu CE, you will get prompt to install Shibboleth SAML, enter Yes and install it.
2. SP
Service Provider is the application or software which users are use to access facilities, features and you can say protected resources.
For example: You have one File Storage application where you are storing your all data. Before accessing this data, it prompts or show a login page to you for security and authentication. So here your File Storage application use Gluu Shibboleth SAML IDP to authenticate you and secure your data. In this the File Storage application is SP and Gluu Shibboleth is SAML IDP.
What is SSO?
You need to login once and you can use any application of Currently logged in organization.
For Example: You login to Google Gmail one application then you can use Google Drive, Google Keep Node, and other Google Applications.
What is SAML?
SAML is Security Assertion Markup Language where it defines some open standard to exchanging authentication and authorization data between IDP(Identity Provider) and SP(Service Provider). It is like a framework where defines many flows and clearly defines how to request and respond for auth so that you can achieve authentication, authorization, and Single Sign-On(SSO) feature with Full Security features.
SP Initiated Flow
There are many flows in SAML. Currently, we are trying the most common and used flow that is SP initiated flow. In which the SP first request for user authentication to the IDP
www.websequencediagrams.com
title SAML SSO SP Initiated Flow
user->SP: Click on the login button on page or request for protected data
SP->IDP: SAML authentication request
IDP->user: Prompt and show login page
note left of IDP: If the user already logged in then directly allow ie. SSO
user->IDP: enter credentials
IDP->IDP: authenticate the user
IDP->SP: send authentication response to SP i.e. SAML Assertion
SP->user: Verify user and allow access to use protected data

Integration and Implementation
Step 1 SP Configuration: Register Passport-SAML strategy
We are here making our custom SP(Nodejs App) which requests IDP for user authentication. We are using Passport-SAML to make it easy.
For demo, I've created and using node-passport as a Service Provider, Code is here.
- As per my code, Node SP is running on
http://localhost:4200 - Gluu IDP is running on
https://gluu.mali.org - Callback URL as per my code is
http://localhost:4200/auth/saml/redirect. IDP send back to SP with SAML assertion to this endpoint and it should beHTTP POSTas per current configuration. In SAML language it is known asACS(Assertion Consumer Service) URL.
I am using the Passport SAML client in my Node Application. It is a good library or client that provides many facilities to quickly configure the SAML SSO into your Node application. More details
First thing we need to register the passport-saml strategy.
const PassportSAMLStrategy = require('passport-saml').Strategy;
samlConfig: {
entryPoint: 'https://gluu.mali.org/idp/profile/SAML2/POST/SSO',
identifierFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient',
authnRequestBinding: 'HTTP-POST',
issuer: 'passport_saml_rp',
skipRequestCompression: true,
callbackUrl: 'http://localhost:4200/auth/saml/redirect',
cert: 'MIIDbTC...Z5X7Ykd/DrrGc=',
requestIdExpirationPeriodMs: 3600000,
decryptionPvk: '-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0MQHOuNNQ6c...LAOWSw==\n-----END RSA PRIVATE KEY-----\n'
}
const oPassportOIDCStrategy = new PassportSAMLStrategy(strategyConfig.samlConfig,
// verfiy
(profile, done) => {
console.log('--- SAML Response ---', profile)
return done(null, { id: profile['urn:oid:0.9.2342.19200300.100.1.3'], name: profile['urn:oid:2.16.840.1.113730.3.1.241'] })
}
)
passport.use(
oPassportOIDCStrategy
)
Step 2 SP Configuration: What is cert in passport samlConfig? How to get it?
It is the IDP's public signing certificate used to validate the signatures of the incoming SAML Responses.
As Per Gluu settings you can get this in https://[your-idp-url]/idp/shibboleth. In my case, I use https://gluu.mali.org/idp/shibboleth.
Copy the public cert from <ds:X509Certificate> tag inside of <KeyDescriptor use="signing"> and past it into passport config key cert.
Step 3 SP Configuration: What is decryptionPvk in passport samlConfig? How to get it?
It is a private key that will be used to attempt to decrypt any encrypted assertions that are received by our node application.
As Per gluu settings you can get this key in gluu chroot and the path is /etc/certs/passport-sp.key. Open this file copy content and past it into decryptionPvk in passport config.
Step 4 SP Configuration: Generate a Service Provider(SP) metadata
In this step, we will generate the SP metadata and register it into Gluu IDP as a Trust Relationship.
I've created the Node CLI Program where you can easily pass some certs details and generate an SP metadata file.
The program is here
You need to set two certs in file.
decryptionCert:/etc/certs/passport-sp.crtinGluu CECasesigningCert: the cert fromhttps://<your.idp.com>/idp/shibbolethendpoint in sidesigning>ds:X509Certificate. It is same which we pass in passportcertconfig above.
After settings values, run below command
$ node generate-service-provider-metadata.js
It will generate local.xml in the current directory. The next step is to register this XML into your Gluu IDP as SP Metadata so that In SMAL Request your IDP can verify your SP.
Step 5 Gluu IDP Configuration: Create TR(Trust Relationship) in Gluu IDP
- Go to Gluu Admin UI - oxTrust identity
- Go to menu SAML > Add Trust Relationship
- Add whatever you want in
Display NameandDescription - Select entity type
Single SP - Select Metadata local
File - Select your
local.xmlfile - Skip Logout URL for now
- Check the box of
Configure Relying Party:then click onConfigure Relying Party- the right side of the checkbox - Now it will open one model popup
- Select
SAML2SSOand Add - Enter
assertionLifetime: 300000 - Select
Sign Responses: Always - Select
Sign Assertions: Never - Select
Sign Request: Conditional - Select
Encrypt Assertions: Always - Select
Encrypt Name IDs: Always - Select
Default Authn Methods: urn:oasis:names:tc:SAML:2.0:ac:classes:Password - Checked true
includeAttributeStatement? - Checked true
Support Unspecified NameIdFormat? - Select
SAML:2.0:nameid-format:transientand add - Now
Release additional attributeswhich is at the right side, select the attribute you want after authentication. - Click on Save
Step 6 Gluu IDP Configuration: Enable passport-saml script in Gluu IDP
Gluu has some custom authentication script by which you can control the authentication flow at IDP. for saml you need to enable the passport_saml script. Check Gluu CE Docs here for more details.
In passport_saml script there is one more option for SAML ACRs Select SAML ACRS: so select all acrs and update script.
Step 7 SP Configuration: Authentication request in Node App
This is available in code here. Let's take a quick look again.
router.get(`/auth/saml/`, passport.authenticate('saml', {}))
router.post(`/auth/saml/redirect`, bodyParser.urlencoded({ extended: false }), passport.authenticate('saml', {}))
There are two things
-
It will generate SAML request as per configuration in passport saml strategy and redirect you to IDP Page for authentication.
-
After user authentication at IDP side, IDP redirect back to this endpoint with an
HTTP Postrequest and SAML Assertion
If all is ok then your control will be passed to passport verify section:
const oPassportSAMLStrategy = new PassportSAMLStrategy(strategyConfig.samlConfig,
// verfiy section
(profile, done) => {
console.log('--- SAML Response ---', profile)
return done(null, { id: profile['urn:oid:0.9.2342.19200300.100.1.3'], name: profile['urn:oid:2.16.840.1.113730.3.1.241'] })
}
)
And In profile, you will get your user information.
Thank you !!!