By AndyPublished

JWT vs SAML: Tokens, Assertions and Single Sign-On

SAML 2.0 and JWT are both ways for an identity provider to tell an application “this user has authenticated, and here are their attributes” in a form the application can verify. SAML does it with an XML assertion signed using XML Signature and delivered through the browser. JWT does it with a compact JSON token signed using JWS; in single sign-on that token is the OpenID Connect ID token. Strictly, SAML is a whole protocol and JWT is only a token format, so the like-for-like comparison is SAML vs OpenID Connect.

In practice: SAML remains the standard for enterprise web SSO into SaaS applications, and every serious identity provider supports it. JWT-based OpenID Connect is the default for new applications, mobile and single-page apps, and anything that also needs to call APIs. Many organisations run both.

JWT vs SAML Token: Format Compared

A SAML assertion and an OIDC ID token carry almost the same information. Here is an abbreviated SAML 2.0 assertion, with namespaces and most of the signature trimmed:

<saml:Assertion ID="_a75adf55" IssueInstant="2026-09-24T09:00:00Z" Version="2.0">
  <saml:Issuer>https://idp.example.com/saml</saml:Issuer>
  <ds:Signature>
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
      <ds:Reference URI="#_a75adf55">...</ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>kJ3x...</ds:SignatureValue>
  </ds:Signature>
  <saml:Subject>
    <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">ada@example.com</saml:NameID>
    <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
      <saml:SubjectConfirmationData InResponseTo="_req42" NotOnOrAfter="2026-09-24T09:05:00Z"
        Recipient="https://app.example.com/saml/acs"/>
    </saml:SubjectConfirmation>
  </saml:Subject>
  <saml:Conditions NotBefore="2026-09-24T08:59:30Z" NotOnOrAfter="2026-09-24T09:05:00Z">
    <saml:AudienceRestriction><saml:Audience>https://app.example.com</saml:Audience></saml:AudienceRestriction>
  </saml:Conditions>
  <saml:AuthnStatement AuthnInstant="2026-09-24T09:00:00Z" SessionIndex="_s1"/>
  <saml:AttributeStatement>
    <saml:Attribute Name="groups"><saml:AttributeValue>engineering</saml:AttributeValue></saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>

And the decoded payload of an equivalent OpenID Connect ID token:

{
  "iss": "https://idp.example.com",
  "sub": "00u1a2b3c4",
  "aud": "app-client-id",
  "iat": 1790240400,
  "exp": 1790240700,
  "auth_time": 1790240400,
  "nonce": "n-0S6_WzA2Mj",
  "email": "ada@example.com",
  "groups": ["engineering"]
}

The ID token is then signed as a JWS and serialised as header.payload.signature. The fields map closely:

SAML assertionJWT / OIDC claim
<Issuer>iss
<Subject><NameID>sub
<AudienceRestriction><Audience>aud
<Conditions NotBefore>nbf
<Conditions NotOnOrAfter>exp
<Assertion IssueInstant>iat
<Assertion ID>jti
<AuthnStatement AuthnInstant>auth_time (OIDC)
<AuthnContextClassRef>acr (OIDC)
<SubjectConfirmationData InResponseTo>nonce (OIDC, roughly equivalent)
<AttributeStatement>Custom or standard claims (email, name, groups)

Each JWT claim is described in JWT claims explained. The validation rules are the same idea on both sides: right issuer, right audience, inside the time window, signature valid.

JWT vs SAML Authentication: The Full Comparison

AspectSAML 2.0JWT (via OpenID Connect)
What it isA full federation protocol (SAML 2.0, OASIS, 2005) plus its assertion formatA token format (RFC 7519); the protocol is usually OpenID Connect or OAuth 2.0
EncodingXML, Base64-encoded when sent through the browserJSON, Base64url-encoded, three dot-separated segments
SignatureXML Signature (XML-DSig) over a canonicalised XML elementJWS (RFC 7515) over the exact encoded header and payload bytes
EncryptionXML Encryption: EncryptedAssertionJWE (RFC 7516), rarely used for ID tokens
Key distributionX.509 certificate in SAML metadata XMLJWKS endpoint advertised by the OIDC discovery document
Typical sizeSeveral KB; too large for an HTTP headerUsually under 1 KB; designed for headers and URLs
TransportBrowser redirects and auto-submitting POST formsToken endpoint responses, then Authorization headers
Primary useEnterprise web SSOConsumer and enterprise sign-on, mobile and SPA apps, API access
API and mobile supportPoor: built for browser-to-web-app flowsNative: tokens are sent directly to APIs

SSO With JWT vs SAML: How the Flows Differ

SAML SP-initiated SSO

  • ·The user opens the application (the service provider). It builds an AuthnRequest and redirects the browser to the identity provider, usually with the HTTP-Redirect binding.
  • ·The user authenticates at the IdP.
  • ·The IdP returns an HTML page containing an auto-submitting form that POSTs a Base64-encoded SAMLResponse to the application’s Assertion Consumer Service (ACS) URL.
  • ·The application verifies the XML signature, checks audience, recipient, time conditions and InResponseTo, then creates its own session, typically a cookie.

SAML also supports IdP-initiated SSO, where the user starts from a portal tile and the IdP posts an unsolicited response. It is convenient but removes the request binding that protects against replayed and injected responses.

OpenID Connect SSO

  • ·The application redirects the browser to the provider’s /authorize endpoint with scope=openid, a state, a nonce and a PKCE challenge.
  • ·The user authenticates; the browser comes back with a short-lived authorisation code.
  • ·The application exchanges the code at the token endpoint over a direct back-channel call and receives an ID token (a JWT) and usually an access token.
  • ·The application verifies the ID token against the provider’s JWKS and creates its session.

The structural difference: in SAML the token travels through the browser, so its signature is the only protection. In the OIDC code flow the token comes from a server-to-server call over TLS, which removes a whole class of injection problems. The access token from the same flow can then be used to call APIs, which SAML has no native answer for. The OIDC side is covered in JWTs in OAuth 2.0 and OpenID Connect.

Security: XML Signatures vs JWS

Both formats have a history of implementation bugs, and they differ in kind.

  • ·SAML: XML Signature signs one element inside a larger document, after canonicalisation. That creates XML Signature Wrapping attacks, where an attacker moves the signed element and inserts an unsigned one that the application reads instead. XML parsers add XXE and entity-expansion risks, and comment handling in NameID has caused authentication bypasses in several libraries.
  • ·JWT: the signature covers the exact bytes of the header and payload, so there is no wrapping problem. The classic flaws are in header trust instead: accepting alg: none, algorithm confusion between RSA and HMAC, and unvalidated kid or jku values. See the none algorithm vulnerability and JWT attacks and vulnerabilities.
⚠
For both, the defence is the same: use a mature, maintained library, never parse or verify signatures by hand, pin the expected algorithm and signing key, and validate audience, issuer and time conditions on every token.

Validating a SAML Assertion vs a JWT

The checks a relying party must run are close to identical, which is a useful way to see that the two formats solve the same problem. For each item, the SAML check is on the left and the JWT check on the right.

  • ·Signature: verify the XML signature with the IdP certificate from metadata, and confirm the signed element is the one you read / verify the JWS with the key from the JWKS matching kid, using a pinned algorithm.
  • ·Issuer: Issuer equals the configured IdP entity ID / iss equals the configured issuer URL, exactly.
  • ·Audience: your SP entity ID appears in AudienceRestriction / your client ID appears in aud.
  • ·Time window: now is between NotBefore and NotOnOrAfter / now is before exp and not before nbf, with a small clock-skew allowance on both.
  • ·Binding to your request: InResponseTo matches the AuthnRequest you sent and Recipient matches your ACS URL / nonce matches the one you stored before redirecting.
  • ·Replay: remember assertion IDs until they expire and reject repeats / the code flow makes ID token replay much harder, and jti can be tracked where needed.

The JWT side of this list is covered claim by claim in the JWT verification guide, and the time checks, including clock skew, in common JWT errors. On the SAML side, the most important habit is to read attributes only from the element whose signature you verified, never by searching the whole document.

Using JWT and SAML Together

The two are not mutually exclusive, and mixed estates are common:

  • ·Identity brokering: a broker such as Keycloak or a hosted identity platform accepts SAML from a customer’s corporate IdP and issues OIDC ID tokens and JWT access tokens to your applications. Your apps only ever see JWTs.
  • ·SAML bearer grant: RFC 7522 lets a client exchange a SAML 2.0 assertion at an OAuth token endpoint for an access token, which may be a JWT.
  • ·Token exchange: RFC 8693 defines token type identifiers for both SAML 1.1 and SAML 2.0 assertions alongside JWTs, so a security token service can convert between them.

Where JWT and SAML Are Used Today

  • ·SAML: workforce SSO into SaaS products, where enterprise customers expect a SAML option from Okta, Microsoft Entra ID, Google Workspace or ADFS; higher-education and research federations; many government and legacy line-of-business systems.
  • ·JWT / OIDC: consumer sign-in (Google, Apple, Microsoft accounts), mobile and single-page apps, B2B SaaS built in the last decade, API authorisation, and service-to-service identity.

If you are building a new B2B application, the pragmatic answer is usually to implement OIDC yourself and support SAML through a broker or identity platform, because some enterprise customers will require it. If you only need to call APIs, SAML is the wrong tool. To inspect an ID token or access token from either route, paste it into the jwtdecode.app decoder, which decodes it in the browser without sending it anywhere.

JWT vs OAuth vs SAML

The three sit at different layers. SAML is a federation protocol for authentication with its own XML token. OAuth 2.0 is an authorisation framework for API access and does not define authentication at all. JWT is a token format used by OpenID Connect (for authentication) and by many OAuth deployments (for access tokens). A modern stack typically pairs OIDC and OAuth with JWTs; SAML sits alongside for enterprise SSO. JWT vs OAuth covers the second half of that picture.

Summary

  • ·SAML is a complete SSO protocol with XML assertions; JWT is a token format, used for SSO through OpenID Connect.
  • ·SAML assertions are signed with XML-DSig and delivered through browser POSTs; JWTs are signed with JWS and fit in HTTP headers.
  • ·The claims map almost one-to-one: Issuer to iss, NameID to sub, Audience to aud, NotOnOrAfter to exp.
  • ·SAML remains the enterprise SSO standard; OIDC with JWTs is the default for new, mobile and API-driven applications.
  • ·Brokers, the SAML bearer grant (RFC 7522) and token exchange (RFC 8693) let the two coexist.
Ready to decode a token?
Use the free JWT decoder — paste any token for instant results, entirely in your browser.
Open JWT Decoder