Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
lib
 
 
src
 
 
 
 
 
 
 
 
 
 

README.md

hapi-passport-saml

A Hapi plugin that wraps passport-saml for SAML SSO (as SP) with support for multiple strategies

Version 2.1.0 is compatible with Hapi 17. For previous version, stay with 1.x.x

Current release

2.1.0

Install

npm install hapi-passport-saml

Configuration

Uses samlidp.io as IdP, read passport-saml for how to use options

const Hapi = require('hapi');
const saml = require('hapi-passport-saml');
const routes = require('./routes/');

const server = Hapi.Server({
  port,
});

const samlOptions = {
  // passport saml settings
  saml: {
    callbackUrl: 'http://localhost/api/sso/v1/assert',
    logoutCallbackUrl: 'http://localhost/api/sso/v1/notifylogout',
    logoutUrl: 'https://my-idp.samlidp.io/saml2/idp/SingleLogoutService.php',
    host: 'localhost',
    protocol: 'http',
    entryPoint: 'https://my-idp.samlidp.io/saml2/idp/SSOService.php',
    // Service Provider Private Signing Key
    privateCert: fs.readFileSync(__dirname + '/privateSigning.pem', 'utf-8'),
    // Service Provider Private Encryption Key
    decryptionPvk: fs.readFileSync(__dirname + '/privateEncryption.pem', 'utf-8'),
    // IdP Public Signing Key
    cert: fs.readFileSync(__dirname + '/publicKey.crt', 'utf-8'),
    issuer: 'my-saml'
  },
  // hapi-passport-saml settings
  config: {
    // Service Provider Public Signing Key *Required if privateCert is provided
    signingCert: fs.readFileSync(__dirname + '/publicKey.crt', 'utf-8'),
    // Service Provider Public Encryption Key *Required if decryptionPvk is provided
    decryptionCert: fs.readFileSync(__dirname + '/publicKey.crt', 'utf-8'),
    // Plugin Routes
    routes: {
      // SAML Metadata
      metadata: {
        path: '/api/sso/v1/metadata.xml',
      },
      // SAML Assertion
      assert: {
        path: '/api/sso/v1/assert',
      },
    },
    assertHooks: {
      // Assertion Response Hook
      // Use this to add any specific props for your business
      // or appending to existing cookie
      // or make use of the RelayState
      onResponse: (profile, request, h) => {
        if(request.payload.RelayState)
          return h.redirect(request.payload.RelayState);
        else
          return h.response();
      },
    }
  }
};

// Internal cookie settings
const schemeOpts = {
  password: '14523695874159852035.0',
  isSecure: false,
  isHttpOnly: false,
  ttl: 3600,
};

(async function start() {
  try {
    await server.register([
      { plugin: saml, options: samlOptions },
    ]);

    await server.auth.strategy('single-sign-on', 'saml', schemeOpts);
    await server.auth.default('single-sign-on');
    await server.route(routes);
    await server.start();
    console.log(`Server listening on ${port}`);
  } catch (e) {
    server.stop();
    console.error('Server stopped due to an error', e);
  }
}());

Note: Internal cookie name is hapi-passport-saml-cookie, if you need to read the SAML credentials for integration with other strategies, use assertion hook.

Multiple strategies

Use hapi-passport-saml as the last strategy. Tested with try and required modes.

  • required: If successful, returns credentials, else HTTP 200 with JSON
  • try: If successful, returns credentials, else empty credentials and isAuthenticated set to false

More info: Integrating hapi cookie with hapi passport saml v1.1.0

Demo application

Demo

References, Ideas and Based from

License

MIT

You can’t perform that action at this time.