An interactive, visual Single Sign-On (SSO) playground and multi-server sandbox built using Node.js, Express, and RS256 Asymmetric Cryptography.
This project is designed to explain the mechanics of OpenID Connect (OIDC) / OAuth 2.0 Authorization Code Flow and Single Logout (SLO) through both a visual simulation board and a real, runnable multi-server setup.
- Visual OIDC Simulator (Port 3000): A step-by-step graphical flow tracker showing how browser cookies, authorization codes, and JWT tokens move between the Browser, the Client Apps, and the Identity Provider.
- Real Multi-Server Architecture: Runs 4 separate servers concurrently on different local ports to demonstrate real-world domain/port isolation.
- RS256 Signature Verification: The Identity Provider (IdP) generates a 2048-bit RSA key pair on boot. Client apps fetch public keys dynamically via a
/certsendpoint to verify JWTs offline. - Single Logout (SLO): Demonstrates how logging out of one client application invalidates the central cookie, cascading logout states across all active apps.
- JWT Token Inspector: Decodes OIDC ID tokens into Header, Payload, and Signature with color-coding to explain token structures.
When launched, the sandbox starts four server processes:
| Port | Component | Purpose |
|---|---|---|
| 3000 | Developer Console | The centralized dashboard, visual simulator, and log stream aggregator. |
| 4000 | Identity Provider (IdP) | The central authentication server (OIDC Issuer). |
| 4001 | Client App A | Independent project planning portal (OIDC Client). |
| 4002 | Client App B | Independent HR analytics portal (OIDC Client). |
- Node.js (v18.0.0 or higher)
-
Clone the repository and install the dependencies:
npm install
-
Start all sandbox servers concurrently:
npm start
-
Open your browser and navigate to the Developer Console: http://localhost:3000
When challenged by the central Login screen (port 4000), use the following pre-configured credentials:
- Username:
admin - Password:
password123
- Visit Client App A: Browser requests App A page. App A checks for local session cookie (
app_a_session). None is found. - Redirect to IdP: App A redirects the browser to the central IdP auth endpoint (
/auth) with query parameters identifying Client ID, Redirect URI, and a CSRF State. - Login Challenge: The IdP checks for its central session cookie. None is found, so it prompts the user for credentials.
- Auth Code Issued: Upon verification, the IdP sets a central session cookie (
sso_session_id) in the browser, generates a one-time Authorization Code, and redirects back to App A's callback URL. - Back-Channel Exchange: App A receives the code and requests tokens from the IdP (
/token) using a secure server-to-server POST call (passing its Client Secret). The browser never sees this exchange. - Local Session Created: App A verifies the JWT token signature using the IdP's public certificate, sets a local
app_a_sessioncookie, and logs the user in. - Visit Client App B: The user opens App B. App B checks for a local session cookie. Since local cookies are isolated, it is missing. App B redirects the browser to the IdP.
- SSO Hit!: The browser hits the IdP. Because the browser has the active central cookie (
sso_session_id), the IdP recognizes the user immediately and skips the login screen, redirecting straight back to App B callback with a code. - App B Logged In: App B exchanges the code back-channel, verifies the token, and creates a local
app_b_sessioncookie. The user logs in instantly without entering a password twice. - Single Logout: Logging out of App A clears the local App A cookie and calls the IdP
/logoutendpoint to clear the central session cookie. Reloading App B forces it to re-authenticate, logging the user out globally.
- Front-Channel vs Back-Channel Isolation: Keeps client secrets and JWT tokens off the browser during code exchange.
- Asymmetric Key Cryptography: Utilizes RSA private-signing/public-verification to keep signing keys secure.
- CSRF Mitigation: Mitigates redirect hijacking using state tokens.
- One-Time Codes: Destroys codes immediately on verification to block replay attacks.