SSO, SAML, and OpenID Connect: How Enterprise Login Works

Fractional CTO · Founder of Injuria.ai
Single Sign-On, or SSO, is the ability for a user to log in once to a central authority and then access multiple independent applications without re-entering their credentials.[21] For users, it's a convenience. For an enterprise, it's a critical security and administration control plane. It centralizes user management, simplifies access revocation, and enables consistent policy enforcement. This capability isn't magic; it's built on standardized communication protocols that allow applications to trust an external system for authentication.
The two dominant protocols that power almost all modern SSO are SAML 2.0 and OpenID Connect.[22] While they achieve similar goals, they were born in different eras and are designed with different philosophies. Understanding how they work, their history, and their respective strengths is essential for anyone building or managing software in an enterprise context. This is not just about integrating a "Log in with Google" button; it's about the fundamental architecture of trust on the internet.
The Core Problem: Identity and Trust
At its heart, SSO solves a problem of distributed trust. Imagine your company uses dozens of SaaS applications: a CRM, a code repository, an HR platform, and a project management tool. Each application needs to know who its users are. Without SSO, each application maintains its own separate user database with usernames and passwords. This creates a nightmare for administration. When an employee joins, they need dozens of accounts. When they leave, an administrator must diligently find and deactivate every single one. Users are burdened with remembering many passwords, leading to poor security practices like password reuse.
SSO reframes this problem by establishing two distinct roles:
-
Identity Provider (IdP): This is the single, authoritative source of truth for user identity. It manages the user directory, credentials (passwords, MFA tokens), and performs the act of authentication. Examples include Microsoft Entra ID (formerly Azure AD), Okta[1], and Google Workspace.[23] The NIST glossary[2] defines an Identity Provider (IdP) as 'The party in a federation transaction that creates an assertion for the subscriber and transmits the assertion to the RP.'
-
Service Provider (SP) or Relying Party (RP): This is the application the user wants to access, like Salesforce or GitHub. This application provides a service but relies on the IdP to handle the authentication. In SAML terminology, this is the Service Provider[3]. In OpenID Connect, it's called the Relying Party[4].
The core of SSO is a standardized, secure conversation between the IdP and the SP. The SP needs to ask the IdP, "Is this user who they say they are?" The IdP's job is to answer that question definitively. The protocols, SAML and OpenID Connect, are the languages they use for this conversation.[24]
SAML: The Enterprise Workhorse
Security Assertion Markup Language (SAML) is a mature, XML-based standard for exchanging authentication and authorization data. Its history dates back to the early 2000s, with work by the Liberty Alliance[5] and the OASIS[6] standards body.[25] The version in widespread use today, SAML 2.0, was ratified in 2005[7] and remains a cornerstone of enterprise identity.
How SAML Works: The SP-Initiated Flow
The most common SAML workflow is called the "SP-Initiated Flow," where the user's journey begins at the application they want to use. The entire exchange happens through the user's browser via HTTP redirects and form posts, meaning the SP and IdP never need to communicate directly over the network.
Here is the step-by-step mechanism:
-
Access Request: A user navigates to the SP, for example
https://your-company.salesforce.com. -
Authentication Check & Redirect: The SP checks for an active session cookie. Finding none, it determines the user must be authenticated. Instead of showing a password field, it crafts a
SAMLRequest. This is an XML document, typically compressed and Base64-encoded, containing information like which SP is making the request and where the IdP should send the user back. The SP then redirects the user's browser to the IdP's SSO endpoint with thisSAMLRequestin a URL query parameter. -
IdP Authentication: The user's browser arrives at the IdP's login page, for example
https://login.microsoftonline.com. The IdP first authenticates the user. This is where the user enters their password, uses a hardware key, or responds to a push notification. If the user already has an active SSO session with the IdP, this step may be skipped entirely. -
Assertion Generation: Once authenticated, the IdP generates a SAML Assertion. This is the core of the exchange: a digitally signed XML document stating that the IdP has successfully authenticated a specific user at a specific time. It includes the user's identifier (like an email address) and can contain additional attributes like their name, department, or group memberships.
-
POST to SP: The IdP sends a response to the user's browser. This response is an HTML page with a form that is set to automatically submit itself using JavaScript. The form's
actionattribute points to the SP's Assertion Consumer Service (ACS)[8] URL. Inside this form is a hidden input field namedSAMLResponsecontaining the Base64-encoded SAML Assertion. This is known as the HTTP POST Binding[9]. -
SP Validation: The user's browser automatically POSTs the form to the SP's ACS endpoint. The SP's server receives the
SAMLResponse, decodes it, and parses the XML assertion. Crucially, it must validate the assertion's digital signature. Before the integration was set up, the SP administrator uploaded the IdP's public certificate. The SP uses this public key to verify that the assertion was signed by the trusted IdP and has not been tampered with. It also checks that the assertion is valid (e.g., not expired) and intended for this SP (the audience). -
Session Creation: If the signature is valid and all checks pass, the SP trusts the information within the assertion. It finds or creates a local user account corresponding to the identifier in the assertion and establishes a session for that user by setting a cookie. The user is now logged in and redirected to their destination within the application.
The SAML Assertion
A SAML Assertion is verbose, but its structure is logical. It contains all the information the SP needs to trust the user's identity. Here is a simplified example:
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_abc123" IssueInstant="2024-05-21T10:00:00Z" Version="2.0">
<saml:Issuer>https://idp.example.com/saml</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<!-- Digital signature of the assertion -->
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">jane.doe@example.com</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2024-05-21T10:05:00Z" Recipient="https://sp.example.com/acs"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2024-05-21T09:55:00Z" NotOnOrAfter="2024-05-21T10:05:00Z">
<saml:AudienceRestriction>
<saml:Audience>https://sp.example.com/metadata</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AttributeStatement>
<saml:Attribute Name="FirstName">
<saml:AttributeValue>Jane</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="LastName">
<saml:AttributeValue>Doe</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
<Issuer>: Identifies the IdP that issued the assertion.<Signature>: The XML Signature[10] that guarantees authenticity and integrity.<Subject>: Identifies the user who was authenticated.<Conditions>: Specifies constraints, like the assertion's validity window (NotBefore,NotOnOrAfter) and the intended audience (the SP).<AttributeStatement>: Contains additional user attributes (claims) that the SP can use for provisioning or authorization.
OpenID Connect: The Modern Standard for Web and Mobile
OpenID Connect (OIDC) is an identity layer built on top of the OAuth 2.0[11] authorization framework. Finalized in 2014 by the OpenID Foundation, OIDC was designed for the modern web of APIs, mobile apps, and Single Page Applications (SPAs).
It's critical to understand the relationship with OAuth 2.0. OAuth 2.0 is a protocol for authorization, delegating access. It allows an application to access resources on behalf of a user (e.g., "Can this app post to my timeline?"). It does not, by itself, provide information about who the user is. OIDC extends OAuth 2.0 to add this missing authentication piece, providing a verifiable identity assertion.
How OIDC Works: The Authorization Code Flow
The most common and secure OIDC flow for web applications is the Authorization Code Flow. It is analogous to the SAML SP-Initiated flow but involves a direct back-channel communication step.
Here is the step-by-step mechanism:
-
Login Request: A user clicks a "Log in with..." button on the Relying Party (RP). The RP is the OIDC term for the application.
-
Redirect to OP: The RP constructs a URL and redirects the user's browser to the OpenID Provider (OP), like Google or Auth0. The URL includes parameters like:
response_type=code: Specifies the Authorization Code Flow.client_id: The public identifier for the RP, pre-registered with the OP.redirect_uri: The URL where the OP will send the user back after login. This must be pre-registered for security.scope: Must includeopenidto signal an OIDC request. It can also include other scopes likeprofileandemailto request more user information.state: A random string generated by the RP to prevent CSRF attacks.
-
OP Authentication & Consent: The user arrives at the OP. The OP authenticates the user. If this is the first time the user is logging into this RP, the OP will typically display a consent screen: "App X wants to know your name and email address. Allow?"
-
Redirect with Authorization Code: After successful authentication and consent, the OP redirects the user's browser back to the RP's
redirect_uri. The redirect includes a short-lived, one-time-usecodeand the originalstatevalue from step 2. -
Code-for-Token Exchange: The RP's backend server receives the request. It first checks that the returned
statevalue matches the one it sent. Then, it makes a direct, secure, back-channel HTTP POST request to the OP's token endpoint. This request is not visible to the browser. It includes thecodeit just received, along with itsclient_idand aclient_secret(a password for the application itself, known only to the RP and OP). -
Receive and Validate Tokens: The OP validates the code,
client_id, andclient_secret. If everything is correct, it returns a JSON object containing several tokens. For OIDC, the most important one is theid_token. It also typically returns anaccess_token(for accessing APIs) and arefresh_token. -
ID Token Validation & Session Creation: The
id_tokenis a JSON Web Token (JWT)[12]. The RP must validate it by:
- Checking its digital signature using the OP's public key (which can be dynamically discovered from a
.well-knownendpoint). - Verifying that the
iss(issuer) andaud(audience) claims in the JWT payload match the OP and its ownclient_id. - Checking that the token is not expired (
expclaim).
- User Identified: After validation, the RP trusts the claims inside the JWT. The
sub(subject) claim provides a stable, unique identifier for the user. The RP uses this and other claims (likeemail) to identify the user, create a session, and grant access.
The ID Token (JWT)
A JWT is a compact, URL-safe string that consists of three Base64Url-encoded parts separated by dots: Header.Payload.Signature. It's much more concise than SAML's XML.
Here's what the decoded payload of a typical id_token looks like:
{
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"aud": "1234567890-abc.apps.googleusercontent.com",
"iat": 1684663200,
"exp": 1684666800,
"email": "jane.doe@example.com",
"email_verified": true,
"name": "Jane Doe"
}
These are some of the standard JWT claims[13]: iss (Issuer), sub (Subject), aud (Audience), exp (Expiration Time), and iat (Issued At). OIDC adds others like email and name.
Key Differences and Decision Factors
Choosing between SAML and OIDC depends on your specific use case, existing infrastructure, and development goals.
| Feature | SAML 2.0 | OpenID Connect |
|---|---|---|
| Primary Format | XML | JSON (JWT) |
| Signature | XML Digital Signature | JSON Web Signature (JWS) |
| Typical Use Case | Enterprise web SSO | Web, mobile, SPA, API security |
| Configuration | Often manual exchange of XML metadata files | Often dynamic via discovery endpoints |
| Client Support | Browser-based flows | Native support for various clients (web, mobile, server) |
| Complexity | Verbose and complex to parse/debug | More lightweight, but has many flows (code, implicit, hybrid) |
When to Choose What
-
Choose SAML when: You are integrating with established enterprise software that has long-standing, robust SAML support (e.g., Salesforce, Workday). Many large organizations built their identity infrastructure around SAML and require it for any new application integration. If your primary goal is to sell to large enterprises, supporting SAML is often a business requirement.
-
Choose OpenID Connect when: You are building a new application from scratch, especially one with mobile or single-page application components. OIDC's reliance on JSON and tokens fits naturally into modern API-driven architectures. It is the protocol of choice for consumer-facing social logins ("Log in with Google/Facebook/Apple") and is generally considered easier for developers to work with.
-
Supporting Both: For a B2B SaaS application, the pragmatic answer is often to support both. You can use OIDC as your primary, modern protocol and add SAML support to meet the requirements of large enterprise customers. Identity platforms like Auth0[14] or cloud services like AWS IAM Identity Center[15] can act as a bridge, allowing you to implement one protocol while they handle the translation to the other for specific connections.
Common Misconceptions
-
"SSO is a product." SSO is a capability, not a product you can buy off the shelf. It is enabled by implementing protocols like SAML or OIDC to connect an SP/RP to an IdP/OP. You buy an IdP product, and you integrate your application with it using a standard protocol.
-
"SAML/OIDC handles authorization." This is a critical distinction. These protocols are primarily for authentication, verifying who a user is. While a SAML assertion or OIDC ID Token can carry attributes (like group memberships or roles) that an application can use to make authorization decisions, the application itself is still responsible for enforcing those decisions. The IdP says "This is Jane from Engineering." The SP must decide what Jane from Engineering is allowed to do.
-
"OAuth 2.0 and OIDC are the same." They are not. OAuth 2.0 is for delegated access (authorization). OIDC is a layer on top of it that adds user authentication. You can use OAuth 2.0 without OIDC, but you cannot use OIDC without OAuth 2.0.[26]
Implementation and Operational Reality
Never build your own IdP. The implementation of these protocols, especially the cryptographic and security-sensitive parts, is extraordinarily difficult to get right. A tiny mistake can lead to a catastrophic vulnerability. Always use a well-vetted, certified commercial IdP or open-source server. For your application (the SP/RP), use a trusted library for the protocol you're implementing. Don't parse raw XML or JWTs yourself.[27]
Key Failure Modes:
- Certificate Expiration: In SAML, the IdP's signing certificate expires. If the SP doesn't have the new one, all logins will fail. This requires coordination between the IdP and SP administrators.
- Clock Skew: Both protocols rely on timestamps (
IssueInstant,exp,iat) to prevent replay attacks. If the server clocks on the IdP and SP drift apart by more than a few minutes, assertions and tokens will be considered invalid. Servers should use the Network Time Protocol (NTP)[16] to keep clocks synchronized. - Misconfigured Endpoints: A typo in an ACS URL or a
redirect_uriwill break the entire flow. OIDC's strictredirect_urimatching is a security feature to prevent tokens from being leaked to an attacker. - PKCE is Essential for Public Clients: For mobile apps and SPAs that cannot securely store a
client_secret, the Proof Key for Code Exchange (PKCE)[17] extension to OAuth/OIDC is non-negotiable. It prevents an attacker from intercepting the authorization code and using it.
The State of Identity Today
SAML remains deeply embedded in the enterprise ecosystem and will not disappear anytime soon. Its stability and widespread support in legacy systems make it a persistent requirement. However, all new development momentum is with OIDC. It is the default choice for customer-facing identity, mobile applications, and securing APIs.
Looking forward, the landscape is changing at the point of user interaction. The rise of phishing-resistant credentials through WebAuthn Level 2[18], the current W3C Recommendation as of August 2026, and passkeys[19] is transforming how users prove their identity to the IdP. This innovation strengthens the initial authentication step, but it doesn't replace the need for federation protocols. The IdP still needs to communicate that successful authentication to the SP, and that communication will continue to run over SAML and OIDC for the foreseeable future. Advanced standards like the Continuous Access Evaluation Protocol (CAEP)[20] are also being built on the OIDC event-based model to allow IdPs to notify SPs of security events in real-time, moving beyond the simple check at login time.
Sources (27)
- Okta
- csrc.nist.gov
- NIST - Service Provider Definition
- OpenID Connect Core 1.0 - Relying Party
- Wikipedia - Liberty Alliance
- OASIS Standards Body
- SAML 2.0 Core Specification
- SAML 2.0 Glossary - Assertion Consumer Service
- SAML 2.0 Bindings - HTTP POST Binding
- W3C - XML Signature Syntax and Processing
- IETF RFC 6749 - The OAuth 2.0 Authorization Framework
- IETF RFC 7519 - JSON Web Token (JWT)
- IETF RFC 7519 - JWT Claims
- Auth0 by Okta
- AWS IAM Identity Center
- Wikipedia - Network Time Protocol (NTP)
- IETF RFC 7636 - Proof Key for Code Exchange (PKCE)
- W3C - Web Authentication (WebAuthn)
- FIDO Alliance - Passkeys
- OpenID - Continuous Access Evaluation Protocol (CAEP)
- Emmett Dulaney, Chuck Easttom, CompTIA Security+ Study Guide (John Wiley & Sons, 2017)
- Mostapha Zbakh, Mohammed Essaaidi, Claude Tadonki, Artificial Intelligence and High Performance Computing in the Cloud (Springer Nature, 2024)
- Jorge T. Negron, Christoffer Jones, George Sawyer, AWS Certified SysOps Administrator Study Guide (John Wiley & Sons, 2024)
- James Michael Stewart, CompTIA Security+ Review Guide (John Wiley & Sons, 2017)
- Norbert Pohlmann, Helmut Reimer, Wolfgang Schneider, ISSE 2011 Securing Electronic Business Processes (Springer, 2019)
- Roger A. Grimes, Hacking Multifactor Authentication (John Wiley & Sons, 2020)
- Yvonne Wilson, Abhishek Hingnikar, Solving Identity Management in Modern Applications (Apress, 2019)