Understanding SAML 2.0

A comprehensive guide to Security Assertion Markup Language – the enterprise standard for Single Sign-On (SSO) authentication.

Authentication SSO XML-Based Enterprise
By Anish Nath
What is SAML?

SAML (Security Assertion Markup Language) is an XML-based open standard for exchanging authentication and authorization data between parties. Developed by OASIS, SAML 2.0 (released in 2005) is the current version widely used in enterprise environments.

Key Concept

SAML enables Single Sign-On (SSO) – users authenticate once with an Identity Provider and can access multiple Service Providers without re-entering credentials. This is especially valuable in enterprise environments with many applications.

Benefits
  • Single Sign-On across applications
  • Centralized identity management
  • Reduced password fatigue
  • Improved security posture
  • Cross-domain authentication
Common Use Cases
  • Enterprise SSO (Okta, Azure AD, OneLogin)
  • Cloud application access
  • Federated identity across organizations
  • Government and healthcare systems
  • B2B partner integrations
Key Components
Identity Provider (IdP)

The authority that authenticates users and issues SAML assertions. Examples: Okta, Azure AD, OneLogin, ADFS, Ping Identity.

Service Provider (SP)

The application that relies on the IdP for authentication. It consumes SAML assertions to grant access. Examples: Salesforce, Slack, AWS.

Principal (User)

The end user who wants to access a service. They authenticate with the IdP and are redirected to the SP with a SAML assertion.

SAML Metadata

Both IdP and SP publish metadata XML files containing:

  • Entity ID: Unique identifier for the IdP or SP
  • Endpoints: URLs for SSO, SLO, and Artifact Resolution services
  • Certificates: X.509 certificates for signing and encryption
  • Supported bindings: HTTP-POST, HTTP-Redirect, etc.
  • Name ID formats: Email, persistent, transient identifiers
SAML Authentication Flow

There are two main flows: SP-Initiated (most common) and IdP-Initiated.

SP-Initiated SSO Flow
1
User Accesses SP

User tries to access a protected resource on the Service Provider (e.g., app.example.com).

2
SP Generates AuthnRequest

SP creates a SAML AuthnRequest and redirects user to IdP with the request (via HTTP-Redirect or HTTP-POST binding).

3
User Authenticates at IdP

IdP presents login page. User enters credentials (or uses existing session if already logged in).

4
IdP Generates Response

IdP creates a SAML Response containing an Assertion with user attributes and signs it with its private key.

5
Response Sent to SP

User's browser POSTs the SAML Response to the SP's Assertion Consumer Service (ACS) URL.

6
SP Validates & Grants Access

SP verifies the signature, checks conditions (time validity, audience), extracts user info, and creates a local session.

IdP-Initiated Flow

In IdP-initiated SSO, the user starts at the IdP portal and clicks on an application. The IdP sends an unsolicited SAML Response to the SP. This flow is less secure as there's no AuthnRequest to tie the response to, making replay attacks easier.

SAML Bindings

Bindings define how SAML messages are transported between IdP and SP.

HTTP-POST Binding
Most Common Large Messages

Messages are Base64-encoded and sent in HTML form fields. Supports large payloads (signed responses with assertions).

<form method="POST" action="https://sp.example.com/acs">
  <input type="hidden" name="SAMLResponse" value="PHNhbWxwOl..."/>
  <input type="hidden" name="RelayState" value="..."/>
</form>
HTTP-Redirect Binding
URL Length Limit Requests Only

Messages are DEFLATE-compressed, Base64-encoded, and URL-encoded in query parameters. Used for AuthnRequests.

https://idp.example.com/sso?
  SAMLRequest=fZJNT8Mw...&
  RelayState=...&
  SigAlg=...&
  Signature=...
SOAP Binding
Back-channel

Direct server-to-server communication using SOAP. Used for Artifact Resolution and Attribute Queries. Not browser-based.

Artifact Binding
Reference-based

Instead of sending the full message, a small artifact (reference) is passed. SP resolves the artifact via back-channel to retrieve the actual message.

HTTP-Redirect Encoding Process
  1. Start: Raw XML message
  2. Deflate: Compress using DEFLATE algorithm (RFC 1951)
  3. Base64: Encode the compressed bytes
  4. URL Encode: Make safe for URL query string
  5. Sign (optional): Add signature as separate query parameter
SAML Message Types
Message Sender Purpose
AuthnRequest SP → IdP Request authentication of a user
Response IdP → SP Contains authentication result and user assertions
LogoutRequest SP/IdP Request termination of user session (Single Logout)
LogoutResponse SP/IdP Acknowledge logout request
AttributeQuery SP → IdP Request additional user attributes
ArtifactResolve SP → IdP Retrieve full message from artifact reference
Example AuthnRequest
<samlp:AuthnRequest
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    ID="_abc123"
    Version="2.0"
    IssueInstant="2025-01-28T10:00:00Z"
    Destination="https://idp.example.com/sso"
    AssertionConsumerServiceURL="https://sp.example.com/acs"
    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
    <saml:Issuer>https://sp.example.com</saml:Issuer>
    <samlp:NameIDPolicy
        Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
        AllowCreate="true"/>
</samlp:AuthnRequest>
SAML Assertions

An Assertion is the core of SAML – it contains statements about the user made by the IdP.

Authentication Statement

Confirms the user was authenticated at a specific time using a specific method (password, MFA, certificate, etc.).

Attribute Statement

Contains user attributes like email, name, groups, roles. These are used by SP for authorization decisions.

Authorization Decision

States whether the user is permitted/denied access to a specific resource. Rarely used in practice.

Assertion Structure
<saml:Assertion ID="_xyz789" IssueInstant="2025-01-28T10:00:30Z">
  <saml:Issuer>https://idp.example.com</saml:Issuer>
  <ds:Signature>...</ds:Signature>

  <saml:Subject>
    <saml:NameID Format="emailAddress">[email protected]</saml:NameID>
    <saml:SubjectConfirmation Method="bearer">
      <saml:SubjectConfirmationData
        NotOnOrAfter="2025-01-28T10:05:30Z"
        Recipient="https://sp.example.com/acs"/>
    </saml:SubjectConfirmation>
  </saml:Subject>

  <saml:Conditions NotBefore="..." NotOnOrAfter="...">
    <saml:AudienceRestriction>
      <saml:Audience>https://sp.example.com</saml:Audience>
    </saml:AudienceRestriction>
  </saml:Conditions>

  <saml:AuthnStatement AuthnInstant="...">
    <saml:AuthnContext>
      <saml:AuthnContextClassRef>PasswordProtectedTransport</saml:AuthnContextClassRef>
    </saml:AuthnContext>
  </saml:AuthnStatement>

  <saml:AttributeStatement>
    <saml:Attribute Name="firstName">
      <saml:AttributeValue>John</saml:AttributeValue>
    </saml:Attribute>
    <saml:Attribute Name="groups">
      <saml:AttributeValue>admin</saml:AttributeValue>
      <saml:AttributeValue>users</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>
Name ID Formats
emailAddressUser's email address
persistentOpaque, stable identifier across sessions
transientTemporary identifier, changes per session
unspecifiedAny format, IdP decides
XML Digital Signatures

SAML uses XML Digital Signatures (XMLDSig) to ensure message integrity and authenticity.

What Gets Signed?
  • Response: Entire SAML Response element
  • Assertion: Just the Assertion element
  • Both: Some IdPs sign both
  • AuthnRequest: Can be signed for non-repudiation
Signature Process
  1. Canonicalize XML (C14N)
  2. Compute digest of canonicalized content
  3. Create SignedInfo with digest
  4. Sign SignedInfo with private key
  5. Embed signature in document
Signature Structure
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="...xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="...rsa-sha256"/>
    <ds:Reference URI="#_assertionId">
      <ds:Transforms>
        <ds:Transform Algorithm="...enveloped-signature"/>
        <ds:Transform Algorithm="...xml-exc-c14n#"/>
      </ds:Transforms>
      <ds:DigestMethod Algorithm="...sha256"/>
      <ds:DigestValue>base64-encoded-digest</ds:DigestValue>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>base64-encoded-signature</ds:SignatureValue>
  <ds:KeyInfo>
    <ds:X509Data>
      <ds:X509Certificate>base64-encoded-cert</ds:X509Certificate>
    </ds:X509Data>
  </ds:KeyInfo>
</ds:Signature>
Signature Validation Steps
  1. Extract the certificate from KeyInfo or use pre-configured IdP certificate
  2. Verify the certificate is trusted (chain validation)
  3. Canonicalize the signed element using specified algorithm
  4. Compute digest and compare with DigestValue
  5. Verify SignatureValue using the public key
Security Best Practices
Always Validate
  • Verify XML signature using IdP certificate
  • Check NotBefore and NotOnOrAfter conditions
  • Validate Audience matches your SP Entity ID
  • Verify Destination matches your ACS URL
  • Check InResponseTo matches your AuthnRequest ID
Common Vulnerabilities
  • XML Signature Wrapping: Moving signed content
  • XXE: XML External Entity injection
  • Replay Attacks: Reusing valid assertions
  • Comment Injection: Bypassing canonicalization
  • Missing Validation: Skipping security checks
Time-Based Security
NotBefore Assertion is not valid before this time
NotOnOrAfter Assertion expires at this time (typically 5 minutes)
SessionNotOnOrAfter When to force re-authentication

Clock Skew: Allow 1-2 minutes tolerance for server time differences.

SAML vs OAuth 2.0 vs OpenID Connect
Aspect SAML 2.0 OAuth 2.0 OpenID Connect
Purpose Authentication + Attributes Authorization Authentication (on top of OAuth)
Format XML JSON JSON + JWT
Token SAML Assertion Access Token ID Token (JWT)
Transport Browser redirects/POSTs HTTP APIs HTTP APIs
Best For Enterprise SSO, Legacy API Authorization, Mobile Modern SSO, Consumer Apps
Complexity High Medium Medium
When to Use What?
  • SAML: Enterprise environments, existing IdPs (Okta, Azure AD), legacy systems, cross-domain SSO
  • OAuth 2.0: API access, mobile apps, third-party integrations (e.g., "Login with Google to access your Drive")
  • OpenID Connect: Modern web apps, mobile apps, when you need both authentication and simple API access
Troubleshooting Common Issues
  • Ensure you're using the correct IdP certificate (not SP certificate)
  • Check if IdP certificate has been rotated/renewed
  • Verify you're checking the right element (Response vs Assertion)
  • Look for XML modifications during transport (whitespace, encoding)
  • Check canonicalization algorithm compatibility
  • Check server clocks on both IdP and SP (use NTP)
  • Configure clock skew tolerance (1-2 minutes)
  • Verify timezone settings are correct
  • Check if assertion validity period is too short
  • Verify your SP Entity ID matches exactly what IdP expects
  • Check for trailing slashes in Entity ID
  • Ensure case sensitivity matches
  • Update IdP configuration if SP Entity ID changed
  • Verify ACS URL in IdP config matches your actual endpoint
  • Check for HTTP vs HTTPS mismatch
  • Verify URL path is correct (case sensitive)
  • Ensure no load balancer is rewriting URLs
  • HTTP-Redirect: Needs URL decode → Base64 decode → Inflate
  • HTTP-POST: Just needs Base64 decode
  • Check for double-encoding issues
  • Use our SAML Decoder tool to test
SAML Tools

Use these tools to work with SAML messages:


Support This Free Tool

Every coffee helps keep the servers running. Every book sale funds the next tool I'm dreaming up. You're not just supporting a site — you're helping me build what developers actually need.

500K+ users
200+ tools
100% private
Privacy Guarantee: Private keys you enter or generate are never stored on our servers. All tools are served over HTTPS.