← back to projects
LIVE2025

Enterprise SSO Security Portal

Growing organizations face real security risk when employees maintain separate passwords across every internal and external application. This breeds credential vulnerabilities, inflates help-desk ticket volume, and makes new-hire provisioning a multi-hour manual task. I built a centralized, multi-tenant authentication server fully compliant with the OpenID Connect (OIDC) standard. Every corporate application is secured under a single sign-on portal, with role-based permission settings managed from a master administrator dashboard. Tenant isolation is enforced at the data and routing layer — each organization's client configurations, registered applications, and user roles are completely segregated. The authorization server issues signed JWTs with custom claims, supports PKCE for SPA clients, and exposes a compliance-ready token introspection endpoint. The admin dashboard enables non-technical administrators to provision users, assign roles, and register new OAuth2 client applications without touching config files.

$ Architecture

  • Spring Authorization Server (Spring Security 6): three security filter chains — one for the authorization server endpoints (.well-known/openid-configuration, /oauth2/authorize, /oauth2/token), one for the admin dashboard, one for the API layer. All chains independently scoped.
  • Multi-tenant isolation: TenantResolutionFilter extracts org slug from the request path or subdomain, loads the correct tenant context, and scopes all downstream queries — client lookups, user store, role assignments — to that tenant with no cross-tenant data bleed.
  • Custom token customizer (SSOTokenCustomizer): injects org ID, tenant slug, and RBAC role claims into every issued JWT. Downstream services consume these claims for authorization without a separate lookup.
  • Persistent client registry (TenantAwareRegisteredClientRepository): OAuth2 registered clients stored in PostgreSQL per tenant, managed via admin API. Supports confidential clients (server-side apps) and public clients (SPAs) with PKCE enforcement.
  • Admin frontend (React + Vite + Tailwind): SPA with protected routes — AppsPage (register/revoke OAuth2 clients), UsersPage (create/deactivate users), RolesPage (define and assign roles), OverviewPage (active session stats). Auth via OIDC callback into the same authorization server it manages.
  • Database migrations via Flyway: all schema changes version-controlled and applied on startup. OAuth2 authorization, consent, and token tables follow Spring Authorization Server schema conventions.

$ Tech Stack

JavaSpring BootSpring Authorization ServerOIDCOAuth2ReactTypeScriptVitePostgreSQLFlywayJWTDockerNginx

$ Outcomes

100% password compliance across all connected corporate systems — single credential, zero per-app password sprawl
Employee account provisioning and onboarding time reduced by 50% via admin dashboard user creation and role assignment
OIDC-compliant .well-known/openid-configuration endpoint — any standards-compliant client integrates in minutes
Multi-tenant isolation: each organization's clients, users, and roles are fully segregated at the database layer
PKCE enforcement for SPA clients — eliminates authorization code interception attacks on public clients
Custom JWT claims (org ID, tenant slug, roles) — downstream services enforce RBAC without a separate user-info lookup
Admin dashboard: register and revoke OAuth2 applications, manage users and roles, view active session stats — no config file editing required
Credential-stuffing and unauthorized access risk eliminated via centralized, audited authentication path