SurePassID Identity Provider
SAML Session Cache - Setup and Configuration Guide
Overview
The SAML Session Cache provides:
- Replay Attack Prevention - Tracks SAML request IDs to prevent replay attacks
- Session Management for SLO - Stores active sessions for Single Logout support
Cache Implementations
1. In-Memory Cache (Default)
- Class:
SurePassClassLib.Utility.SamlRequestIdCache(static) - Provider:
SamlSessionCacheProviderwithInMemorysetting - Best for: Single-server deployments
- No setup required - works out of the box
- Thread-safe: Yes, uses
ConcurrentDictionary
2. SQL Server Cache (Recommended for Production)
- Class:
SurePassClassLib.Utility.SqlServerSamlSessionCache - Provider:
SamlSessionCacheProviderwithSqlServersetting - Best for: Multi-server deployments, load-balanced environments
- Requires: Database schema setup
Quick Start - Configuration
Add to your web.config:
<appSettings>
<!-- Cache provider: "InMemory" (default) or "SqlServer" -->
<add key="SamlCache.Provider" value="InMemory" />
<!-- Optional: Request ID expiration in minutes (default: 5) -->
<add key="SamlCache.RequestIdExpirationMinutes" value="5" />
<!-- Optional: Session expiration in hours (default: 8) -->
<add key="SamlCache.SessionExpirationHours" value="8" />
</appSettings>SQL Server Setup
Step 1: Run the Schema Script
Execute the SQL script located at:
Documentation\Development\Database\SamlSessionCache_Schema.sql
This creates:
- Tables:
SamlRequestIds,SamlSessions - Stored Procedures:
TryAddSamlRequestId- Atomic request ID trackingAddOrUpdateSamlSession- Session creationGetSamlSession- Session lookup by SessionIndexGetSamlSessionsByUser- All sessions for a user (for SLO)RemoveSamlSession- Session removalRemoveSamlSessionsByUser- Logout all sessionsCleanupExpiredSamlData- Expired entry cleanup
Step 2: Create SQL Agent Job (Recommended)
Create a SQL Agent job to run CleanupExpiredSamlData
every 5 minutes:
-- Example SQL Agent job step
EXEC dbo.CleanupExpiredSamlData;Step 3: Configure the Application
No additional configuration needed - the SQL Server cache uses the
existing database connection settings from web.config.
Provider Selection
| Setting | Description |
|---|---|
SamlCache.Provider=InMemory |
Uses in-memory cache (default) |
SamlCache.Provider=SqlServer |
Uses SQL Server cache |
Request ID Expiration
- Config Key:
SamlCache.RequestIdExpirationMinutes - Default: 5 minutes
- Purpose: How long to remember request IDs for replay detection
- Should be: Longer than max expected SAML request processing time
Session Expiration
- Config Key:
SamlCache.SessionExpirationHours - Default: 8 hours
- Purpose: How long sessions are valid for SLO
- Should match: Your IdP session timeout
In-Memory Cache Details
Thread Safety
The in-memory cache is fully thread-safe:
- Uses
ConcurrentDictionary<TKey, TValue>for all storage - Uses
Monitor.TryEnterfor cleanup to avoid blocking - Uses
lockfor reset operations
Memory Usage
| Collection | Purpose | Memory per Entry |
|---|---|---|
_requestIds |
Request ID → DateTime | ~100 bytes |
_sessions |
SessionIndex → SamlSessionInfo | ~500 bytes |
_userSessions |
UserId → Set of SessionIndexes | ~50 bytes per session |
_spSessions |
SpEntityId → Set of SessionIndexes | ~50 bytes per session |
Automatic Cleanup
- Runs every 1 minute (non-blocking)
- Removes expired request IDs and sessions
- Can force cleanup with
ForceCleanup()
Limitations
- Not persistent: Data lost on app pool recycle
- Single server: Not shared across web farm
- Memory bound: Large deployments should use SQL Server
Security Considerations
Fail Open vs Fail Closed
- Current implementation: Fails open (allows request if DB unavailable)
- Rationale: Availability over security for authentication
- Can be changed to fail closed if required
Request ID Uniqueness
- SAML spec requires request IDs to be unique
- We track IDs for the expiration period only
- After expiration, the same ID could be reused (by design)
Session Security
- Sessions are server-side only
- SessionIndex is sent in SAML assertions
- Cannot be forged without IdP private key
Monitoring
SQL Server Cache Metrics
-- Active request IDs
SELECT COUNT(*) FROM SamlRequestIds WHERE ExpiresAt > GETUTCDATE();
-- Active sessions
SELECT COUNT(*) FROM SamlSessions WHERE ExpiresAt > GETUTCDATE();
-- Sessions by SP
SELECT SpEntityId, COUNT(*) as SessionCount
FROM SamlSessions
WHERE ExpiresAt > GETUTCDATE()
GROUP BY SpEntityId;
-- Sessions by user
SELECT UserId, COUNT(*) as SessionCount
FROM SamlSessions
WHERE ExpiresAt > GETUTCDATE()
GROUP BY UserId;Troubleshooting
"Replay attack detected" for legitimate requests
- Check server clocks are synchronized
- Increase request ID expiration if requests take long to process
- Check if request is being retried by browser
Sessions not found for SLO
- Verify session was created during SSO
- Check session hasn't expired
High memory usage (in-memory cache)
- Reduce expiration times
- Consider SQL Server cache for high-volume scenarios
Migration from In-Memory to SQL Server
- Run the SQL schema script
- Create SQL Agent cleanup job
- Update
web.config:<add key="SamlCache.Provider" value="SqlServer" /> - Restart the application
- Test SLO flows
- Monitor for errors
Note: During migration, active in-memory sessions will be lost. Plan for a maintenance window or accept that users may need to re-authenticate.
© 2013–2026 SurePassID. All rights reserved. Protected by patents pending. SurePassID, the SurePassID logo and design, and Secure SSO are registered trademarks or trademarks of SurePassID, Corp. in the United States and/or other jurisdictions. All other marks and names mentioned herein may be trademarks of their respective companies.
SurePassID 360 Central Avenue #800 St. Petersburg, FL 33701 USA +1 (888) 200-8144 surepassid.com