SAML vs OIDC is the protocol decision behind single sign-on. SAML 2.0 (OASIS Standard, March 2005) has an identity provider sign an XML assertion about the user, which the browser carries to the service provider. OpenID Connect (Core 1.0, February 2014, also ISO/IEC 26131:2024) adds an identity layer to OAuth 2.0: the provider issues a signed JWT, the ID token, usually through the authorization code flow, and can issue access tokens for APIs in the same exchange.
At a glance
| SAML 2.0 | OpenID Connect | |
|---|---|---|
| Published | OASIS Standard, March 2005 | Core 1.0, February 2014 (errata 2023); ISO/IEC 26131:2024 |
| Token | XML assertion | JWT ID token, plus OAuth access and refresh tokens |
| Signature | XML Signature with canonicalization, usually RSA-SHA256 | JWS; RS256 must be supported, ES256 and others common |
| Transport | Browser POST or redirect; artifact resolution over SOAP | Authorization code via redirect, tokens from the token endpoint |
| Configuration | XML metadata exchanged per partner | Discovery document and JWKS at .well-known URLs |
| Measured for Microsoft Entra ID (below) | Metadata 28–32 KB, 5 certificates | Discovery 1,728 bytes, JWKS with 7 RSA keys |
| Key rotation | New certificate in metadata, often updated manually by each partner | Automatic: clients refresh the JWKS |
| Native and mobile apps | Awkward (browser POST to a server) | Designed for it (RFC 8252, PKCE) |
| API access | Not covered (separate token exchange) | Access tokens in the same flow |
| Logout | Single Logout over front or back channel | RP-Initiated, Front-Channel and Back-Channel Logout (final 2022) |
| Typical users | Enterprise SaaS, universities (eduGAIN), government | Consumer sign-in, modern SaaS, mobile, workforce identity |
How each one signs a user in
In SAML, the service provider redirects the browser to the identity provider with an AuthnRequest. After sign-in, the IdP returns an HTML form that posts a base64-encoded Response containing the assertion: issuer, subject, audience restriction, validity window, attributes and an XML Signature. The service provider verifies the signature with the certificate from the IdP's metadata and checks the conditions.
In OpenID Connect, the client redirects to the provider's authorization endpoint with scope=openid, a state, a nonce and a PKCE challenge. The provider returns a one-time code to the redirect URI; the client exchanges it at the token endpoint for the ID token and access token over a direct TLS connection, so the tokens never pass through the browser's address bar.
The script below reads both kinds of configuration from the same provider (20 October 2026, curl and jq 1.8.1). The SAML metadata size varied between 28 and 32 KB and the JWKS between 7 and 8 keys across repeated fetches, as different servers answered.
#!/bin/sh
base=https://login.microsoftonline.com/common
echo "== OpenID Connect discovery"
curl -s "$base/v2.0/.well-known/openid-configuration" -o oidc.json
echo "bytes: $(wc -c < oidc.json | tr -d ' ')"
jq -c '{id_token_signing_alg_values_supported, response_types_supported}' oidc.json
curl -s "$(jq -r .jwks_uri oidc.json)" | jq -c '{jwks_keys: (.keys | length), kty: ([.keys[].kty] | unique)}'
echo "== SAML 2.0 metadata"
curl -s "$base/FederationMetadata/2007-06/FederationMetadata.xml" -o saml.xml
echo "bytes: $(wc -c < saml.xml | tr -d ' ')"
grep -o 'SignatureMethod Algorithm="[^"]*"' saml.xml | sort -u
grep -o 'SingleSignOnService Binding="[^"]*"' saml.xml | sort -u
echo "distinct certificates: $(grep -o '<X509Certificate>[^<]*' saml.xml | sort -u | wc -l | tr -d ' ')"
rm -f oidc.json saml.xml
== OpenID Connect discovery
bytes: 1728
{"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"]}
{"jwks_keys":7,"kty":["RSA"]}
== SAML 2.0 metadata
bytes: 28179
SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
distinct certificates: 5
What a relying party must check
SAML: verify the XML Signature against the IdP certificate you configured (never one embedded in the message), and make sure the signature covers the exact assertion your code reads; then check Issuer, Destination, InResponseTo, AudienceRestriction, NotBefore and NotOnOrAfter, and reject replays. The difficulty is structural. XML Signature signs elements referenced by ID after canonicalization, so a document can contain a validly signed element and a different, unsigned one that the application processes instead. In 2012, Somorovsky and colleagues showed such signature wrapping in 11 of 14 SAML frameworks; in 2024 and 2025, ruby-saml (used by GitLab) needed fixes again (CVE-2024-45409, CVE-2025-25291 and CVE-2025-25292) because two XML parsers in the same library read one document differently.
OpenID Connect (Core §3.1.3.7): verify the JWS with a key from the provider's JWKS, matched by kid, with the algorithm you expect; then check iss, aud (your client ID), exp, iat and the nonce you sent. JSON has one parse tree and the signature covers the exact bytes received, so there is no wrapping problem; the remaining pitfalls are accepting unexpected algorithms, skipping aud checks and weak redirect URI matching, which the OAuth security best current practice (RFC 9700, January 2025) addresses. The OIDC token validator runs these checks against a provider's live JWKS, and the SAML inspector shows which element a signature actually covers.
When to choose which
- New applications, mobile apps, single-page apps, APIs: OpenID Connect with the code flow and PKCE.
- Selling SaaS to enterprises: support both; many customers' identity teams still configure SAML first.
- Research and education federations (eduGAIN, InCommon): SAML, with metadata aggregates; OpenID Federation 1.0 (final since February 2026) is being piloted for eduGAIN but is not yet the norm.
- Government and regulated sectors: follow the profile your ecosystem mandates; open banking and similar regimes use FAPI 2.0, a hardened OAuth and OpenID Connect profile.
- Provisioning users and groups: neither; use SCIM 2.0 (RFC 7643 and RFC 7644) alongside either protocol.
Migration notes
- Run both in parallel: configure an OIDC application in the same identity provider and map the same user identifier (
subor a stable attribute) to existing accounts before switching. - Map attributes to claims explicitly; SAML attribute names (often URNs) rarely match OIDC claim names, and group claims may need a separate API call when users have many groups.
- Use a certified library for OpenID Connect, enable discovery and JWKS caching with refresh on unknown
kid, and pin accepted algorithms. - Harden what stays on SAML: update the library, require signed assertions, reject documents with multiple assertions or DTDs, and monitor certificate expiry in partner metadata.
- Plan logout separately: map SAML Single Logout to OIDC Back-Channel Logout where sessions must end centrally.
- Retire the SAML connection only after logs show no SAML sign-ins for a full business cycle.
References
- OASIS SAML 2.0 Core and Bindings
- OpenID Connect Core 1.0 (§3.1.3.7 ID token validation)
- OpenID Connect Discovery 1.0
- OpenID Connect Back-Channel Logout 1.0
- RFC 9700, OAuth 2.0 Security Best Current Practice
- RFC 7636, PKCE and RFC 8252, OAuth for native apps
- W3C XML Signature Syntax and Processing 1.1
- Somorovsky et al., On Breaking SAML, USENIX Security 2012