Skip to content
ecdsa.com

SAML vs OIDC: choosing a single sign-on protocol

Both let an identity provider vouch for a user to another application. SAML signs XML assertions posted through the browser; OpenID Connect signs JSON tokens on top of OAuth 2.0.

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.0OpenID Connect
PublishedOASIS Standard, March 2005Core 1.0, February 2014 (errata 2023); ISO/IEC 26131:2024
TokenXML assertionJWT ID token, plus OAuth access and refresh tokens
SignatureXML Signature with canonicalization, usually RSA-SHA256JWS; RS256 must be supported, ES256 and others common
TransportBrowser POST or redirect; artifact resolution over SOAPAuthorization code via redirect, tokens from the token endpoint
ConfigurationXML metadata exchanged per partnerDiscovery document and JWKS at .well-known URLs
Measured for Microsoft Entra ID (below)Metadata 28–32 KB, 5 certificatesDiscovery 1,728 bytes, JWKS with 7 RSA keys
Key rotationNew certificate in metadata, often updated manually by each partnerAutomatic: clients refresh the JWKS
Native and mobile appsAwkward (browser POST to a server)Designed for it (RFC 8252, PKCE)
API accessNot covered (separate token exchange)Access tokens in the same flow
LogoutSingle Logout over front or back channelRP-Initiated, Front-Channel and Back-Channel Logout (final 2022)
Typical usersEnterprise SaaS, universities (eduGAIN), governmentConsumer 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.

Compare OIDC discovery with SAML metadata for one provider
#!/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
Output
== 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

  1. Run both in parallel: configure an OIDC application in the same identity provider and map the same user identifier (sub or a stable attribute) to existing accounts before switching.
  2. 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.
  3. Use a certified library for OpenID Connect, enable discovery and JWKS caching with refresh on unknown kid, and pin accepted algorithms.
  4. 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.
  5. Plan logout separately: map SAML Single Logout to OIDC Back-Channel Logout where sessions must end centrally.
  6. Retire the SAML connection only after logs show no SAML sign-ins for a full business cycle.

References

All comparisons