A complete SAML Single Sign-On (SSO) implementation using Node.js with encrypted assertions, featuring both Identity Provider (IdP) and Service Provider (SP) applications.
- β Complete SAML 2.0 SSO Flow with proper signature verification
- β Configurable Encryption - Enable/disable AES-256-CBC encrypted assertions
- β Dynamic Metadata Loading for real-time configuration synchronization
- β Custom User Attributes (firstName, lastName, age, gender, email, username, displayName)
- β Comprehensive Testing Suite with automated flow verification
- β JSON Debug Responses for easy troubleshooting
- β Production-Ready Architecture
- β Environment-Based Configuration with .env file support
smal-encrypt/
βββ idp-app/ # Identity Provider Application
β βββ app.js # IdP Express server
β βββ idp.js # IdP SAML configuration
β βββ constants.js # IdP constants
β βββ package.json # IdP dependencies
β βββ .env.sample # IdP environment template
β βββ idp-signing.cert # IdP signing certificate
β βββ idp-signing.key # IdP signing private key
β βββ idp-encrypt.cert # IdP encryption certificate
β βββ idp-encrypt.key # IdP encryption private key
βββ sp-app/ # Service Provider Application
β βββ app.js # SP Express server
β βββ sp.js # SP SAML configuration
β βββ constants.js # SP constants
β βββ package.json # SP dependencies
β βββ .env.sample # SP environment template
β βββ sp-signing.cert # SP signing certificate
β βββ sp-signing.key # SP signing private key
β βββ sp-encrypt.cert # SP encryption certificate
β βββ sp-encrypt.key # SP encryption private key
βββ test-scripts/ # Testing and debugging scripts
β βββ complete-saml-test.js # Comprehensive SAML flow test
β βββ debug-saml-post.js # SAML response debugging
β βββ decode-saml.js # SAML response decoder
β βββ test-encryption-modes.js # Test both encrypted/non-encrypted modes
βββ .gitignore # Git ignore rules
βββ README.md # This file
- Node.js (v14 or higher)
- npm or yarn
- OpenSSL (for certificate generation)
# Navigate to project directory
cd smal-encrypt
# Install IdP dependencies
cd idp-app
npm install
cd ..
# Install SP dependencies
cd sp-app
npm install
cd ..
# Copy environment templates
cp idp-app/.env.sample idp-app/.env
cp sp-app/.env.sample sp-app/.env
# Edit the .env files according to your setup
# Key settings:
# - ENABLE_ENCRYPTION=true/false (controls assertion encryption)
# - DEBUG_SAML=true/false (enables detailed logging)
The system supports both encrypted and non-encrypted SAML assertions:
For Encrypted Assertions (Recommended for Production):
# In both idp-app/.env and sp-app/.env
ENABLE_ENCRYPTION=true
ASSERTION_ENCRYPTED=true
For Non-Encrypted Assertions (Development/Testing):
# In both idp-app/.env and sp-app/.env
ENABLE_ENCRYPTION=false
ASSERTION_ENCRYPTED=false
For IdP (Identity Provider):
cd idp-app
# Generate signing key and certificate (always required)
openssl req -x509 -newkey rsa:2048 -keyout idp-signing.key -out idp-signing.cert -days 365 -nodes -subj "/CN=IdP Signing"
# Generate encryption key and certificate (only needed if ENABLE_ENCRYPTION=true)
openssl req -x509 -newkey rsa:2048 -keyout idp-encrypt.key -out idp-encrypt.cert -days 365 -nodes -subj "/CN=IdP Encryption"
cd ..
For SP (Service Provider):
cd sp-app
# Generate signing key and certificate (always required)
openssl req -x509 -newkey rsa:2048 -keyout sp-signing.key -out sp-signing.cert -days 365 -nodes -subj "/CN=SP Signing"
# Generate encryption key and certificate (only needed if ENABLE_ENCRYPTION=true)
openssl req -x509 -newkey rsa:2048 -keyout sp-encrypt.key -out sp-encrypt.cert -days 365 -nodes -subj "/CN=SP Encryption"
cd ..
Note: Encryption certificates are only required when
ENABLE_ENCRYPTION=true
. For non-encrypted mode, only signing certificates are needed.
# Terminal 1: Start IdP (Identity Provider)
cd idp-app
npm start
# IdP will run on http://localhost:3000
# Terminal 2: Start SP (Service Provider)
cd sp-app
npm start
# SP will run on http://localhost:4000
# With nodemon for auto-restart on changes
cd idp-app
npx nodemon app.js
cd sp-app
npx nodemon app.js
# Run comprehensive SAML flow test
node complete-saml-test.js
# Test both encryption modes
node test-encryption-modes.js
# Run specific debugging tests
node debug-saml-post.js
node decode-saml.js
- Access SP Login: http://localhost:4000/login
- Follow SAML Redirect to IdP
- Complete Authentication at IdP
- Verify Attributes in SP response
GET /metadata
- IdP metadata endpointGET /sso
- Single Sign-On initiationGET /
- IdP status page
GET /metadata
- SP metadata endpointGET /login
- Initiate SAML authenticationPOST /assert
- SAML assertion consumer (ACS)GET /
- SP status page
The system supports both encrypted and non-encrypted SAML assertions through environment variables:
# .env files for both IdP and SP
ENABLE_ENCRYPTION=true
ASSERTION_ENCRYPTED=true
- β SAML assertions encrypted with AES-256-CBC
- β Maximum security for sensitive user data
- β Requires encryption certificates for both IdP and SP
- β Custom attribute template with tag replacement
# .env files for both IdP and SP
ENABLE_ENCRYPTION=false
ASSERTION_ENCRYPTED=false
- β SAML assertions sent in plain text (signed but not encrypted)
- β Easier debugging and development
- β Only requires signing certificates
- β Standard samlify attribute handling
const idp = saml.IdentityProvider({
entityID: 'http://localhost:3000/metadata',
privateKey: fs.readFileSync('./idp-signing.key'),
signingCert: fs.readFileSync('./idp-signing.cert'),
// Encryption key only loaded when ENABLE_ENCRYPTION=true
...(ENABLE_ENCRYPTION && { encPrivateKey: fs.readFileSync('./idp-encrypt.key') }),
requestSignatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
nameIDFormat: ['urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'],
isAssertionEncrypted: ENABLE_ENCRYPTION,
// Custom template only used when encryption is enabled
...(ENABLE_ENCRYPTION && { loginResponseTemplate: { ... } })
});
const sp = saml.ServiceProvider({
entityID: 'http://localhost:4000/metadata',
privateKey: fs.readFileSync('./sp-signing.key'),
signingCert: fs.readFileSync('./sp-signing.cert'),
// Encryption keys only loaded when ENABLE_ENCRYPTION=true
...(ENABLE_ENCRYPTION && {
encPrivateKey: fs.readFileSync('./sp-encrypt.key'),
encryptCert: fs.readFileSync('./sp-encrypt.cert')
}),
isAssertionEncrypted: ENABLE_ENCRYPTION,
// Dynamic IdP metadata loading
});
The system supports the following user attributes in SAML assertions:
email
- User email addressdisplayName
- Full display namefirstName
- First namelastName
- Last nameage
- User agegender
- User genderusername
- Username/login
const user = {
id: '123',
email: '[email protected]',
displayName: 'Demo User',
firstName: 'John',
lastName: 'Doe',
age: '30',
gender: 'Male',
username: 'johndoe'
};
- RSA-SHA256 Signature Verification
- AES-256-CBC Encrypted Assertions
- X509 Certificate Validation
- Dynamic Metadata Synchronization
- Proper SAML 2.0 Compliance
-
Certificate Issues
# Regenerate certificates if needed openssl req -x509 -newkey rsa:2048 -keyout key.key -out cert.cert -days 365 -nodes
-
Port Conflicts
# Check if ports are in use lsof -i :3000 lsof -i :4000
-
Metadata Loading Issues
- Ensure both applications are running
- Check network connectivity between IdP and SP
- Verify certificate paths in configuration
Enable detailed logging by setting in your .env
files:
DEBUG_SAML=true
LOG_LEVEL=debug
complete-saml-test.js
- Full flow verification with detailed outputtest-encryption-modes.js
- Test both encrypted and non-encrypted modesdebug-saml-post.js
- SAML response debugging with form data analysisdecode-saml.js
- Decode and analyze SAML XML responses
Successful test output should show:
π SAML SSO AUTHENTICATION SUCCESSFUL!
π€ Name ID: [email protected]
π Attributes Count: 7
π USER ATTRIBUTES:
email: [email protected]
displayName: Demo User
firstName: John
lastName: Doe
age: 30
gender: Male
username: johndoe
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the MIT License.
- samlify - SAML 2.0 library for Node.js
- Express.js - Web framework
- OpenSSL - Certificate generation
If you encounter issues:
- Check the troubleshooting section above
- Run the automated test scripts
- Enable debug mode for detailed logging
- Review the SAML response XML structure
Happy SAML SSO Implementation! π