Prompt
How do I build SSO for different identity providers?
Latest observation
Building SSO for multiple identity providers usually means designing your app to support federated authentication through standards like SAML 2.0, OpenID Connect (OIDC), and sometimes OAuth 2.0.
1) Choose the right protocols
- OIDC: Best for modern web/mobile apps and new integrations.
- SAML 2.0: Common in enterprise/legacy IdPs like Okta, ADFS, Azure AD, Ping, OneLogin.
- OAuth 2.0: Authorization framework, often used with OIDC for login; by itself it’s not enough for authentication.
If you want one implementation that works with many IdPs, support OIDC first, and SAML if you need enterprise compatibility.
2) Use a provider-agnostic login model
Your app should not hardcode assumptions about one IdP. Instead, model:
- Tenant / organization
- Identity provider configuration per tenant
- Domain-to-IdP mapping (e.g.
acme.com -> Okta) - Protocol type (
oidcorsaml) - Issuer / entity ID
- Client credentials or certificate
- Allowed redirect URLs / ACS URLs
Typical flow:
- User enters email.
- You infer tenant by email domain or ask them to choose SSO provider.
- Redirect to the configured IdP.
- Validate the response/assertion.
- Map external identity to internal user.
- Create session.
3) Support the standard SSO flows
OIDC login flow
Use Authorization Code Flow with PKCE:
- Redirect to IdP
/authorize - User authenticates
- IdP redirects back with
code - Exchange
codefor tokens at/token - Validate
id_tokensignature, issuer, audience, nonce, expiration - Create your session
Key validation:
issmatches expected issueraudcontains your client ID- signature verifies with the IdP JWKS
noncematchesexp/iatare valid
SAML login flow
- User is redirected to IdP with a SAML AuthnRequest
- IdP posts a SAML Response to your ACS endpoint
- Validate:
- XML signature
- assertion conditions
- audience restrictions
- recipient / destination
- timestamps
- Extract NameID and claims/attributes
- Create or link user session
4) Build a common identity mapping layer
Different IdPs send different identifiers and claims. Normalize them into a common internal user profile.
Store:
internal_user_idtenant_ididp_idexternal_subject- OIDC:
sub - SAML: NameID or stable attribute
- OIDC:
emailemail_verifiedgiven_name,family_name- roles/groups if needed
Important:
- Prefer a stable immutable external identifier over email alone.
- Email can change;
subin OIDC is usually stable per issuer. - For SAML, use a stable NameID or dedicated attribute if the IdP supports it.
5) Design onboarding for each IdP
For each IdP integration, collect:
OIDC configuration
- Issuer URL
- Client ID
- Client secret or private key JWT
- Authorization endpoint, token endpoint, JWKS URL
- Scopes
- Claims mapping
SAML configuration
- IdP entity ID
- SSO URL
- X.509 signing certificate
- Assertion consumer service URL
- NameID format
- Attribute mapping
Also provide your metadata:
- For OIDC: redirect URIs, post-logout redirect URIs
- For SAML: SP metadata XML, ACS URL, Entity ID
6) Handle account linking carefully
Users may sign in through different IdPs or with local accounts.
Recommended approach:
- Link accounts only when:
- same verified email, and
- a trusted migration/linking flow is used, or
- admin-approved linking
- Never auto-link solely on unverified email if security is important.
- Keep a table of linked external identities.
Example linking rules:
tenant + idp + external_subjectmaps to one internal user- optional secondary match: verified email
- support merging accounts if a user changes IdPs
7) Implement provisioning and deprovisioning
SSO is often only authentication. You may also need lifecycle management.
Provisioning
- Just-in-time (JIT): create user on first login
- SCIM: sync users/groups from IdP to your app
- Admin invitation workflows
Deprovisioning
- Disable access if user is removed from IdP group
- Periodically re-check group membership if you rely on groups/roles
- Support SCIM delete/disable events if possible
8) Support group/role claims
Many customers want SSO plus authorization.
Possible sources:
- OIDC claims:
groups,roles, custom claims - SAML attributes:
memberOf,groups, custom attributes - SCIM group sync
Best practice:
- Map IdP groups to application roles in a tenant-specific config
- Avoid using raw group names directly as app permissions without mapping
- Handle large group lists carefully; some IdPs limit token size
9) Build for security
Must-haves:
- Use HTTPS everywhere
- Validate all tokens/assertions
- Store secrets/certs securely
- Rotate keys and secrets
- Use state/nonce in OIDC
- Protect against replay attacks
- Enforce exact redirect URI matching
- Log authentication events without exposing sensitive token contents
- Consider step-up MFA policies if needed
For SAML specifically:
- Require signed assertions/responses
- Validate certificates and metadata freshness
- Prevent XML signature wrapping attacks by using a well-tested library
10) Make the UX flexible
Common enterprise login UX patterns:
- “Sign in with SSO”
- Email-first flow: user enters email, you infer the IdP
- IdP chooser when multiple providers exist
- Fallback to password login for non-SSO users
Example:
- User enters
jane@acme.com - You detect
acme.commapped to Okta - Redirect directly to Okta
- If unknown domain, offer local login or a list of providers
11) Use a well-tested library or broker
Unless you’re building an identity product, avoid hand-rolling protocol code.
Good approach:
- Use libraries for OIDC/SAML validation
- Or use an identity broker like:
- Auth0
- Okta
- Azure AD B2C / Entra External ID
- Keycloak
- FusionAuth
- Cognito
A broker can unify many IdPs and reduce complexity, especially if you need both SAML and OIDC.
12) Test edge cases
Be sure to test:
- multiple tenants with different IdPs
- expired assertions/tokens
- clock skew
- email changes
- user disabled at IdP
- token refresh and logout
- IdP certificate rotation
- multiple accounts with same email
- SAML attribute mapping differences
- mobile/browser session handling
Suggested architecture
A practical architecture is:
- Auth gateway / identity service
- handles OIDC + SAML callbacks
- validates responses
- maps external identities
- issues your app session/JWT
- Tenant config store
- IdP settings per customer
- User identity linking store
- external identity → internal user
- Policy engine
- groups, roles, access rules
- Provisioning service
- SCIM/JIT sync
If you want the simplest route
If you’re starting from scratch:
- Implement OIDC Authorization Code + PKCE
- Add tenant-level IdP configuration
- Use email-domain discovery
- Build an external identity mapping table
- Add SAML support only if your customers need it
- Consider using an identity broker to reduce protocol complexity
If you want, I can also give you:
- a step-by-step architecture diagram
- a database schema for multi-IdP SSO
- or sample code for OIDC and/or SAML in your stack.