Skip to content

Enterprise SAML Single Sign-On implementation featuring AES-256 encrypted assertions, dynamic metadata synchronization, custom user attributes, automated testing suite, and production-ready IdP/SP applications built with Node.js

Notifications You must be signed in to change notification settings

smali-kazmi/saml-sso-encrypted

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SAML SSO Implementation with Encrypted Assertions

A complete SAML Single Sign-On (SSO) implementation using Node.js with encrypted assertions, featuring both Identity Provider (IdP) and Service Provider (SP) applications.

πŸš€ Features

  • βœ… 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

πŸ“ Project Structure

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

πŸ› οΈ Prerequisites

  • Node.js (v14 or higher)
  • npm or yarn
  • OpenSSL (for certificate generation)

πŸ“¦ Installation

1. Clone and Install Dependencies

# 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 ..

2. Environment Configuration

# 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)

3. Configure Encryption Mode

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

4. Generate SAML Certificates

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.

πŸš€ Running the Applications

Start Both Applications (Recommended)

# 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

Development Mode

# With nodemon for auto-restart on changes
cd idp-app
npx nodemon app.js

cd sp-app
npx nodemon app.js

πŸ§ͺ Testing the SAML Flow

Automated Testing (Recommended)

# 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

Manual Testing

  1. Access SP Login: http://localhost:4000/login
  2. Follow SAML Redirect to IdP
  3. Complete Authentication at IdP
  4. Verify Attributes in SP response

πŸ“‹ API Endpoints

Identity Provider (IdP) - Port 3000

  • GET /metadata - IdP metadata endpoint
  • GET /sso - Single Sign-On initiation
  • GET / - IdP status page

Service Provider (SP) - Port 4000

  • GET /metadata - SP metadata endpoint
  • GET /login - Initiate SAML authentication
  • POST /assert - SAML assertion consumer (ACS)
  • GET / - SP status page

πŸ”§ Configuration

Encryption Mode Configuration

The system supports both encrypted and non-encrypted SAML assertions through environment variables:

Encrypted Mode (Production Recommended)

# .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

Non-Encrypted Mode (Development/Testing)

# .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

IdP Configuration (idp-app/idp.js)

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: { ... } })
});

SP Configuration (sp-app/sp.js)

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
});

πŸ‘€ User Attributes

The system supports the following user attributes in SAML assertions:

  • email - User email address
  • displayName - Full display name
  • firstName - First name
  • lastName - Last name
  • age - User age
  • gender - User gender
  • username - Username/login

Sample User Data

const user = {
    id: '123',
    email: '[email protected]',
    displayName: 'Demo User',
    firstName: 'John',
    lastName: 'Doe',
    age: '30',
    gender: 'Male',
    username: 'johndoe'
};

πŸ”’ Security Features

  • RSA-SHA256 Signature Verification
  • AES-256-CBC Encrypted Assertions
  • X509 Certificate Validation
  • Dynamic Metadata Synchronization
  • Proper SAML 2.0 Compliance

πŸ› Troubleshooting

Common Issues

  1. Certificate Issues

    # Regenerate certificates if needed
    openssl req -x509 -newkey rsa:2048 -keyout key.key -out cert.cert -days 365 -nodes
  2. Port Conflicts

    # Check if ports are in use
    lsof -i :3000
    lsof -i :4000
  3. Metadata Loading Issues

    • Ensure both applications are running
    • Check network connectivity between IdP and SP
    • Verify certificate paths in configuration

Debug Mode

Enable detailed logging by setting in your .env files:

DEBUG_SAML=true
LOG_LEVEL=debug

Testing Scripts

  • complete-saml-test.js - Full flow verification with detailed output
  • test-encryption-modes.js - Test both encrypted and non-encrypted modes
  • debug-saml-post.js - SAML response debugging with form data analysis
  • decode-saml.js - Decode and analyze SAML XML responses

πŸ“Š Test Results

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

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

πŸ“„ License

This project is licensed under the MIT License.

πŸ™ Acknowledgments

πŸ“ž Support

If you encounter issues:

  1. Check the troubleshooting section above
  2. Run the automated test scripts
  3. Enable debug mode for detailed logging
  4. Review the SAML response XML structure

Happy SAML SSO Implementation! πŸš€

About

Enterprise SAML Single Sign-On implementation featuring AES-256 encrypted assertions, dynamic metadata synchronization, custom user attributes, automated testing suite, and production-ready IdP/SP applications built with Node.js

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published