SSOGEN / Learn / SAML vs OIDC: One Sign-In, Two Formats
Learn
SAML vs OIDC: One Sign-In, Two Formats
SAML and OpenID Connect carry the same facts about a sign-in, one as signed XML and one as a signed JSON token; what you connect decides which fits.
Updated

SAML vs OIDC, in short. SAML 2.0 (OASIS, 2005) and OpenID Connect (OpenID Foundation, 2014) solve the same problem: single sign-on to an application. SAML packs the sign-in into a signed XML assertion that the browser posts to the application. OIDC packs it into a signed JSON Web Token, the ID token, which the application’s server collects with a one-time code. Pick by what the application supports first, and by application type second.
Whether you search “oidc vs saml” or “saml vs oidc”, the facts below are the same; the order of the names changes nothing.
The same sign-in, written both ways
John Doe of Acme Corp opens Acme Timesheets at 15:04:05 UTC on 2026-11-15. He signed in two seconds earlier with a password and an authenticator code. The identity provider at sso.acme.example vouches for him twice: once as SAML, once as OIDC. Long signatures are cut to ....
As a SAML assertion (inside the response posted to the application’s ACS URL):
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_9d41c0e2b7" Version="2.0" IssueInstant="2026-11-15T15:04:05Z"> <saml:Issuer>https://sso.acme.example</saml:Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"> u-7f3c9a2e </saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData InResponseTo="_req-51ab" Recipient="https://timesheets.acme.example/saml/acs" NotOnOrAfter="2026-11-15T15:09:05Z"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2026-11-15T15:03:35Z" NotOnOrAfter="2026-11-15T15:09:05Z"> <saml:AudienceRestriction> <saml:Audience>https://timesheets.acme.example/saml/metadata</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2026-11-15T15:04:03Z" SessionIndex="_s-8c21"> <saml:AuthnContext> <saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> <saml:AttributeStatement> <saml:Attribute Name="email"><saml:AttributeValue>john.doe@acme.example</saml:AttributeValue></saml:Attribute> <saml:Attribute Name="name"><saml:AttributeValue>John Doe</saml:AttributeValue></saml:Attribute> <saml:Attribute Name="groups"> <saml:AttributeValue>Finance</saml:AttributeValue> <saml:AttributeValue>Timesheet-Approvers</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement></saml:Assertion>As an OIDC ID token (header and payload of the JWT, decoded; the application’s server receives it from the token endpoint):
{ "alg": "RS256", "typ": "JWT", "kid": "acme-2026-11" }{ "iss": "https://sso.acme.example", "sub": "u-7f3c9a2e", "aud": "timesheets-web", "exp": 1794755345, "iat": 1794755045, "auth_time": 1794755043, "nonce": "n-0S6_WzA2Mj", "amr": ["pwd", "otp"], "sid": "s-8c21", "email": "john.doe@acme.example", "name": "John Doe", "groups": ["Finance", "Timesheet-Approvers"]}Field by field
| What the application learns | SAML element | OIDC claim | What to notice |
|---|---|---|---|
| Who vouches | Issuer |
iss |
Same value here; must match the configured identity provider exactly |
| Who the person is | NameID (persistent) |
sub |
Both opaque and stable. An identity provider may issue different values per protocol |
| Who it is for | Audience (an entity ID URL) |
aud (the client ID) |
SAML names the application by URL, OIDC by client ID |
| Tied to this request | InResponseTo |
nonce |
Stops a captured response being replayed into a new session |
| Valid until | NotOnOrAfter (ISO 8601) |
exp (seconds since 1970) |
15:09:05 UTC in both: a five-minute life |
| When he signed in | AuthnInstant |
auth_time |
Two seconds before issue |
| How he signed in | AuthnContextClassRef |
amr |
PasswordProtectedTransport cannot say “plus an authenticator code”; pwd and otp (RFC 8176) can |
| Session for logout | SessionIndex |
sid |
Used by SAML Single Logout and OIDC back-channel logout |
| Profile data | Attribute elements |
email, name |
Standard claims in OIDC; names agreed per application in SAML |
| Groups | Attribute Name="groups" |
groups |
Not standard in either; both carry it as a custom name |
| Proof | XML Signature over the element | JWS signature over the token, key kid |
SAML keys come from metadata certificates, OIDC keys from a JWKS URL |
The table is the practical answer: the facts match one for one. What differs is encoding, transport and the tooling around them.
What differs beyond the token
| SAML 2.0 | OpenID Connect | |
|---|---|---|
| Encoding | XML, signed with XML Signature | JSON, signed as a JWT (JWS) |
| How it reaches the application | The browser posts it to the ACS URL | The server swaps a one-time code at the token endpoint |
| Configuration exchange | Metadata XML with X.509 certificates | Discovery at /.well-known/openid-configuration and a JWKS |
| Native and single-page apps | Awkward: built around browser POST | Designed for them, with PKCE |
| API access in the same flow | None | An access token comes with the ID token |
| Logout | Single Logout over front or back channel | RP-initiated, front-channel and back-channel logout specifications |
| Typical home | Enterprise SaaS and packaged applications | Applications you write, mobile apps, newer SaaS |
Which to use, application by application
| The application | Choose | Reason |
|---|---|---|
| A SaaS product whose SSO page asks for IdP metadata or an entity ID | SAML | That is what it implements |
| A SaaS product that offers both | Either; prefer the one its documentation tests most | Both carry the same facts |
| A web application your team writes | OIDC | Libraries in every language, JSON instead of XML |
| A single-page or mobile app | OIDC with PKCE | SAML’s browser POST does not fit |
| An app that must also call your APIs as the user | OIDC | One flow returns the ID token and the access token |
| A package behind Apache with neither protocol | Neither | Use an agent or proxy; see choose how to connect an app |
The trap when moving an app from SAML to OIDC
- Subject continuity. The app keyed John’s account on
NameID. After the switch it keys onsub. If the two values differ, John gets a second, empty account. - Email is not an identifier. Matching on email hides the problem until someone’s address changes.
- The fix. Before cutover, confirm the identity provider sends the same stable value as
subthat it sent asNameID, or map old to new in the application. - Groups move too. A custom
groupsattribute needs the same custom claim on the OIDC side.
How SSOGEN handles SAML and OIDC
SSOGEN is both a SAML identity provider and an OpenID provider, so one application can be registered either way:
- SAML. The default NameID is an opaque
persistentidentifier, with the email address as an option. The Test step shows the assertion a chosen user would receive before anything is activated. - OIDC. Authorization code flow only, with PKCE
S256on every sign-in. Claims such asemailandnamefollow theprofileandemailscopes. - Same rules for both. Assignments and the sign-in policy apply the same way whichever protocol the application uses.
The guide to choosing how to connect an application covers SAML, OIDC, the Web Agent and the App Proxy in one table.
Questions people ask
What are the key differences between SAML2 and OIDC?
SAML 2.0 sends a signed XML assertion through the browser and configures trust with metadata files. OIDC sends a signed JSON ID token that the application’s server fetches with a one-time code, and configures trust with discovery and a JWKS. OIDC suits mobile and single-page apps and also returns an access token for APIs.
What are the differences between OAuth and OIDC?
OAuth 2.0 issues access tokens so a client can call an API; it does not say who the user is. OIDC adds the ID token on top of OAuth, which is what makes it a sign-in protocol. SAML has no OAuth layer at all. OIDC vs OAuth has the full comparison.
Does Google use SAML or OIDC?
Both. Google Workspace accepts SAML-based and OIDC-based single sign-on from a third-party identity provider, with SAML SSO profiles or an OIDC profile that uses the authorization code flow. Google’s own OAuth 2.0 sign-in for other applications is OpenID Certified.
What is the difference between SAML and federation?
Federation is the arrangement: one organization’s identity provider is trusted by applications or partners it does not run. SAML is one protocol that implements it; OIDC is another. Saying “federated SSO” describes the trust, not the format. Federated identity explains the model.
Where to go next
- The SAML flow step by step. Read SAML authentication, and the SAML assertion for every check a service provider runs.
- Sign-in versus accounts. SCIM vs SAML separates provisioning from sign-in.
- The OAuth layer. OIDC vs OAuth shows where the ID token comes from.
- More explainers. Browse Learn.
Sources, all read 2026-11-15: SAML 2.0 Core (OASIS), OpenID Connect Core 1.0, OpenID Connect Discovery 1.0, RFC 8176, authentication method reference values, Google Workspace: set up SSO, Google Identity: OpenID Connect.