Blog · Guides

Inside a SAML assertion: the fields that decide whether login works

What a SAML assertion contains, how it travels inside a SAMLResponse, what each element means, the validation checks that matter, and the errors that come from getting them wrong.

Casdoor Team · November 1, 2026 · 3 min read

This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 1, 2026. Spotted a mistake? Tell us.

A SAML login succeeds or fails on the contents of one XML document: the assertion. Most integration bugs are not protocol bugs — they are one field with the wrong value, or a signature validated over the wrong element.

This article breaks down what is inside a SAML assertion and what the service provider must check.

Where the assertion lives

The identity provider sends a SAMLResponse: a base64-encoded XML document posted to the service provider's ACS URL. Inside it is one or more assertions. If the response is signed, the signature covers the response; the assertion inside can also carry its own signature.

When debugging, the first step is always the same: capture the SAMLResponse, base64-decode it, and read it. Browsers' developer tools show the form post; from there it is plain XML.

The elements

Element What it says Why it matters
Issuer Which identity provider issued the assertion The SP must accept only its configured IdP
Subject → NameID Who the assertion is about This is usually the user identifier
Conditions NotBefore, NotOnOrAfter, AudienceRestriction Time window and intended audience
AuthnStatement When and how the user authenticated, plus SessionIndex Session tracking and single logout
AttributeStatement Email, name, groups, roles The profile data the SP maps to its user
Signature XML digital signature Proves the IdP produced it

A minimal authentication assertion reads, in effect: "I, the IdP, assert that subject X authenticated at time T using method M, this is valid until E, and it is meant for application A."

The checks that matter

A service provider that skips any of these is either broken or insecure:

1. Signature. Validate the XML signature using the IdP's certificate. Validate over the exact element you read — this is where XML signature wrapping attacks live. Use a parser that rejects duplicate IDs.

2. Issuer. Must match the configured IdP entity ID. Otherwise any IdP the attacker controls can issue assertions.

3. Audience. AudienceRestriction must name your entity ID. Casdoor, for example, compares it against the configured SP entity ID and rejects mismatches with an audience error.

4. Recipient and destination. The response's Destination and the subject confirmation's Recipient must match your ACS URL.

5. Time window. The current time must be within NotBefore and NotOnOrAfter, with a small clock-skew allowance. Casdoor rejects expired assertions with an explicit error.

6. InResponseTo. For SP-initiated logins, the value must match the ID of the AuthnRequest you sent in the same browser session. This prevents an attacker from replaying a response from another login.

7. Replay cache. Remember used assertion IDs until they expire; reject duplicates. Casdoor keeps them until NotOnOrAfter (or one hour), in memory or in Redis when configured.

The error messages, decoded

Error Usually means
"Invalid signature" Wrong certificate at the SP, or the SP rejects a signed assertion it does not expect
"Audience restriction mismatch" Entity ID at the SP and the IdP's Redirect URLs differ — often a trailing slash
"Response not for this recipient" ACS URL at the IdP does not match the SP
"Assertion expired" Clock skew, or a cached response replayed later
"Already been used" Replay cache hit — a retry or a genuine replay
"InResponseTo mismatch" The login did not start at the SP, or the session was lost between request and response

Attributes and NameID

Two practical rules:

  • Map attributes explicitly. Do not assume every IdP sends email; map NameID or an attribute to your user key and document the choice.
  • Treat NameID as immutable only if it is. Some IdPs use the email as NameID, which changes when people change names. Store the value but do not make it your primary key.

Signing the response vs the assertion

SAML allows signing the response, the assertion, or both. Some service providers require a signed assertion specifically; others reject responses where the assertion is signed in addition to the response. Casdoor signs the response by default and adds an assertion signature only when the application setting is enabled — that setting exists because of exactly this compatibility problem.

If a customer reports "invalid signature" on a configuration that should work, check which element their SP expects signed before changing anything else.

Related reading: what SAML is, set up Casdoor as a SAML IdP and SP-initiated vs IdP-initiated SSO.