SAML verstehen
Die Nachrichten, Signaturen und Prüfungen, die eine Anwendung durchführen muss, mit dem, was ID-Kit bei jedem Schritt tut.
SAML 2.0 (2005) ist ein OASIS-Standard für Identitätsföderation. Der Identitätsprovider (IdP) authentifiziert den Benutzer und stellt Assertions aus; der Service Provider (SP) verarbeitet sie an der Adresse namens ACS (Assertion Consumer Service). Jede Partei hat einen eindeutigen Bezeichner, die Entity ID, oft eine URL, die nicht erreichbar sein muss.
Ein XML-Dokument beschreibt jede Partei: ihre Entity ID, ihre Endpunkte, ihre Zertifikate. Sie zu importieren vermeidet die meisten Kopierfehler.
<md:EntityDescriptor entityID="https://idp.example/idp">
<md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">...<ds:X509Certificate>MIIC...</ds:X509Certificate>...</md:KeyDescriptor>
<md:SingleSignOnService Binding="...HTTP-Redirect" Location="https://idp.example/sso"/>
<md:SingleSignOnService Binding="...HTTP-POST" Location="https://idp.example/sso"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>
Der Benutzer öffnet die Anwendung, die einen AuthnRequest sendet. Die Antwort nennt die ID dieser Anfrage in InResponseTo: Die Anwendung kann prüfen, dass sie diese Antwort tatsächlich angefordert hat. Der Parameter RelayState erlaubt dem Benutzer, zur ursprünglich angeforderten Seite zurückzukehren.
Der Benutzer klickt im Portal seiner Organisation auf eine Kachel. Es ging keine Anfrage voraus: Die Antwort kommt „unaufgefordert“ und hat kein InResponseTo. Das ist bequem, aber weniger sicher (die Anwendung kann die Antwort keiner Anfrage zuordnen), und manche Anwendungen lehnen es ab.
Der Browser trägt die Nachrichten. Ein Binding beschreibt, wie:
| Binding | Principe | Usage |
|---|---|---|
| HTTP-Redirect | Das XML wird komprimiert (Deflate), Base64-kodiert und dann in die URL gesetzt (?SAMLRequest=…). Ist die Anfrage signiert, liegt die Signatur außerhalb des XML, in den Parametern SigAlg und Signature, und deckt die Zeichenkette SAMLRequest=…&RelayState=…&SigAlg=… so ab, wie sie gesendet wurde. | Anfragen (Größe durch die URL begrenzt) |
| HTTP-POST | Das XML wird Base64-kodiert in ein HTML-Formular gesetzt, das der Browser automatisch absendet. Die Signatur steckt im XML. | Antworten (fast immer) und Anfragen |
| HTTP-Artifact | Es wird nur eine Referenz gesendet; der Inhalt wird direkt von Server zu Server abgeholt. | Rare |
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="_a1b2c3" <!-- identifiant unique, repris dans la réponse -->
IssueInstant="2026-11-01T10:00:00Z"
Destination="https://idp.example/sso" <!-- à qui la demande est adressée -->
AssertionConsumerServiceURL="https://app.example/saml/acs" <!-- où renvoyer la réponse -->
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://app.example/metadata</saml:Issuer> <!-- l'Entity ID de l'application -->
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"/>
</samlp:AuthnRequest>
Nützliche Optionen: ForceAuthn (neu authentifizieren, auch wenn eine Sitzung besteht), IsPassive (nichts anzeigen, fehlschlagen, wenn der Benutzer nicht bereits angemeldet ist), NameIDPolicy (gewünschtes Bezeichnerformat), RequestedAuthnContext (geforderte Authentifizierungsstufe, zum Beispiel Zwei-Faktor).
<samlp:Response Destination="https://app.example/saml/acs" InResponseTo="_a1b2c3" ...>
<saml:Issuer>https://idp.example/idp</saml:Issuer>
<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
<saml:Assertion ID="_z9y8" IssueInstant="..." Version="2.0">
<saml:Issuer>https://idp.example/idp</saml:Issuer>
<ds:Signature>...</ds:Signature> <!-- le sceau -->
<saml:Subject>
<saml:NameID Format="...emailAddress">jane@example.com</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="_a1b2c3" Recipient="https://app.example/saml/acs" NotOnOrAfter="..."/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="..." NotOnOrAfter="...">
<saml:AudienceRestriction><saml:Audience>https://app.example/metadata</saml:Audience></saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="..." SessionIndex="_z9y8">...</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="groups"><saml:AttributeValue>admins</saml:AttributeValue></saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
Zwei Ebenen: die Response (Umschlag: Status, Ziel) und die Assertion (der Inhalt, auf den es ankommt). Der Status sagt, ob die Identifizierung gelungen ist; bei Misserfolg gibt es keine Assertion.
Issuer), und von der Berechnung ausgeschlossen.SignedInfo-Blocks, der diesen Digest enthält.ID-Kit kann die Assertion, die Antwort oder beides signieren, mit SHA-1/256/384/512, und fehlerhafte Fälle simulieren, um zu prüfen, dass Ihre Anwendung sie ablehnt.
Der Reihe nach prüft eine seriöse Anwendung:
Recipient = ACS-URL, nicht abgelaufen.Der Test-SP von ID-Kit führt all diese Prüfungen aus und zeigt sie einzeln, mit der anzuwendenden Lösung.
email, groups oder ein langer Name im URI-Stil bei Microsoft). Der IdP entscheidet, welche Attribute gesendet werden, und die Anwendung muss sie zuordnen.SessionIndex zugeordnet. In der Praxis ist es der am schlechtesten und am uneinheitlichsten umgesetzte Teil des Standards.InResponseTo, Gedächtnis der verbrauchten IDs.Um diese Verhaltensweisen in der Praxis zu testen, nutzen Sie die Fehlersimulationen des ID-Kit-IdP: Ihre Anwendung muss jede davon ablehnen.
Möchten Sie es live sehen? ID-Kit übernimmt die Rolle, die Ihnen fehlt, und zeigt Ihnen jeden Schritt.