SAML vs. OIDC: Choosing the Right SSO Protocol for Your Organization

Two Protocols, One Goal: Prove Who You Are

Single Sign-On (SSO) lets your users log in once and access multiple applications without re-entering credentials. It reduces password fatigue, simplifies onboarding and offboarding, and centralizes authentication so your security team has one place to enforce MFA, monitor logins, and revoke access.

But SSO is a goal, not a protocol. The two dominant protocols that implement SSO are SAML 2.0 (Security Assertion Markup Language) and OIDC (OpenID Connect). They solve the same fundamental problem — “prove to this application that I am who I say I am” — but they do it in very different ways, and each has strengths and weaknesses that matter for real-world deployments.

This article explains how each protocol works, where each excels, where each struggles, and how to decide which one fits your organization.

SAML 2.0: The Enterprise Veteran

SAML 2.0 was published in 2005 by OASIS (Organization for the Advancement of Structured Information Standards). It was designed for a world of on-premises enterprise applications, web browsers, and XML — and it has been the backbone of enterprise SSO for two decades.

How SAML Works

SAML uses XML-based messages exchanged between three parties:

  1. The User (called the “Principal”) — the person trying to log in
  2. The Identity Provider (IdP) — the system that knows who the user is (e.g., Authentik, Okta, Azure AD, ADFS)
  3. The Service Provider (SP) — the application the user wants to access (e.g., Salesforce, ServiceNow, an internal app)

The typical flow (called “SP-initiated SSO”) works like this:

  1. The user tries to access the Service Provider (e.g., clicks “Log in” on an internal app)
  2. The SP generates a SAML AuthnRequest (an XML document) and redirects the user’s browser to the Identity Provider
  3. The IdP authenticates the user (password, MFA, etc.)
  4. The IdP generates a SAML Response containing a SAML Assertion — an XML document that says “this user is alice@company.com, they authenticated at 10:32 AM, they belong to these groups, and here is my cryptographic signature proving I said all this”
  5. The user’s browser sends the SAML Response back to the SP (via an HTTP POST)
  6. The SP validates the signature, checks the assertion, and grants access

The entire exchange happens through browser redirects and form posts. The IdP and SP never communicate directly — the user’s browser carries the messages back and forth.

What SAML Does Well

Battle-tested in the enterprise: SAML has been the standard for enterprise SSO since the mid-2000s. Every major enterprise application supports it — Salesforce, Workday, ServiceNow, SAP, Oracle, Microsoft 365. If you need SSO for a legacy enterprise app, SAML is almost certainly the only option.

Rich assertions: SAML assertions can carry detailed attribute statements — not just “who is this user” but also their email, department, role, group memberships, and any other attributes the SP needs. These attributes can drive authorization decisions inside the application.

XML Signature security: SAML assertions are digitally signed using XML Signature (XMLDsig). The SP can cryptographically verify that the assertion came from the IdP and has not been tampered with. Assertions can also be encrypted so that only the SP can read them.

IdP-initiated SSO: SAML supports a flow where the user starts at the IdP (e.g., a portal dashboard) and clicks an application icon. The IdP generates a SAML assertion and sends the user directly to the SP without the SP initiating the request. This is useful for intranet portals.

Mature ecosystem: Twenty years of deployment means extensive documentation, well-understood security properties, and widespread tooling.

Where SAML Struggles

XML complexity: SAML messages are verbose XML documents with namespaces, canonicalization, and XML Signature. Implementing SAML correctly is hard — XML parsing vulnerabilities (XXE attacks, signature wrapping attacks) have been a recurring source of security issues. Most developers use SAML libraries rather than implementing it from scratch, but even choosing and configuring a library requires expertise.

Browser-only: SAML was designed for web browsers using HTTP redirects and form posts. It does not work well for mobile apps, single-page applications (SPAs), APIs, or any scenario where a browser is not the client. There is no standard way to use SAML for authenticating a mobile app or an API call.

No native API authorization: SAML handles authentication (“who is this user?”) but not authorization for APIs (“is this app allowed to access this API on behalf of this user?”). SAML has no concept of access tokens, scopes, or delegated authorization. If you need API-level access control, SAML alone is not enough.

Heavy configuration: Setting up SAML requires exchanging XML metadata documents between the IdP and SP, configuring certificate trust, aligning attribute mappings, and debugging XML signature validation. It works, but it is not quick.

Logout is fundamentally broken: This is not a minor inconvenience — it is a security problem. SAML’s Single Logout (SLO) specification exists on paper, but in practice it is so unreliable that most organizations disable it entirely and rely on session timeouts instead.

The problem is architectural. SAML logout requires the IdP to notify every Service Provider that the user has logged out, but the only mechanism is browser redirects — the user’s browser must visit each SP in sequence to deliver the logout message. If the user has ten SAML applications open, the browser must redirect through all ten SPs. If any SP is slow, down, or returns an error, the chain breaks and the remaining SPs never learn about the logout. The user thinks they are logged out. They are not.

This creates real security exposure. When an employee is terminated or a compromised account is detected, the security team revokes access at the IdP. But existing SAML sessions at each SP remain valid until they expire — which could be hours or even days, depending on the SP’s session timeout. During that window, the terminated employee or attacker can continue using every application where they have an active session.

Some organizations work around this with very short session timeouts (forcing frequent re-authentication), but this destroys the user experience that SSO was supposed to provide. Others build custom session revocation APIs for each SP, but this is per-application integration work that SAML was supposed to eliminate.

OIDC handles this better with back-channel logout — a server-to-server HTTP call from the OP to each RP. No browser redirect chain. No dependency on the user’s browser being open. The OP sends a signed logout token directly to each RP’s logout endpoint. It is not perfect (the RP must implement the endpoint and act on it), but the architecture is fundamentally more reliable than SAML’s browser-based approach. OIDC also supports short-lived access tokens with refresh token rotation, so even without explicit logout, a revoked refresh token naturally cuts off access within minutes.

The XML Parser Problem: Why SAML Is Dangerous by Design

This deserves its own section because it is the single strongest technical argument against adopting SAML in any new software.

SAML depends on XML. That sounds innocuous — XML is a well-understood, standardized data format with mature libraries in every language. The problem is that standard XML libraries were never designed to be safe when parsing untrusted input, and SAML requires you to parse XML that arrives from the internet, submitted by users whose identity you have not yet verified. That is the entire point — you are parsing the XML in order to verify identity.

Standard XML parsers support features that become attack vectors when processing untrusted documents:

XML External Entity (XXE) attacks: The XML specification allows documents to reference external entities — files on the server’s filesystem, internal network URLs, or remote resources. A malicious SAML response can include entity declarations that cause the XML parser to read arbitrary files from the server and include their contents in the parsed document. The attacker never authenticates — they just submit a crafted XML document and the parser does the rest. XXE has been so prevalent that it earned its own place in the OWASP Top 10.

XML Signature Wrapping (XSW) attacks: SAML assertions are signed, and the SP must verify the signature before trusting the assertion. But XML Signature operates on a subset of the XML document identified by a reference URI. An attacker can craft a SAML response where the signed assertion is present (so signature verification passes) but a second, unsigned assertion is placed where the application actually reads it. The signature is valid. The assertion the application trusts is forged. This attack has been demonstrated against dozens of SAML implementations, including those from Microsoft, Salesforce, and major open-source libraries.

Billion Laughs (XML Bomb): XML entity expansion allows nested entity definitions that expand exponentially. A small document (a few kilobytes) can expand to gigabytes in memory, crashing the parser and the server. This is a denial-of-service attack that requires no authentication.

DTD retrieval: Standard XML parsers may fetch remote Document Type Definitions (DTDs) referenced in the document, enabling server-side request forgery (SSRF) and information disclosure.

XPath injection: Some SAML libraries use XPath to locate elements in the parsed XML. Malformed input can manipulate XPath queries to extract unintended data or bypass validation logic.

The correct response to these risks is to use a hardened XML parser — one that disables external entities, disables DTD processing, limits entity expansion depth, and validates document structure before signature verification. But “hardened” means “non-standard.” You are deliberately disabling features that the XML specification says a conforming parser must support. Every XML library handles this differently — different APIs, different defaults, different configuration flags, different versions. Getting it right requires deep knowledge of both the XML library and the specific attack vectors.

This is not a theoretical concern. Major SAML vulnerabilities have been disclosed repeatedly:

  • 2012: Multiple XXE vulnerabilities in Java SAML libraries
  • 2017: Signature wrapping attacks against eight major SAML implementations (Duo Security research)
  • 2018: Critical XSW vulnerability in the widely-used ruby-saml library
  • 2019: XXE and SSRF in several Python SAML libraries
  • 2021: Signature bypass in Apache Santuario (Java XML Signature library used by many SAML implementations)
  • 2024: Critical authentication bypass in ruby-saml (CVE-2024-45409) — signature wrapping allowed attackers to forge SAML responses and log in as any user

The pattern is clear: the XML parsing layer is a persistent source of critical authentication bypass vulnerabilities. Each new SAML library, each new language binding, each new version re-introduces the same class of bugs because the underlying problem is architectural — XML was not designed for adversarial parsing.

OIDC avoids this entire class of vulnerability. JSON has no entity expansion, no external entity references, no DTDs, no XPath, and no canonicalization ambiguity. JWT signature verification operates on a simple base64-encoded string, not a complex document tree. There is no equivalent of signature wrapping because the signature covers the entire token, not a referenced subset of a larger document.

This is why no new software should implement SAML. The protocol works, and existing implementations can be made secure with careful library selection and configuration. But every new SAML implementation is a new opportunity to get XML parsing wrong, and the consequences of getting it wrong are total authentication bypass. OIDC provides the same functionality with none of the XML risk.

OIDC: The Modern Standard

OpenID Connect (OIDC) was finalized in 2014 by the OpenID Foundation. It is built on top of OAuth 2.0 (the industry standard for API authorization) and adds an identity layer — turning an authorization framework into a full authentication protocol.

How OIDC Works

OIDC uses JSON-based messages and tokens exchanged between three parties:

  1. The User (called the “End-User”) — the person trying to log in
  2. The OpenID Provider (OP) — the identity provider (e.g., Authentik, Google, Auth0, Azure AD)
  3. The Relying Party (RP) — the application the user wants to access

The typical flow (called the “Authorization Code Flow”) works like this:

  1. The user clicks “Log in” on the application (the RP)
  2. The RP redirects the user’s browser to the OpenID Provider with an authorization request (a URL with query parameters — no XML)
  3. The OP authenticates the user (password, MFA, etc.)
  4. The OP redirects the user back to the RP with an authorization code (a short-lived, one-time-use code)
  5. The RP exchanges the authorization code directly with the OP (a server-to-server HTTPS call) for three tokens:
    • ID Token — a JSON Web Token (JWT) containing the user’s identity claims
    • Access Token — a token the RP can use to call APIs on the user’s behalf
    • Refresh Token — (optional) a long-lived token to get new access tokens without re-authenticating
  6. The RP validates the ID Token and grants access

What OIDC Does Well

Simple and developer-friendly: OIDC uses JSON, JWTs, and standard HTTPS calls. There is no XML parsing, no XML Signature, and no canonicalization. A competent developer can implement an OIDC client in an afternoon. Libraries are available for every major language and framework.

Works everywhere: OIDC was designed for the modern web — SPAs, mobile apps, APIs, microservices, and server-side applications. Different flows (Authorization Code, Authorization Code with PKCE, Client Credentials, Device Authorization) handle different client types. Mobile apps use PKCE (Proof Key for Code Exchange) for secure authentication without embedded secrets.

Built-in API authorization: Because OIDC is built on OAuth 2.0, it natively supports access tokens and scopes. An OIDC login can simultaneously authenticate the user (ID token) and authorize the application to call APIs on their behalf (access token). This eliminates the need for a separate authorization layer.

Lightweight tokens: JWTs are compact, self-contained, and can be verified without contacting the IdP (the RP just needs the IdP’s public key). This makes them efficient for microservice architectures where every service needs to verify the caller’s identity.

Discovery and dynamic registration: OIDC defines a discovery endpoint (.well-known/openid-configuration) that publishes the provider’s capabilities, endpoints, and public keys. Clients can auto-configure themselves by reading this document, reducing manual setup.

Session management: OIDC defines front-channel and back-channel logout specifications. While implementation varies, the specifications are more practical than SAML’s SLO. Back-channel logout (server-to-server notification) is more reliable than SAML’s browser-based approach.

Token refresh: OIDC’s refresh token mechanism allows applications to maintain long-lived sessions without re-authenticating the user, while still enforcing token expiration and rotation.

Where OIDC Struggles

Less mature in legacy enterprise: Many older enterprise applications (especially those deployed before 2015) support SAML but not OIDC. If your organization runs legacy on-premises software, SAML may be the only option for some applications.

OAuth 2.0 complexity: OIDC inherits OAuth 2.0’s complexity — multiple grant types, token types, and flows. Choosing the wrong flow can introduce security vulnerabilities. For example, the Implicit Flow (once common for SPAs) is now deprecated due to token leakage risks.

Token management burden: JWTs are self-contained, which means they cannot be revoked before expiration without additional infrastructure (token revocation endpoints, denylist databases). SAML assertions, by contrast, are validated at the time of use and not stored for repeated use.

No standard attribute mapping: While OIDC defines a set of standard claims (sub, email, name, groups), the actual attributes returned vary by provider. Mapping provider-specific claims to application attributes requires per-provider configuration.

Side-by-Side Comparison

Aspect SAML 2.0 OIDC
Year 2005 2014
Data format XML JSON / JWT
Transport Browser redirects + POST HTTPS + browser redirects
Token format XML Assertion JSON Web Token (JWT)
Signing XML Signature (XMLDsig) JSON Web Signature (JWS)
Encryption XML Encryption JSON Web Encryption (JWE)
API authorization Not supported Native (OAuth 2.0 access tokens)
Mobile apps Poor (browser-only) Native (PKCE flow)
SPAs Poor Native (PKCE flow)
Discovery XML metadata exchange .well-known/openid-configuration
Logout SLO (unreliable in practice) Front-channel + back-channel
Delegated access No Yes (OAuth 2.0 scopes)
Enterprise legacy Dominant Growing
Developer experience Complex (XML, certs) Simple (JSON, JWTs)
Implementation effort Days to weeks Hours to days

When to Choose SAML

Choose SAML when:

  • The application only supports SAML — many legacy enterprise apps (Workday, SAP, older ServiceNow versions) require SAML. You don’t get to choose.
  • IdP-initiated SSO is required — SAML’s IdP-initiated flow lets users launch apps from a portal dashboard. OIDC has no standard equivalent (though some providers implement proprietary versions).
  • You need encrypted assertions — SAML supports encrypting the entire assertion so that intermediate proxies cannot read the user’s attributes. OIDC supports JWT encryption (JWE) but it is less commonly implemented.
  • Your organization is already SAML-centric — if every application already uses SAML and the team has SAML expertise, adding another SAML SP is simpler than introducing OIDC.

When to Choose OIDC

Choose OIDC when:

  • You are building a new application — OIDC is simpler to implement, better documented, and has libraries for every platform. There is no reason to implement SAML in a new application.
  • Mobile or SPA clients — OIDC with PKCE is the standard for mobile and single-page applications. SAML cannot do this.
  • API access is needed — if the application needs to call APIs on behalf of the user, OIDC’s OAuth 2.0 access tokens handle this natively. SAML does not.
  • Microservice architectures — JWTs are lightweight and can be verified without contacting the IdP, making them ideal for distributed systems where every service needs to validate identity.
  • You want simple setup — OIDC’s discovery endpoint and JSON-based configuration are dramatically easier to configure than SAML’s XML metadata exchange.

You Don’t Have to Choose Just One

Most modern identity providers — including Authentik, Okta, Azure AD, and Auth0 — support both SAML and OIDC simultaneously. This means your organization can use OIDC for new applications and APIs while keeping SAML for legacy systems that require it.

The practical strategy for most organizations:

  1. Default to OIDC for all new applications, APIs, and mobile clients
  2. Use SAML only when the application does not support OIDC
  3. Configure your IdP to handle both protocols, presenting a unified login experience regardless of which protocol the application uses
  4. Plan SAML-to-OIDC migration for legacy apps as vendors add OIDC support (most enterprise vendors are adding OIDC to their products)

The ResorsIT Approach

ResorsIT uses Authentik as its identity provider, and Authentik supports both SAML 2.0 and OIDC natively. Our integration strategy follows the practical approach above:

OIDC is the default protocol for ResorsIT platform components and customer-facing applications. Every ResorsIT service — from the resource manager to the proxy layer to Git hosting (Forgejo) — authenticates via OIDC. OIDC’s simplicity, API support, and developer-friendly tooling make it the natural choice for a modern platform built on Go and Vue.js.

SAML is supported for customer applications that require it. When a ResorsIT customer runs a legacy enterprise application that only speaks SAML, Authentik serves as the SAML IdP for that application while simultaneously serving as the OIDC provider for everything else. The user sees one login screen regardless of which protocol the application behind it uses.

This dual-protocol approach means ResorsIT customers are never forced to choose. New applications get the simplicity and power of OIDC. Legacy applications get the SAML support they need. And the identity provider — Authentik — handles the translation seamlessly.


For more on how ResorsIT handles identity and access management, see our article on Beyond SSO: The ResorsIT IAM Solution. For the fundamentals of identity verification, read Four Kinds of Identity.

Visit our other Insight Articles or explore our comprehensive IT Operations Management solutions.