Lab · 03 / 16
Two ways to say it is me.
In companies you meet both every day. SAML runs most enterprise web SSO built in the last twenty years, OpenID Connect is the default for anything new, especially mobile apps and APIs.
In plain words Both are a signed letter from the IdP saying "this is Ada". SAML writes it in XML and hands it over through the browser; OIDC writes it as a compact JSON token and also gives the app a key for APIs.
| SAML 2.0XML assertions | OpenID ConnectJSON tokens | |
|---|---|---|
| Born | 2005, OASIS | 2014, OpenID Foundation |
| Format | XML assertion, XML signature | JWT (JSON), JWS signature |
| Roles | Identity provider and service provider | OpenID provider and relying party (client) |
| Transport | Browser redirects and auto-submitted POST forms | Redirects plus direct calls to the token endpoint |
| Mobile and SPA | Awkward, designed for the browser | Native, with PKCE |
| Calling APIs | Not covered, needs another protocol | Access token from the same flow |
| Setup | Exchange XML metadata and certificates | Discovery URL and automatic key rotation (JWKS) |
| Where you find it | Enterprise SaaS, legacy portals, government | New apps, mobile, consumer sign-in, APIs |
When to use SAML 2.0
Use SAML when the app only supports SAML, which is still common for enterprise SaaS. It is mature and well understood by auditors.
When to use OpenID Connect
Use OpenID Connect for every new app you build, and for mobile, single-page apps and anything that calls APIs.
The most common mistake
Trusting a SAML response without strict checks. The service provider must verify the signature on the assertion itself, and check Audience, Recipient, time window and that the signed element is the one it reads. Weak XML signature handling has caused real breaches.
Side by side
<saml:Assertion ID="_a75adf55" IssueInstant="2026-10-19T08:00:00Z">
<saml:Issuer>https://idp.example.com</saml:Issuer>
<ds:Signature>…</ds:Signature>
<saml:Subject>
<saml:NameID>ada@example.com</saml:NameID>
</saml:Subject>
<saml:Conditions NotOnOrAfter="2026-10-19T08:05:00Z">
<saml:Audience>https://app.example.com</saml:Audience>
</saml:Conditions>
</saml:Assertion>{
"iss": "https://idp.example.com",
"sub": "248289761001",
"aud": "web-app",
"iat": 1760860800,
"exp": 1760861100,
"email": "ada@example.com"
}
// signed with a key published at
// /.well-known/jwks.json