SAML Protocol Identity Provider Middleware

8.0.0 · active · verified Tue Apr 21

samlp is a Node.js middleware library designed to facilitate the creation of SAML Protocol Identity Provider (IdP) endpoints. It handles the complexities of generating SAML responses and metadata, allowing developers to focus on user authentication mechanisms. The current stable version is 8.0.0, released March 31, 2026. This library is actively maintained by Auth0 and sees releases for new features, bug fixes, and dependency updates, typically on a monthly to quarterly cadence. Its key differentiator is its focus specifically on the IdP side of SAML, providing a configurable Express/Koa-compatible middleware, in contrast to libraries that are more general-purpose or service provider-centric. It requires Node.js version 12 or greater, reflecting modern Node.js ecosystem practices.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart sets up a basic SAML Identity Provider (IdP) using Express and samlp, exposing login and metadata endpoints. It demonstrates how to configure the core `samlp.auth` middleware with required options like issuer, certificates, and a placeholder for the `getPostURL` and `getUserFromRequest` functions. It assumes a pre-authenticated `req.user` for simplicity. **Note**: Requires `some-cert.pem` and `some-cert.key` in the project root.

import express from 'express';
import samlp from 'samlp';
import fs from 'fs';
import path from 'path';

const app = express();
const PORT = process.env.PORT || 3000;

// Dummy user object for demonstration
const dummyUser = { id: 'user123', email: 'test@example.com', name: 'Test User' };

// Minimal SAMLP configuration
const samlpOptions = {
  issuer: 'http://localhost:3000/samlp',
  cert: fs.readFileSync(path.join(process.cwd(), 'some-cert.pem'), 'utf8'), // Ensure 'some-cert.pem' exists
  key: fs.readFileSync(path.join(process.cwd(), 'some-cert.key'), 'utf8'),   // Ensure 'some-cert.key' exists
  getPostURL: function (audience, samlRequestDom, req, callback) {
    // In a real scenario, this would dynamically determine the SP's AssertionConsumerService URL
    // For quickstart, we'll just return a placeholder or a mock SP URL.
    // Usually, the `audience` from SAMLRequest can help determine the SP.
    console.log('SAML Request received from audience:', audience);
    // For a minimal example, let's assume a fixed SP URL for posting the assertion
    const spAcsUrl = 'http://localhost:8080/saml/acs'; // Replace with a real SP's ACS URL
    return callback(null, spAcsUrl);
  },
  getUserFromRequest: function (req) {
    // In a real app, this would get the authenticated user from req.user or session
    return dummyUser;
  },
  profileMapper: samlp.PassportProfileMapper,
  signatureAlgorithm: 'rsa-sha256',
  digestAlgorithm: 'sha256',
  signResponse: false,
  signAssertion: true
};

app.get('/samlp', (req, res, next) => {
  // Simulate a pre-authenticated user for the IdP flow
  req.user = dummyUser;
  samlp.auth(samlpOptions)(req, res, next);
});

// SAML IdP Metadata endpoint
app.get('/samlp/FederationMetadata/2007-06/FederationMetadata.xml', samlp.metadata(samlpOptions));

app.listen(PORT, () => {
  console.log(`SAML IdP listening on port ${PORT}`);
  console.log('Access SAML Login Initiator via: http://localhost:3000/samlp');
  console.log('Access SAML Metadata via: http://localhost:3000/samlp/FederationMetadata/2007-06/FederationMetadata.xml');
});

view raw JSON →