
September 11, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
Choosing between SAML vs OIDC for SSO is one of the first architecture calls you make when a client asks for single sign-on. SAML 2.0 still dominates enterprise IdPs like Azure AD, Okta, and Google Workspace SAML apps. OpenID Connect sits on OAuth 2.0 and fits modern SPAs, mobile clients, and API-first stacks. If you build REST APIs and Laravel backends, the wrong protocol adds weeks of integration pain. This guide compares both protocols with real flows, a decision table, and production-oriented Laravel notes drawn from client portals and booking systems I've shipped since 2010.
What is the difference between SAML and OIDC for SSO?
SAML (Security Assertion Markup Language) and OIDC (OpenID Connect) both let users sign in once at an identity provider (IdP) and access multiple apps. They solve the same business problem with different wire formats and client expectations.
SAML 2.0 exchanges XML documents called assertions. The service provider (SP) trusts a signed assertion that states who the user is and which attributes they carry. Flows are almost always browser-based. HTTP-POST and HTTP-Redirect bindings are the common ones.
OIDC is an identity layer on top of OAuth 2.0. After OAuth authorisation, the IdP returns a signed JWT called an ID token. Optional access tokens authorise API calls. JSON, REST endpoints, and bearer tokens make OIDC natural for SPAs and mobile apps.
For deeper OIDC mechanics, see our OpenID Connect explained guide. SAML remains the default when IT hands you a metadata XML file and expects ACS URL configuration in Azure or Okta.
| Criteria | SAML 2.0 | OpenID Connect |
|---|---|---|
| Payload format | XML assertion (signed/encrypted) | JWT ID token (+ optional access token) |
| Transport | Browser POST, Redirect, Artifact | OAuth 2.0 authorisation code, PKCE, implicit (legacy) |
| Primary clients | Browser SSO to web apps | Web, mobile, machine-to-machine APIs |
| Token lifetime | Short-lived assertion per login | ID token + refresh token patterns |
| Logout | SLO (Single Logout) — often partial | End-session endpoint — provider-dependent |
| Enterprise adoption | Very high (ADFS, Azure SAML, Okta SAML) | High and growing (Azure OIDC, Auth0, Keycloak) |
| Developer ergonomics | XML metadata, certificate rotation pain | JSON discovery, standard JWT libraries |
| API authorisation | Not designed for bearer API calls | Access tokens map cleanly to resource servers |
The table is the short answer most architects want. SAML wins on enterprise compatibility. OIDC wins on developer velocity and API ecosystems.
How does SAML 2.0 SSO work step by step?
SAML SP-initiated login is the flow you see when a user hits your app's login page and clicks "Sign in with company account." The SP sends an AuthnRequest. The IdP authenticates the user. The IdP posts a SAML Response back to your Assertion Consumer Service (ACS) URL.
Validate the assertion on your server
Never trust a SAML Response without cryptographic validation. Your SP must verify the XML signature against the IdP certificate from metadata. Check NotBefore and NotOnOrAfter conditions. Confirm the Audience restriction matches your entity ID. Match the InResponseTo value when you sent an AuthnRequest.
A minimal validation checklist on a production Laravel application looks like this:
- Fetch and cache IdP metadata XML (entity ID, SSO URL, signing cert).
- Configure SP entity ID and ACS URL — must match exactly what IT registered.
- Parse the SAML Response, verify signature with IdP X.509 cert.
- Extract NameID (often email) and attribute statements (groups, department).
- Map attributes to a local user record and start a Laravel session.
- Log assertion ID to prevent replay if your library supports it.
SAML metadata is XML-heavy. I keep a copy in version control and diff it when enterprise IT rotates certificates. Missing a cert rotation breaks login for every user at once. That failure mode is common on long-running client portal projects tied to corporate IdPs.
The official SAML 2.0 core specification is maintained by OASIS. Microsoft's Entra ID SAML documentation is a practical reference for Azure-specific attribute naming. Both are worth bookmarking during integration.
How does OpenID Connect SSO work in a modern web app?
OIDC adds identity to OAuth 2.0. The authorisation server returns an ID token (JWT) that proves who the user is. An access token may authorise API calls separately. Discovery via /.well-known/openid-configuration gives you endpoints and supported scopes without manual XML exchange.
Validate the ID token
OIDC validation is JWT-based. Fetch JWKS from the IdP. Verify signature, iss, aud, and exp. Reject tokens with excessive clock skew. Use nonce in implicit-like flows; with authorisation code + PKCE, nonce is still recommended for hybrid setups.
Example discovery and token exchange pattern (PHP 8.3+, Laravel 12 or 13):
GET https://login.example.com/.well-known/openid-configuration
POST https://login.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE_HERE
&redirect_uri=https://app.example.com/auth/callback
&client_id=YOUR_CLIENT_ID
&code_verifier=PKCE_VERIFIER_FROM_SESSION Decode the ID token only after signature verification against JWKS. Map sub as the stable external identifier. Use email only when the IdP marks it verified. Our GitHub Actions OIDC guide covers machine identity with the same OAuth family — useful when comparing human SSO with workload federation.
The OpenID Connect Core 1.0 specification defines standard claims and validation rules. Pair it with openid.net's official OIDC core spec and the IETF OAuth 2.0 RFC for authoritative definitions.
When should you choose SAML vs OIDC for SSO?
Protocol choice is constrained by what the IdP and the customer IT team already support. Greenfield products favour OIDC. Enterprise procurement often mandates SAML.
- Choose SAML when the customer's IdP app catalogue is SAML-only, you integrate with legacy ADFS, or procurement documents specify SAML 2.0 federation.
- Choose OIDC when you ship a SPA, mobile app, or Laravel API with Sanctum/Passport, or when you need refresh tokens and fine-grained scopes.
- Support both when you sell B2B SaaS to mixed enterprises — common on enterprise application builds with separate SAML and OIDC connectors.
- Avoid SAML for native mobile unless you wrap it in a WebView — UX and SLO are brittle.
- Avoid OIDC-only assumptions with law firms and banks in Nepal — IT vendors often deliver SAML metadata first; plan attribute mapping early.
On legal-tech portals like Court Marriage In Nepal, staff SSO is rare at small firms. Enterprise clients requesting staff dashboards are where SAML appears. Public-facing social login is OIDC via Google or Microsoft — different threat model, same protocol family.
How do you implement SSO in Laravel with SAML or OIDC?
Laravel does not ship SAML or OIDC in core. Composer packages and Socialite drivers fill the gap. Pick packages with active maintenance and clear certificate handling.
OIDC with Laravel Socialite
For OIDC providers exposing OAuth2 endpoints (Google, Azure OIDC, Keycloak), Socialite plus a provider-specific driver is the fastest path on Laravel 12 or 13 with PHP 8.3+.
composer require laravel/socialite
composer require socialiteproviders/microsoft-azure
Route::get('/auth/redirect', fn () =>
Socialite::driver('azure')->scopes(['openid', 'profile', 'email'])->redirect()
);
Route::get('/auth/callback', function () {
$oidcUser = Socialite::driver('azure')->user();
$user = User::updateOrCreate(
['external_id' => $oidcUser->getId()],
['email' => $oidcUser->getEmail(), 'name' => $oidcUser->getName()]
);
Auth::login($user, true);
return redirect('/dashboard');
}); For first-party APIs, pair OIDC login with Laravel Sanctum or Passport. Issue your own API tokens after federated login. Do not expose the upstream IdP access token to browser clients unless you accept token passthrough risk.
SAML with a dedicated package
SAML in Laravel typically uses aacotroneo/laravel-saml2 or 24slides/laravel-saml2. Configuration spans config/saml2, routes for ACS, and metadata export for the IdP admin.
composer require 24slides/laravel-saml2
SAML2_IDP_ENTITYID=https://sts.windows.net/TENANT-ID/
SAML2_IDP_SSO_URL=https://login.microsoftonline.com/TENANT-ID/saml2
SAML2_IDP_x509=MIIC...base64-cert...
SAML2_SP_x509=MIIC...your-sp-cert...
SAML2_SP_PRIVATEKEY=-----BEGIN PRIVATE KEY-----... Publish SP metadata at the URL your IdP admin expects. Map SAML attributes in an event listener after login:
Event::listen(SignedIn::class, function (SignedIn $event) {
$samlUser = $event->getSaml2User();
$email = $samlUser->getAttribute('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress')[0] ?? null;
}); Test SAML with dummy IdP tools before involving client IT. Validate clock sync on your Ubuntu server — skew breaks NotOnOrAfter checks silently. NTP matters on Linux production hosts the same way it matters for JWT exp validation.
Session hardening shared by both protocols
After federated login, you still own session security. Regenerate session ID on login. Set secure, HttpOnly, SameSite cookies. Apply authorisation policies after authentication — SSO proves identity, not permission to billing or admin modules.
Use our password generator for service account secrets. Store IdP client secrets and SAML private keys outside git. Laravel's .env plus encrypted env on Deployer releases is the pattern I use on GitLab CI pipelines.
What are common SAML vs OIDC deployment mistakes?
Most SSO outages are configuration drift, not protocol bugs. These failures repeat across client projects.
- ACS / redirect URI mismatch — trailing slashes, http vs https, or wrong subdomain. IdPs treat URLs as exact strings.
- Certificate expiry without monitoring — SAML signing certs and SP certs expire quietly. Alert 30 days ahead.
- Attribute mapping assumptions — Azure sends
emailaddressclaim URIs; Okta uses different keys. Log raw attributes once in staging. - Confusing authentication with authorisation — SSO group claims need mapping to local roles. Spatie Permission still applies.
- Using OIDC implicit flow in new apps — prefer authorisation code with PKCE for public clients per current OAuth best practice.
- Ignoring single logout — users expect global logout; SAML SLO and OIDC end-session are inconsistently supported. Document actual behaviour.
- Passing IdP tokens to the frontend — increases leak surface. Exchange for a first-party session or Sanctum token.
Debug SAML responses with browser devtools on the ACS POST — base64-decode only in staging. For JWTs, paste into a local JSON formatter after redacting secrets — never log full tokens in production.
Rate-limit login and callback routes. Federated endpoints attract abuse similar to password forms. See API rate limiting patterns for shared middleware ideas.
The OASIS SAML 2.0 technical overview remains the authoritative SAML reference. For Azure-specific SAML claim URIs, Microsoft's identity platform docs beat generic tutorials.
Key Takeaways
- SAML 2.0 fits enterprise browser SSO with XML metadata; OIDC fits modern web, mobile, and API stacks with JWTs.
- Validate SAML signatures and OIDC JWTs on the server — never skip issuer, audience, and expiry checks.
- Prefer OIDC with authorisation code + PKCE for new Laravel apps unless the IdP mandates SAML.
- Map external attributes explicitly; log staging assertions once to catch IdP-specific claim names.
- Monitor IdP and SP certificate expiry — it is the most common production SSO outage.
- After SSO login, enforce local authorisation with Laravel policies and roles independent of the IdP.
People Also Ask
Is OIDC replacing SAML?
OIDC is the default for new cloud and developer-centric integrations, but SAML is not dead. Large enterprises standardised on SAML for years. Many IdPs support both. New SaaS products often ship OIDC first and add SAML for enterprise sales cycles.
Can one app support both SAML and OIDC?
Yes. B2B platforms frequently expose a SAML connector for corporate IdPs and OIDC for Google/Microsoft social or partner APIs. Keep user records linked by a stable external ID per provider. Document which tenant uses which protocol.
Which is more secure, SAML or OIDC?
Neither is inherently more secure. Security depends on TLS everywhere, correct signature validation, PKCE for public OIDC clients, short token lifetimes, and secret rotation. SAML's XML complexity increases misconfiguration risk. OIDC's JWT ecosystem is easier to audit with standard libraries.
Does Laravel Sanctum replace OIDC?
No. Sanctum issues tokens for your application's API after a user is authenticated. OIDC federates authentication to an external IdP. Typical pattern: OIDC or SAML for login, then Sanctum for SPA API sessions on your domain.
Pick the protocol your IdP and product actually need
SAML vs OIDC for SSO is not a popularity contest. Read the customer's IdP documentation first. Ship OIDC when you control both sides or target modern clients. Implement SAML when enterprise metadata arrives before your first sprint ends. On greenfield custom software projects, I default to OIDC for Laravel APIs and add SAML when contract requirements appear — not the other way around.
If you are planning federated login for a portal, booking platform, or internal dashboard, map IdP constraints before writing auth code. Contact us for architecture review, or browse the Adventure Third Pole Trek portfolio for multi-role apps where session and role design matter as much as the protocol choice. For related reading, see essential Laravel packages, web development services, and ongoing support after go-live.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

