Spring Security, SAML & ADFS: Úvod
Posledních pár týdnů jsem se teď mordoval se Spring Security, abych v grandiózním finále doiteroval k autentikaci pomocí SAML vůči ADFS.
Mimochodem, přijde mi, že poslední dobou, je to se Springem, jako s jakoukoliv jinou (velkou) dominantní značkou — pokud se pohybujete uvnitř dané domény, na vyhrazeném dvorečku, všechno frčí, jak na drátkách. Jakmile to zkusíte zintegrovat s něčím ne-nativním, začnou probémy. A rozlousknout ty problémy chvilku trvá — zvlášť, když StackOverflow mlčí a oficiální dokumentace se k (technologickým) cizincům moc nezná.
Ale to jsem odbočil, zpátky k tématu. Tentokrát se nebudu věnovat ani aktuálnímu use casu, ani těm problémům, ale zaměřím se jen na to, jak Springovský SAML s ADFS funguje a jak to v aplikaci naimplementovat a celkově nakonfigurovat.
Nicméně, pokud jste se ještě stále nechytli, o čem to mluvím a přemýšlíte, jestli číst dál, tak to bude o: lehce komplikované autentikaci webové aplikace oproti Active Directory (takový Microsoftí LDAP).
SAML slovníček
Neuškodí si trochu prosvištět názvosloví. I když SAML nepřináší nic moc převratného, přeci jenom říká určitým věcem svým vlastním způsobem.
- SAML — Security Assertion Markup Language
- User Agent (UA) — software, skrz který uživatel komunikuje se zabezpečeným zdrojem, typicky browser.
- Service Provider (SP) — systém, který poskytuje zabezpečený zdroj a akceptuje authentication assertions a poskytuje Single Sign-On (viz následující body).
- Identity Provider (IdP) — systém, který vydává authentication assertions a podporuje Single Sign-On.
- SAML Assertions — assertions jsou gró SAML zpráv, které lítají mezi SP a IdP. Obsahují bezpečnostní informaci/e trojího typu: authentication statements, attribute statements a authorization decision statements. Nás budou zajímat první dva typy: jestli je uživatel autentikovaný a do jakých Active Directory skupin patří.
- Single Sign-On (SSO) — přihlášení uživatele do více systémů jedinou akcí.
- Single Logout (SLO) — odhlášení uživatele z více systémů jedinou akcí.
- SAML Metadata — XML data formát pro popis specifického SAML deploymentu, tedy SP nebo IdP.
ADFS slovníček
I ADFS má vlastní okruh termínů:
- ADFS — Active Directory Federation Services
- Claims — prohlášení týkající se uživatelů, které se primárně používá pro autorizaci přístupu k aplikacím. Claims jsou to, co potřebujeme dostat do SAML assertions jako attribute statements.
- Claims Provider — systém, který poskytuje claims.
- Relying Party Trust — partnerský systém, který zpracovává claims a kterému ADFS důvěřuje.
- Federation Metadata — XML data formát pro výměnu konfigurace mezi Claims Providerem a Relying Party Trust.
SAML Binding
Následující popis SSO a SLO je poměrně detailní (musím se pochválit, že podrobnější jsem nevygoogloval) a je zaměřený na jednu konkrétní technologickou integraci — Spring Security SAML a ADFS. To znamená, že pro jiné konstelace to může fungovat “trošku” jinak.
Rovněž stojí za zmínku, že SAML specifikace definuje tzv. binding, tj. jak jsou SAML requesty a responsy mapovány na standardní message a komunikační protokoly. Pro SSO v browseru se většinou společně používají HTTP Redirect Binding a HTTP POST Binding. V následujících diagramech byste je měli bez problémů identifikovat. Co je podstatné — u tohoto druhu bindingu teče veškerá komunikace přes User Agent (browser), takže tam např. není žádná komunikace na pozadí mezi SP a IdP.
SAML Single Sign-On
Na následujícím obrázku jsem si dal hodně záležet a věřím, že jeho vysvětlující a informační hodnota je enormní, podaná krystalicky čistým způsobem. Přesto si neodpustím kratičké shrnutí:
- Browser (UA) přistoupí na chráněný zdroj na Service Providerovi (SP), který přesměruje UA na svoje login URL.
- SP vygeneruje SAML request a přesměruje UA na Identity Providera (IdP), kterému je předán SAML request.
- IdP vrátí UA přihlašovací formulář (jméno, heslo).
- UA pošle IdP credentials uživatele, spolu se SAML requestem.
- IdP předá credentials Claims Providerovi (CP), který ověří uživatele a v případě úspěchu vrátí před-konfigurované claims.
- IdP přebalí claims do assertions, které obalí do SAML response a tu pak vloží do HTML formuláře, který pošle UA. Součástí formuláře je i JavaScript, který může formulář automaticky odeslat.
- UA automaticky odešle formulář se SAML response na SP. V případě, že je v UA vypnutý JavaScript, musí uživatel odeslat formulář klepnutím na tlačítko.
- SP ověří přijaté SAML assertions a pokud je všechno v pořádku, přesměruje UA na původně vyžádaný zdroj.
Uvedené schéma zobrazuje komunikaci pro ne-autentikovaného uživatele. V případě, že je uživatel již přihlášen — ať už lokálně na daném SP, nebo díky SSO na jakémkoliv jiném SP (který je registrován u daného IdP) — tak se přeskočí posílání a odesílání ADFS login formuláře (a samozřejmě komunikace s CP) a UA rovnou obdrží SAML response.
IdP Discovery
Uvedený scénář se dá zpestřit ještě o jednu věc. Vztah mezi SP a IdP je m:n
- jeden IdP může obsluhovat několik SP a stejně tak
- jeden SP si může vybrat z několika IdP.
V prvním případě se nic zvláštního neděje, právě od toho tu je SSO. V druhém případě je to trochu komplikovanější — jak si UA/SP vybere, vůči kterému IdP se autentikovat?
Tenhle případ řeší IdP Discovery. Místo úvodního přesměrování na login URL aktuálního SP dojde k přesměrování na stránku se seznamem všech zaregistrovaných IdP, z nichž si uživatel explicitně vybere.
Nastavit IdP Discovery pomocí Spring Security SAML není nijak složité, nicméně pro tento a následující články s touto možností nepracuji.
SAML Single Logout
Když jsem se pustil do kreslení předešlého diagramu pro SSO, tak se mi výsledek tak zalíbil, že jsem si střihnul ještě jeden obrázek — pro Single Logout (SLO).
A aby to nebylo triviální, tak jsem si rozchodil dva SP, abych mohl zdokumentovat, jak probíhá odhlášení ze všech zaregistrovaných SP. Protože o tom SLO je: když se odhlásím na jednom SP, tak mě to automaticky odhlásí i ze všech ostatních SP.
To be continued…
Abych udržel článek v rozumné čitelnosti, rozhodl jsem se téma rozdělit do krátkého mini-seriálku. Příště bych se podíval, jak vyměnit metadata mezi SP a IdP, plus jak nakonfigurovat ADFS.
V závěrečném díle bych probral konfiguraci Spring Security SAML. Můžete se těšit na popis Java configuration (ofiko dokumentace jede furt na XML) a samozřejmě to pofrčí na aktuálním Spring 5.