Co je SAML
SAML (Security Assertion Markup Language) je standard organizace OASIS; verze 2.0 z roku 2005 se používá dodnes. Popisuje, jak si dvě strany bezpečně předají informaci o přihlášeném uživateli:
- Poskytovatel identity (IdP) — ověří uživatele (heslo, druhý faktor, eObčanka) a vydá o tom podepsané prohlášení. Příklady: Microsoft Entra ID, Okta, Keycloak, Shibboleth IdP na univerzitě, Národní identitní autorita.
- Poskytovatel služby (SP) — aplikace, do které se uživatel přihlašuje. Heslo nikdy nevidí, věří podepsanému prohlášení od IdP.
- Aserce (assertion) — samotné XML prohlášení: „uživatel X se u mě v 8:15 přihlásil heslem, jeho e-mail je … a platí to pro službu Y po dobu 5 minut“.
Všechny zprávy jsou XML ve dvou jmenných prostorech: protokol
(urn:oasis:names:tc:SAML:2.0:protocol, prefix samlp) a aserce
(urn:oasis:names:tc:SAML:2.0:assertion, prefix saml). Důvěru zajišťuje
elektronický podpis XML.
Průběh přihlášení
Nejčastější scénář je přihlášení zahájené u služby (SP-initiated Web Browser SSO):
- Uživatel otevře chráněnou stránku služby a není přihlášený.
- Služba vytvoří
AuthnRequesta přesměruje prohlížeč na přihlašovací adresu IdP. - IdP uživatele ověří — případně ho pozná podle existující relace a nic nechce.
- IdP vrátí stránku se skrytým formulářem obsahujícím
SAMLResponses podepsanou asercí. Podepsaná může být i celá odpověď. - Prohlížeč formulář automaticky odešle na adresu služby (Assertion Consumer Service).
- Služba odpověď ověří, založí vlastní relaci a pošle uživatele na původní stránku (podle
RelayState).
Server služby a server IdP spolu při tom přímo nekomunikují — všechny zprávy nese prohlížeč. Služba proto musí ověřit požadované podpisy a všechny podmínky profilu. U vazby HTTP-POST musí být doručené aserce podepsané; samotný podpis obálky není podle tohoto profilu náhradou podpisu aserce.
Požadavek: AuthnRequest
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_a1b2c3d4e5f6"
Version="2.0"
IssueInstant="2026-09-29T08:15:00Z"
Destination="https://idp.example.cz/sso"
AssertionConsumerServiceURL="https://sluzba.example.cz/saml/acs"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
<saml:Issuer>https://sluzba.example.cz/saml</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
AllowCreate="true"/>
</samlp:AuthnRequest> IDmusí být jedinečné a nesmí začínat číslicí (je to typxs:ID) — proto ta podtržítka.Issuerje entityID služby, jak ho IdP zná z metadat.AssertionConsumerServiceURLaProtocolBindingříkají, kam a jak má IdP odpověď poslat.NameIDPolicyžádá o formát identifikátoru uživatele — trvalý pseudonym (persistent), jednorázový (transient) nebo e-mail.
Odpověď a aserce
<samlp:Response
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_r9f8e7d6" Version="2.0" IssueInstant="2026-09-29T08:15:04Z"
Destination="https://sluzba.example.cz/saml/acs"
InResponseTo="_a1b2c3d4e5f6">
<saml:Issuer>https://idp.example.cz</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ID="_x5y6z7" Version="2.0" IssueInstant="2026-09-29T08:15:04Z">
<saml:Issuer>https://idp.example.cz</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">…</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">a7c1e0f4b2</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="_a1b2c3d4e5f6"
Recipient="https://sluzba.example.cz/saml/acs"
NotOnOrAfter="2026-09-29T08:20:04Z"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2026-09-29T08:14:04Z" NotOnOrAfter="2026-09-29T08:20:04Z">
<saml:AudienceRestriction>
<saml:Audience>https://sluzba.example.cz/saml</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2026-09-29T08:15:02Z" SessionIndex="_s42">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" FriendlyName="eduPersonPrincipalName"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue>jana.novakova@example.cz</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="urn:oid:0.9.2342.19200300.100.1.3" FriendlyName="mail"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue>jana@example.cz</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response> Status— výsledek. KroměSuccessse vrací napříkladRequester,ResponderneboAuthnFailed.-
Subject— kdo je přihlášený (NameID). Metodabearerznamená, že aserce platí pro toho, kdo ji doručí;SubjectConfirmationDataproto omezuje, na jakou adresu (Recipient), do kdy a jako odpověď na který požadavek ji lze doručit. Conditions— časová platnost a pro jakou službu aserce platí (Audience).AuthnStatement— kdy a jak se uživatel ověřil;SessionIndexse hodí pro odhlášení.-
AttributeStatement— atributy uživatele. Ve federacích se pojmenovávají identifikátory OID a čitelné jméno je jen vFriendlyName.
Požadavky na podpis určuje použitý profil a vazba. U Web Browser SSO přes HTTP-POST
musí být aserce podepsané; podepsaná může být navíc i celá odpověď. Aserce může být také zašifrovaná
(EncryptedAssertion, podle standardu XML Encryption).
Vazby: jak zprávy cestují
| Vazba (binding) | Jak zpráva putuje | Použití |
|---|---|---|
| HTTP-Redirect | parametr SAMLRequest v URL: DEFLATE, Base64, URL kódování; podpis v parametru Signature | krátké požadavky (AuthnRequest, odhlášení) |
| HTTP-POST | skrytý formulář, který prohlížeč automaticky odešle; zpráva v Base64 | odpovědi s aserci (jsou dlouhé a podepsané uvnitř XML) |
| HTTP-Artifact | prohlížečem jde jen krátký odkaz, zprávu si SP vyzvedne přímo u IdP přes SOAP | když aserce nesmí projít prohlížečem |
| SOAP | přímé volání server–server | vyzvednutí artefaktu, dotazy na atributy |
<!-- Stránka, kterou vrátí IdP; prohlížeč formulář hned sám odešle -->
<form method="post" action="https://sluzba.example.cz/saml/acs">
<input type="hidden" name="SAMLResponse" value="PHNhbWxwOlJlc3BvbnNlIHhtbG5z…"/>
<input type="hidden" name="RelayState" value="/objednavky"/>
</form> Metadata
Než spolu IdP a služba začnou komunikovat, vymění si metadata — XML soubor,
který popisuje entitu: její entityID, adresy endpointů, podporované vazby a
certifikáty pro podpis a šifrování.
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="https://sluzba.example.cz/saml">
<md:SPSSODescriptor
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"
AuthnRequestsSigned="true" WantAssertionsSigned="true">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data><ds:X509Certificate>MIIC…</ds:X509Certificate></ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:AssertionConsumerService index="0" isDefault="true"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://sluzba.example.cz/saml/acs"/>
</md:SPSSODescriptor>
</md:EntityDescriptor> Federace jako eduID.cz publikují metadata všech členů v jednom podepsaném souboru, který si služby pravidelně stahují. Když IdP vymění certifikát a služba má stará metadata, přihlášení přestane fungovat — to je jedna z nejčastějších provozních chyb.
SAML v Česku
- Identita občana (NIA) — Národní identitní autorita zprostředkovává přihlášení
eObčankou, bankovní identitou nebo mobilním klíčem eGovernmentu. Kvalifikovaní poskytovatelé
služeb se k ní připojují přes SAML 2.0 (vazba HTTP-POST) a úroveň záruky ověření požadují
podle pravidel eIDAS. Metadata NIA jsou veřejná na adrese
https://nia.identitaobcana.cz/fpsts/FederationMetadata/2007-06/FederationMetadata.xml. - eduID.cz — akademická federace provozovaná sdružením CESNET. Univerzity v ní mají poskytovatele identity (typicky Shibboleth), knihovny, časopisy a e-learning jsou služby. Přes eduGAIN se propojuje s federacemi v zahraničí.
- Firemní SSO — většina podnikových aplikací (Salesforce, Atlassian, SAP a další) umí SAML s Microsoft Entra ID, Okta nebo Keycloak.
Ladění: jak zprávu přečíst
Zprávy v prohlížeči nejsnáz zachytíš rozšířením SAML-tracer (Firefox, Chrome), které je rovnou dekóduje. Ručně je potřeba rozlišit vazbu:
# HTTP-POST: jen Base64
echo "$SAMLResponse" | base64 --decode | xmllint --format -
# HTTP-Redirect: URL dekódování, Base64 a raw DEFLATE (bez hlavičky zlib)
python3 -c 'import sys,zlib,base64,urllib.parse as u;
print(zlib.decompress(base64.b64decode(u.unquote(sys.argv[1])), -15).decode())' "$SAMLRequest" Totéž zvládneš v prohlížeči nástroji Base64 a Deflate. Výsledek vlož do formátovače — ale podepsanou zprávu, kterou chceš dál odeslat, nikdy nepřeformátovávej: změna bílých znaků v podepsaném elementu podpis rozbije.
Bezpečnost: co musí služba ověřit
| Co SP musí zkontrolovat | Proč |
|---|---|
| podpisy požadované profilem; u HTTP-POST podpis aserce klíčem z důvěryhodných metadat IdP | podpis obálky sám nenahrazuje povinný podpis aserce |
| že podepsaný element je ten, ze kterého čteš data | obrana proti XML Signature Wrapping |
| Issuer, Audience a Recipient / Destination | aserce pro jinou službu se nesmí dát použít u tebe |
| NotBefore a NotOnOrAfter (s malou tolerancí hodin) | prošlá aserce je neplatná |
| InResponseTo proti odeslaným požadavkům a jednorázovost ID | obrana proti opakovanému použití (replay) |
| parser bez DTD a externích entit | odpověď je XML od klienta — riziko XXE |
Nejzákeřnější je XML Signature Wrapping: útočník vezme platně podepsanou
odpověď, podepsanou aserci ponechá (podpis sedí), ale vloží vedle ní vlastní aserci s jiným
uživatelem. Pokud knihovna ověří podpis jednoho elementu a data čte z jiného — třeba z
prvního nalezeného přes //Assertion — útočník se přihlásí jako kdokoli. Proto
nepiš vlastní zpracování SAML, ale použij udržovanou knihovnu (například Shibboleth SP,
OneLogin php-saml a python3-saml, Sustainsys.Saml2 pro .NET, Spring Security SAML) a pravidelně
ji aktualizuj. Podrobnosti o parserech najdeš v kapitole o útoku XXE.
SAML, nebo OpenID Connect?
| SAML 2.0 | OpenID Connect | |
|---|---|---|
| Formát zpráv | XML, podpis XMLDSig | JSON, token JWT |
| Vznik | 2005, OASIS | 2014, OpenID Foundation (nad OAuth 2.0) |
| Přenos | přesměrování a formuláře v prohlížeči | přesměrování a volání REST API |
| Mobilní a SPA aplikace | nepohodlné | navržené pro ně |
| Typické nasazení | firemní SSO, univerzitní federace, státní správa | přihlášení přes Google, Apple, Microsoft, nové aplikace |
Pro nové aplikace, hlavně mobilní a SPA, se dnes obvykle volí OpenID Connect. SAML ale zůstává standardem všude, kde už federace a IdP existují — v podnicích, na univerzitách i ve státní správě. Rozhodující je podpora protokolu, průběh přihlášení a pravidla ověřování, nikoli jen volba XML nebo JSON. Obecné srovnání formátů najdeš v kapitole XML vs JSON.
Podpisy se kontrolují podle konkrétní vazby
Web Browser SSO přes HTTP-POST požaduje podpis jednotlivých asercí. U HTTP-Artifact platí jiná pravidla, protože služba zprávu získává přímou komunikací s poskytovatelem identity. Podpis vždy ověřuj podle SAML Profiles, oddílů 4.1.4.4 a 4.1.4.5, ne podle toho, který element náhodou obsahuje Signature. Nejdřív ověř podpis a podmínky; teprve z ověřené aserce založ uživatelskou relaci.