Node.js N-API binding for the Lasso SAML library.
Provides complete SAML 2.0 Identity Provider (IdP) and Service Provider (SP) functionality for Node.js applications.
- Full SAML 2.0 SSO (Single Sign-On) support
- Full SAML 2.0 SLO (Single Logout) support
- IdP and SP roles
- Multiple bindings: HTTP-Redirect, HTTP-POST, SOAP
- Signature and encryption support
- TypeScript definitions included
Debian/Ubuntu:
sudo apt-get install -y \
liblasso3-dev \
libxml2-dev \
libxmlsec1-dev \
libglib2.0-devFedora/RHEL:
sudo dnf install -y \
lasso-devel \
libxml2-devel \
xmlsec1-devel \
glib2-develmacOS (Homebrew):
brew install lasso libxml2 xmlsec1 glibnpm install lasso.jsimport { init, shutdown, Server, Login, HttpMethod, NameIdFormat } from 'lasso.js';
// Initialize Lasso library (call once at startup)
init();
// ... use Lasso ...
// Shutdown when done (call once at exit)
shutdown();import { init, Server, Login, NameIdFormat, AuthnContext } from 'lasso.js';
import fs from 'fs';
init();
// Load IdP configuration
const server = Server.fromBuffers(
fs.readFileSync('idp-metadata.xml'),
fs.readFileSync('idp-key.pem'),
fs.readFileSync('idp-cert.pem')
);
// Add known Service Providers
server.addProviderFromBuffer(
'https://sp.example.com',
fs.readFileSync('sp-metadata.xml')
);
// Process AuthnRequest
function handleSsoRequest(samlRequest: string, relayState?: string) {
const login = new Login(server);
// Process the AuthnRequest
login.processAuthnRequestMsg(samlRequest);
login.validateRequestMsg();
// After user authenticates, build the response
login.setNameId('user@example.com', NameIdFormat.EMAIL);
login.buildAssertion(AuthnContext.PASSWORD);
if (relayState) {
login.relayState = relayState;
}
const result = login.buildResponseMsg();
return {
url: result.responseUrl,
body: result.responseBody,
relayState: result.relayState
};
}import { init, Server, Login, HttpMethod } from 'lasso.js';
import fs from 'fs';
init();
// Load SP configuration
const server = Server.fromBuffers(
fs.readFileSync('sp-metadata.xml'),
fs.readFileSync('sp-key.pem'),
fs.readFileSync('sp-cert.pem')
);
// Add the IdP
server.addProviderFromBuffer(
'https://idp.example.com',
fs.readFileSync('idp-metadata.xml')
);
// Initiate SSO
function initiateSso(returnUrl: string) {
const login = new Login(server);
login.initAuthnRequest('https://idp.example.com', HttpMethod.REDIRECT);
login.relayState = returnUrl;
const result = login.buildAuthnRequestMsg();
return result.responseUrl; // Redirect user here
}
// Process SAML Response
function processSsoResponse(samlResponse: string) {
const login = new Login(server);
login.processResponseMsg(samlResponse);
login.acceptSso();
return {
nameId: login.nameId,
relayState: login.relayState
};
}init()- Initialize Lasso library (must be called first)shutdown()- Shutdown Lasso librarycheckVersion()- Get Lasso version stringisInitialized()- Check if Lasso is initialized
// Create from buffers
const server = Server.fromBuffers(metadata, privateKey, certificate, password?);
// Restore from dump
const server = Server.fromDump(dumpString);
// Add providers
server.addProvider(providerId, metadataPath, publicKeyPath?, caCertPath?);
server.addProviderFromBuffer(providerId, metadata, publicKey?);
// Get provider info
const provider = server.getProvider(providerId);
// Serialize
const dump = server.dump();const login = new Login(server);
// IdP methods
login.processAuthnRequestMsg(message, method?);
login.validateRequestMsg();
login.setNameId(nameId, format?);
login.setAttributes(attributes);
login.buildAssertion(authMethod?, authInstant?);
const result = login.buildResponseMsg();
// SP methods
login.initAuthnRequest(providerId?, method?);
const result = login.buildAuthnRequestMsg();
login.processResponseMsg(message);
login.acceptSso();
// Properties
login.identity; // Identity object
login.session; // Session object
login.remoteProviderId;
login.nameId;
login.nameIdFormat;
login.relayState;const logout = new Logout(server);
logout.identity = identity;
logout.session = session;
logout.initRequest(providerId?, method?);
const result = logout.buildRequestMsg();
logout.processRequestMsg(message, method?);
logout.validateRequest();
const result = logout.buildResponseMsg();
logout.processResponseMsg(message);
const nextProvider = logout.getNextProviderId();// Identity
const identity = new Identity();
const identity = Identity.fromDump(dump);
const dump = identity.dump();
const isEmpty = identity.isEmpty;
// Session
const session = new Session();
const session = Session.fromDump(dump);
const dump = session.dump();
const isEmpty = session.isEmpty;
const isDirty = session.isDirty;
const assertions = session.getAssertions(providerId);
const index = session.getProviderIndex(providerId);# Clone the repository
git clone https://github.com/linagora/lasso.js.git
cd lasso.js
# Install dependencies
npm install
# Build
npm run build
# Test
npm testlasso.js includes an Express middleware for easy SP integration:
import express from 'express';
import session from 'express-session';
import { createSamlSp, requireAuth } from 'lasso.js';
const app = express();
app.use(session({ secret: 'secret', resave: false, saveUninitialized: true }));
// Mount SAML SP endpoints
app.use('/saml', createSamlSp({
spMetadata: './sp-metadata.xml',
spKey: './sp-key.pem',
spCert: './sp-cert.pem',
idpMetadata: './idp-metadata.xml',
onAuth: (user, req) => {
// Called when user authenticates successfully
return { id: user.nameId, email: user.attributes.email };
},
onLogout: (req) => {
// Called when user logs out
}
}));
// Protect routes
app.get('/protected', requireAuth(), (req, res) => {
res.send(`Hello ${req.session.user.id}`);
});
app.listen(3000);GET /saml/metadata- SP metadata XMLGET /saml/login- Initiate SAML loginPOST /saml/acs- Assertion Consumer ServiceGET /saml/logout- Initiate SAML logoutGET|POST /saml/slo- Single Logout Service
GPL-2.0-or-later (same as Lasso library)
Copyright (c) LINAGORA
Contributions are welcome! Please open an issue or submit a pull request.
- Lasso - The underlying C library
- LemonLDAP::NG - Web SSO solution using Lasso