3

Still a noob!

I am working on to build a Node application, and I have already setup various required end points. One of the requirements for my project is to use authentication using SAML mechanism. I am using passport-SAML for authentication in my application.

So far, I have been able to setup and use SAML strategy, and my application is able to call the idp entry point, and receive the response back from Idp.

I am unable to understand how do we access the user information returned by idp, so that I can use the SAML returned user information to create and maintain sessions.

const saml = require('passport-saml');

module.exports = function (passport, config) {

  passport.serializeUser(function (user, done) {
    done(null, user);
  });

  passport.deserializeUser(function (user, done) {
    done(null, user);
  });

  var samlStrategyOptions = new saml.Strategy(
    {
      // URL that goes from the Identity Provider -> Service Provider
      callbackUrl: config.passport.saml.callback_url,
      // path: config.passport.saml.path,
      // URL that goes from the Service Provider -> Identity Provider
      entryPoint: config.passport.saml.entryPoint,
      issuer: config.passport.saml.issuer,
      identifierFormat: null,
      // Service Provider private key
      decryptionPvk: config.passport.saml.decryptionPvk,
      // Service Provider Certificate
      privateCert: config.passport.saml.privateCert,
      // Identity Provider's public key
      cert: config.passport.saml.cert,
      validateInResponseTo: false,
      disableRequestedAuthnContext: true
    },
    function (profile, done) {
      return done(null,
        {
          id: profile.uid,
          email: profile.email,
          displayName: profile.cn,
          firstName: profile.givenName,
          lastName: profile.sn
        });
    })


  // module.exports.samlStrategyOptions = samlStrategyOptions  ;
  passport.use(samlStrategyOptions);

};

Following are my route controllers for express

router.route('/login')

.get(
    passport.authenticate(config.passport.strategy,
      {
        successRedirect: '/',
        failureRedirect: '/login'
      })
);

router.route('/login/callback/')

.post(
    passport.authenticate(config.passport.strategy,
      {
        failureRedirect: '/',
        failureFlash: true
      }),
    function (req, res) {

      res.redirect('/');
    }
);

And this is a SAML snippet of properties that I recieve in response from Idp.

<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">Shubham123</saml:NameID>
shubhammakharia
  • 147
  • 1
  • 2
  • 10
  • hi could you please share how you were able to extract the SAML xml from the response? – Sumit May 11 '20 at 18:59
  • 1
    @Sumit in response, there are these functions available: getAssertion, getAssertionXml and getSamlResponseXml. – Ankit Oct 15 '20 at 04:39

3 Answers3

0

I was getting the same. SO I have used body-parser as middleware

 // middleware to parse HTTP POST's JSON, buffer, string,zipped or raw and URL encoded data and exposes it on req.body
app.use(bodyParser.json());
// use querystring library to parse x-www-form-urlencoded data for flat data structure (not nested data)
app.use(bodyParser.urlencoded({ extended: false }));

and then you will get the profile like

{ issuer: '',
   sessionIndex: '_x0P5ZeWx-ACSQAulKgVTxSquNsVdac_H',
   nameID: 'auth0|5a266569083226773d5d43a9',
   nameIDFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified',
   nameQualifier: undefined,
   spNameQualifier: undefined,
   'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier': 'auth0|s9ds',
   'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress': 'myuser@q.com',
   'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name': 'myuser@q.com',
   'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn': 'myuser@q.com',
   'http://schemas.auth0.com/identities/default/provider': 'auth0',
   'http://schemas.auth0.com/identities/default/connection': 'Username-Password-Authentication',
   'http://schemas.auth0.com/identities/default/isSocial': 'false',
   'http://schemas.auth0.com/email_verified': 'false',
   'http://schemas.auth0.com/clientID': 'bZVOM5KQmhyir5xEYhLHGRAQglks2AIp',
   'http://schemas.auth0.com/picture': 'https://s.gravatar.com/avatar/e85e57405a82225ff36b5af793ed287c?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fsu.png',
   'http://schemas.auth0.com/nickname': 'myuser',
   'http://schemas.auth0.com/identities': '[object Object]',
   'http://schemas.auth0.com/updated_at': 'Mon Dec 18 2017 12:14:28 GMT+0000 (UTC)',
   'http://schemas.auth0.com/created_at': 'Tue Dec 05 2017 09:22:49 GMT+0000 (UTC)',
   getAssertionXml: [Function] }

and create user by extracting data like

{ id: profile["nameID"], userName: profile["http://schemas.auth0.com/nickname"] }
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
0

In order to get the user details, in your IDP's console, you have to setup the parameters in SP settings which you want the IDP to return and you'll get them in the assertion. This is what I did in onelogin: onelogin

Ankit
  • 143
  • 1
  • 8
0

I'm using the node-saml passport module and I found this example very useful. To summarize, once the SAML process is resolved, (your IdP is making a POST callback to your handler), the user data is stored in the request object. Now, if you want to get that user data, for example in any GET request, you could do the following:

    app.get('/logout', function(req, res) {
    console.log('logout');
    console.log(req.user);
    req.logout();
    res.redirect(config.passport.saml.logoutCallback);
});

Where req.user contains all your user data. In the example, req.user contains the following:

{
firstName: 'local givenName',
lastName: 'local lastname',
email: 'testUser@sample.com'
}