All Docs
FeaturesCSI Teachable Replacement AppUpdated March 15, 2026

Fixing SAML HTTP-Redirect Binding Compliance for Okta, Azure AD & ADFS

Fixing SAML HTTP-Redirect Binding Compliance for Okta, Azure AD & ADFS

Release: v1.0.52
Area: SSO / SAML Authentication
Severity: High — affected SSO login for tenants using strict IdPs


Background

Our platform supports SAML 2.0 Single Sign-On (SSO), allowing organizations to authenticate learners through their existing Identity Provider (IdP) rather than managing separate credentials. When a user initiates a SAML SSO login, our platform constructs an AuthnRequest XML document and redirects the user's browser to the IdP using the HTTP-Redirect binding.

What Was Wrong

The SAML 2.0 Bindings specification, Section 3.4.4 defines a precise encoding pipeline for the HTTP-Redirect binding:

  1. Serialize the AuthnRequest to XML
  2. DEFLATE-compress the XML (raw deflate, RFC 1951 — no zlib header)
  3. Base64-encode the compressed bytes
  4. URL-encode the result and append it to the IdP redirect URL

The implementation in src/lib/auth-sso-saml.ts (buildSamlRedirect, lines 78–91) was skipping step 2 — the DEFLATE compression — and encoding the raw XML bytes directly:

// Non-compliant implementation
const encoded = Buffer.from(authnRequestXml).toString('base64');

Many IdPs tolerate this deviation, but Okta, Azure AD, and ADFS enforce strict spec compliance and respond with a 400 Bad Request or a generic error page when they receive an uncompressed payload. This effectively blocked SAML SSO logins for any tenant whose IdP applied strict validation.

The Fix

The fix adds raw DEFLATE compression using Node.js's built-in zlib module before Base64 encoding the AuthnRequest:

import * as zlib from 'zlib';

// Spec-compliant implementation
const deflated = zlib.deflateRawSync(Buffer.from(authnRequestXml, 'utf8'));
const encoded = deflated.toString('base64');

Using deflateRawSync (rather than deflateSync) is important — raw deflate omits the zlib header and checksum bytes, which is exactly what the SAML HTTP-Redirect binding requires per RFC 1951.

Who Was Affected

IdPBehavior before fixBehavior after fix
Okta400 error on AuthnRequestSSO login works correctly
Azure AD / Entra IDAuthentication error pageSSO login works correctly
ADFS400 / generic failureSSO login works correctly
Other permissive IdPsSSO login worked (tolerated non-compliant encoding)SSO login continues to work

Diagnosing the Issue in Your Environment

If your organization was experiencing failed SAML SSO logins, the typical symptoms were:

  • Users were redirected to the IdP but immediately saw a 400 Bad Request or a generic error — before the IdP login form appeared.
  • No authentication event was logged in the IdP's audit trail (because the request was rejected at the binding layer, not the authentication layer).
  • SP-initiated SSO failed; IdP-initiated SSO (if configured) may have continued to work.

Action Required

No configuration changes are required on your end. The fix is applied server-side. If your tenant's SAML SSO was broken due to this issue, it will resume working automatically after upgrading to v1.0.52.

If you are setting up SAML SSO for the first time, follow the standard SSO configuration guide — the HTTP-Redirect binding is now fully spec-compliant out of the box.

Further Reading