passport-saml

Retrieve RelayState value using Passport-SAML


I am unable to retrieve the RelayState value. Can someone please direct me or provide a link to relevant documentation.

This is what I have so far as my setup and routes.

Setup

const saml_strategy = new saml.Strategy(
    {
        'callbackUrl': 'https://callback-url/adfs/postResponse',
        'entryPoint': 'https://entry-url/adfs/ls/',
        'issuer': 'issuer-name',
        'decryptionPvk': fs.readFileSync('./private.key', 'utf-8'),
        'cert': [idp_cert],
        'identifierFormat': null,
   'disableRequestedAuthnContext': true,
   'authnContext': ["urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"],
   'additionalParams':{'RelayState':'test'}
    }, 

Routes

app.get(
    '/', 
    function (req, res) {
        if (req.isAuthenticated()) 
        {
           res.send( '{ "authenticated": true }' );
        } 
        else 
        {
            res.send( '{ "authenticated":  false }' );
        }
    }
);

app.get(
    '/login', 
    passport.authenticate('saml', { 'successRedirect': '/', 'failureRedirect': '/login' }),
    function(req, res) 
      {
        res.redirect('/');
      }
);

///login/callback
app.post(
    '/adfs/postResponse',
    passport.authenticate('saml', { 'failureRedirect': '/', 'failureFlash': true }),
    function(req, res) 
    {
        res.redirect('/');
    }
);

Solution

  • RelayState is set from the query string of the initial login request page, and then (provided the IdP respects it), it is available in the body of the callback POST response.

    So in your case, this should work:

    app.get(
        '/login', 
        function(req, res, next){
            // you could redirect to /login?RelayState=whatever, or set query here,
            // the value must be encoded for passing in the query string:
            req.query.RelayState = encodeURIComponent('my relay state');
        },
        passport.authenticate('saml', { 'successRedirect': '/', 'failureRedirect': '/login' }),
        function(req, res) 
        {
            res.redirect('/');
        }
    );
    
    app.post(
        '/adfs/postResponse',
        passport.authenticate('saml', { 'failureRedirect': '/', 'failureFlash': true }),
        function(req, res) 
        {
            console.log(`relay state was ${decodeURIComponent(req.body.RelayState)}`);
            res.redirect('/');
        }
    );