Zum Inhalt springen

SAML-SSO-Ablaufdiagramm: SP-initiierter und IdP-initiierter Login

So funktioniert Single Sign-On mit SAML 2.0: SP- und IdP-initiierte Abläufe, der Inhalt einer SAML-Response, was deine App prüfen muss und wo es bricht.

· Gründer & Entwickler

Veröffentlicht am

Sequenzdiagramm mit Benutzer, Browser, Service Provider und Identity Provider. Die App leitet mit einem AuthnRequest zum IdP um; ein optionales Fragment zeigt Login und MFA; der IdP liefert ein Formular, das die SAMLResponse an die ACS-URL postet; die App prüft sie und setzt ein Cookie.

Der erste große Kunde, der einen Vertrag unterschreibt, wird Single Sign-On mit seinem Identity Provider verlangen, und sehr oft heißt das SAML 2.0. Der Standard stammt von 2005, transportiert XML über Browser-Redirects und Formular-Posts, und seine Fehlermeldungen reichen von vage bis stumm. Die meisten SAML-Bugs, auch ernste Sicherheitslücken, entstehen, weil nicht klar ist, welche Nachricht genau wohin geht und was der Service Provider prüfen muss.

Dieser Beitrag geht den SP-initiierten Ablauf Nachricht für Nachricht mit einem Sequenzdiagramm durch, dann die IdP-initiierte Variante und ihre Risiken, den Aufbau einer SAML-Response, die Validierungs-Checkliste für deine App, Metadaten und Zertifikatsrotation und wie SAML im Vergleich zu OpenID Connect abschneidet.

Die drei Beteiligten

Beteiligter In SAML-Begriffen Beispiele
Der Browser des Benutzers User Agent Jeder Browser
Deine Anwendung Service Provider (SP) Deine SaaS-App
Das Login-System des Kunden Identity Provider (IdP) Microsoft Entra ID, Okta, Google Workspace, AD FS

Im verbreiteten Web-Browser-SSO-Profil sprechen SP und IdP nie direkt miteinander. Jede Nachricht läuft über den Browser, als Redirect oder als automatisch abgeschicktes Formular. Was sie teilen, ist Konfiguration, einmal als Metadaten ausgetauscht: die Entity-ID jeder Seite, die Anmelde-URL des IdP, die Assertion-Consumer-Service-URL (ACS-URL) des SP und das Signaturzertifikat des IdP.

Der SP-initiierte Ablauf Schritt für Schritt

Der Benutzer beginnt bei deiner App:

  1. Der Benutzer öffnet https://app.example.com/dashboard ohne Session.
  2. Deine App erzeugt einen AuthnRequest mit einer eindeutigen ID, ihrer Entity-ID und ihrer ACS-URL, speichert die ID im ausstehenden Login-Zustand und leitet den Browser zum IdP weiter. Mit dem HTTP-Redirect-Binding reist der Request im Query-String als SAMLRequest (deflate-komprimiert, base64-kodiert), neben einem RelayState-Wert, der sich merkt, wohin der Benutzer wollte.
  3. Der IdP authentifiziert den Benutzer: Passwort und MFA oder eine bestehende IdP-Session, dann sieht der Benutzer gar nichts.
  4. Der IdP liefert eine HTML-Seite mit einem Formular, das eine signierte SAMLResponse und denselben RelayState an deine ACS-URL postet. Das ist das HTTP-POST-Binding, und ein kleines Skript schickt das Formular automatisch ab.
  5. Deine App validiert die Response, legt ihr eigenes Session-Cookie an und leitet den Benutzer auf die in RelayState gespeicherte Seite weiter.

Ab dann entscheidet die eigene Session deiner App, wer der Benutzer ist. SAML kommt erst wieder ins Spiel, wenn diese Session abläuft.

Die Binding-Spezifikation begrenzt RelayState auf 80 Byte, also speichere die echte Rücksprung-URL serverseitig und schick einen kurzen Schlüssel.

Was eine SAML-Response enthält

Auf die Teile gekürzt, die deine App liest, sieht eine Response so aus:

<samlp:Response ID="_r81c" InResponseTo="_req42" Destination="https://app.example.com/saml/acs">
  <saml:Assertion ID="_a77e">
    <saml:Issuer>https://idp.customer.com/entity</saml:Issuer>
    <ds:Signature>…</ds:Signature>
    <saml:Subject>
      <saml:NameID>ana@customer.com</saml:NameID>
      <saml:SubjectConfirmationData InResponseTo="_req42"
        Recipient="https://app.example.com/saml/acs" NotOnOrAfter="2026-11-02T09:05:00Z"/>
    </saml:Subject>
    <saml:Conditions NotBefore="2026-11-02T08:59:30Z" NotOnOrAfter="2026-11-02T09:05:00Z">
      <saml:AudienceRestriction><saml:Audience>https://app.example.com</saml:Audience></saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AttributeStatement>…email, name, groups…</saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>

Die Assertion ist die signierte Aussage: wer der Benutzer ist (NameID), wer das sagt (Issuer), für wen (Audience), wie lange und als Antwort auf welchen Request (InResponseTo).

Die Validierungs-Checkliste

An deinem ACS-Endpunkt entscheidet sich, ob SAML sicher ist. Er muss:

  1. Die Signatur mit dem Zertifikat aus den Metadaten des IdP prüfen, nie mit einem Zertifikat, das in der Nachricht selbst steckt.
  2. Nur lesen, was die Signatur abdeckt. XML-Signature-Wrapping-Angriffe fügen eine zweite, unsignierte Assertion ein und hoffen, dass der Code ein Element verifiziert und ein anderes liest. Forscher fanden diese Lücke 2012 in 11 von 14 großen SAML-Frameworks, und sie kehrt immer wieder: ruby-saml behob 2024 eine Signaturumgehung mit CVSS 10.0 (CVE-2024-45409) und 2025 zwei Umgehungen durch Parser-Differenzen (CVE-2025-25291 und CVE-2025-25292).
  3. Issuer prüfen gegen die Entity-ID des IdP für diesen Kunden.
  4. Audience prüfen gegen deine eigene Entity-ID.
  5. Destination und Recipient prüfen gegen deine ACS-URL.
  6. NotBefore und NotOnOrAfter prüfen, mit ein bis zwei Minuten Toleranz für Uhrenabweichungen.
  7. InResponseTo abgleichen mit einer AuthnRequest-ID, die du für diesen Browser ausgestellt und noch nicht verwendet hast.
  8. Replays abweisen, indem du dir Assertion-IDs bis zu ihrem Ablauf merkst.
  9. RelayState als nicht vertrauenswürdig behandeln. Leite nur auf relative Pfade oder eine Allowlist um, sonst hast du einen Open Redirect.

Die Lehre aus zehn Jahren SAML-Schwachstellen: Nutze eine gepflegte Bibliothek, pinne sie, patche sie schnell und schreib nie deine eigene XML-Signaturprüfung.

IdP-initiiertes SSO und warum es riskanter ist

Im IdP-initiierten Ablauf beginnt der Benutzer beim IdP, meist mit einem Klick auf die Kachel deiner App in einem Dashboard wie dem Okta- oder Microsoft-My-Apps-Portal. Der IdP postet eine unaufgeforderte Response an deine ACS-URL. Es gab keinen AuthnRequest, also gibt es kein InResponseTo zum Abgleichen.

SP-initiiert IdP-initiiert
Startet bei Deiner App Dem Portal des IdP
AuthnRequest Ja Nein
Prüfung von InResponseTo Ja Nicht möglich
Schutz vor Login-CSRF Eingebaut Braucht zusätzliche Sorgfalt
Deep Links Über RelayState Landet meist auf einer Standardseite

Ohne InResponseTo kann ein Angreifer, der eine gültige Response erbeutet oder den Browser eines Opfers dazu bringt, eine zu posten, das Opfer in das Konto des Angreifers einloggen oder eine gestohlene Response innerhalb ihres Gültigkeitsfensters wieder einspielen. Wenn Kunden Dashboard-Kacheln brauchen, ist das sicherere Muster eine Kachel, die die Login-URL deiner App öffnet, die dann einen normalen SP-initiierten Ablauf startet. Wenn du unaufgeforderte Responses akzeptieren musst, halte die Gültigkeit kurz, erzwinge einmalige Assertion-IDs und erlaube es pro Kunde statt global.

Metadaten, Zertifikate und Multi-Tenant-Setups

Der IdP jedes Kunden ist eine eigene Vertrauensbeziehung. Speichere pro Tenant: die Entity-ID des IdP, die Anmelde-URL, die Signaturzertifikate und das Attribut-Mapping. Das Multi-Tenant-SaaS-Architekturdiagramm zeigt, wo diese Tenant-Konfiguration üblicherweise liegt.

Signaturzertifikate laufen ab, und ein abgelaufenes oder rotiertes Zertifikat ist die häufigste Ursache dafür, dass sich ein ganzer Kunde plötzlich nicht mehr anmelden kann. Akzeptiere während eines Wechsels zwei Zertifikate pro IdP, lies die Metadaten-URL des IdP regelmäßig, falls er eine veröffentlicht, und alarmiere Wochen vor dem Ablauf.

SAML authentifiziert; es hält deine Benutzerliste nicht synchron. Konten beim ersten Login anzulegen ist einfach, aber Zugriff zu entziehen, wenn jemand geht, braucht Provisioning, meist SCIM 2.0 (RFC 7644). Ohne das behält ein deaktivierter Mitarbeiter jede Session, die deine App bereits ausgestellt hat.

SAML oder OpenID Connect?

SAML 2.0 OpenID Connect
Format XML-Assertions mit XML-Signaturen JSON, mit JWT-ID-Tokens
Transport Browser-Redirects und Formular-Posts Redirects plus ein Token-Request im Backchannel
Mobile Apps und SPAs Umständlich Dafür entworfen
Typischer Einsatz Enterprise-SSO in SaaS-Apps Consumer-Login, APIs, modernes Enterprise-SSO

Neue Apps können mit OpenID Connect starten, aber Enterprise-Kunden werden weiter nach SAML fragen, deshalb unterstützen die meisten B2B-Produkte beides. Das OAuth-2.0-Ablaufdiagramm behandelt das Protokoll, auf dem OpenID Connect aufbaut.

Das SAML-SSO-Diagramm

Sequenzdiagramm mit Benutzer, Browser, Service Provider und Identity Provider. Die App leitet mit einem AuthnRequest zum IdP um; ein optionales Fragment zeigt Login und MFA; der IdP liefert ein Formular, das die SAMLResponse an die ACS-URL postet; die App prüft sie und setzt ein Cookie.

6 Komponenten · 11 Verbindungen

In Archboard öffnen
Diagramminhalt
  • User
  • Browser
  • Service provider (your app)
  • Identity provider
  • no IdP session yet
  • 1. Open the app
  • 2. GET /dashboard (no session)
  • 3. 302 to IdP: SAMLRequest + RelayState
  • 4. GET /sso?SAMLRequest=…&RelayState=… (HTTP-Redirect)
  • 5. Login page
  • 6. Password + MFA
  • 7. HTML form: signed SAMLResponse + RelayState
  • 8. POST /saml/acs (HTTP-POST, auto-submit)
  • 9. 302 /dashboard + session cookie
  • 10. GET /dashboard (cookie)
  • 11. 200 OK
SP-initiiertes SAML-Single-Sign-On. Die App leitet den Browser mit einem AuthnRequest zum Identity Provider weiter, der IdP meldet den Benutzer an und postet eine signierte Response an die ACS-URL der App, und die App validiert sie, bevor sie eine eigene Session anlegt.

So liest du es:

  • Vier Beteiligte. Der Benutzer, der Browser, deine App als Service Provider und der Identity Provider. Die Zeit läuft nach unten.
  • Der Redirect trägt AuthnRequest und RelayState von deiner App über den Browser zum IdP.
  • Das optionale Fragment ist der Login-Schritt. Mit einer bestehenden IdP-Session entfällt er, und der Benutzer sieht nur einen kurzen Redirect.
  • Der Formular-Post liefert die signierte SAMLResponse an die ACS-URL. Deine App validiert sie und setzt ihr eigenes Session-Cookie.
  • Der Markdown-Block listet die Prüfungen, die der ACS-Endpunkt durchführen muss.

SSO-Abläufe zeichnen, die beim Debuggen helfen

  • Zeichne den Browser als eigenen Beteiligten. SAML ist ein Front-Channel-Protokoll; wer den Browser versteckt, versteckt, wo Nachrichten abgefangen oder wieder eingespielt werden können.
  • Schreib das Binding an jeden Pfeil: Redirect oder POST und den Parameternamen. Die meisten Konfigurationsfehler sind eine falsche URL oder ein falsches Binding.
  • Schreib IDs an die Nachrichten. Zu zeigen, dass InResponseTo die Request-ID wiederholt, erklärt, warum es geprüft wird.
  • Zeichne den IdP-initiierten Ablauf separat, mit vermerktem Risiko, statt als Zweig des Hauptdiagramms.

Das Sequenzdiagramm-Beispiel behandelt Beteiligte, Fragmente und Beschriftungen ausführlicher, und das Zero-Trust-Architekturdiagramm zeigt, wo der Identity Provider in einem umfassenderen Zugriffsmodell sitzt.

In Archboard nachbauen

  1. Melde dich mit Google oder GitHub an und leg ein Diagramm an.
  2. Füge einen Akteur aus dem Sequenz-Pack für den Benutzer hinzu, dann drei Lebenslinie-Nodes: Browser, Service provider und Identity provider.
  3. Zeichne die Nachrichten von oben nach unten als Kanten zwischen den Lebenslinien: den ersten Request, den Redirect mit SAMLRequest und RelayState, den Request an den IdP, das Formular mit SAMLResponse, den POST an die ACS-URL und den letzten Redirect mit dem Session-Cookie.
  4. Füge ein Kombiniertes Fragment aus dem Sequenz-Pack mit dem Operator opt um den Schritt mit Login und MFA hinzu.
  5. Füge einen Markdown-Block aus dem Basis-Pack mit der Validierungs-Checkliste hinzu.

Das Beispiel nutzt 6 Diagramm-Nodes und bleibt damit im Free-Plan.

FAQ

Was ist der Unterschied zwischen SP-initiiertem und IdP-initiiertem SSO? Der SP-initiierte Login beginnt bei deiner App, die einen AuthnRequest an den IdP schickt. Der IdP-initiierte Login beginnt im Portal des IdP, das eine unaufgeforderte Response an deine App postet. Beim zweiten gibt es keinen Request zum Abgleichen, was den Schutz vor Replays und Login-CSRF schwächt.

Was ist eine ACS-URL? Die Assertion-Consumer-Service-URL ist der Endpunkt in deiner App, der die SAML-Response per HTTP POST empfängt. Sie wird im IdP konfiguriert und muss zu den Werten Destination und Recipient in jeder Response passen.

Wofür wird RelayState verwendet? Es trägt den Ort, den der Benutzer erreichen wollte, damit deine App ihn nach dem Login dorthin schicken kann. Es ist auf 80 Byte begrenzt und eine nicht vertrauenswürdige Eingabe, also nutze es als Schlüssel zu serverseitigem Zustand oder prüfe es gegen eine Allowlist.

Ist SAML veraltet? Es ist älter als OpenID Connect und schwerer sicher zu implementieren, bleibt aber der Standard, den viele Enterprise-Identity-Provider und Käufer erwarten. Die meisten B2B-Produkte unterstützen beides.

Entfernt SAML Benutzer, wenn sie das Unternehmen verlassen? Nein. SAML authentifiziert nur beim Login. Deprovisioning braucht SCIM oder eine andere Provisioning-Integration, dazu vernünftige Session-Laufzeiten in deiner App.

Kostenlos starten — ein Seat, keine Kreditkarte.

Ähnliche Beiträge

← Zurück zum Blog

In einer Minute ein Canvas öffnen

Melden Sie sich mit Google oder GitHub an. Kostenlos für einen Sitzplatz. Upgraden Sie, wenn das Team dazukommt.