Moderní autentizace: od SELECT password FROM k Oauth2

V sérií článků na téma moderní autentizace budu objevovat detaily přihlašování a autorizace z pohledu protokolů. Projdeme si proč to vzniklo a k čemu je to dobré a pak se pustíme do jednotlivých scénářů a vyzkoušíme si je s Azure Active Directory. Nejste programátoři? Já také ne, nemusíte se děsit. Půjdeme po stopách fungování protokolů a vystačíme si s prohlížečem a Postmanem … do appky ať to pak dá někdo jiný :)

Doba hesel per aplikace (1980s)

Všechno začalo někde v 60. letech tak, že řízení přístupu k sálovému počítači spočívalo v zaměstnaní šikovného vrátného. Nicméně i tak se občas hodilo pro sadu privilegovaných nahrát nějaké prostředí či data podle toho, kdo to je. Z toho postupně vznikl systém jméno a heslo. V nejhorším případě aplikace například zobrazila okno s políčky na jméno a heslo a pak poslala dotaz do databáze typu SELECT password FROM users WHERE username=$input a bylo. Příčetnější si samozřejmě při vzniku hesla toto neukládali, ale zaznamenali si pouze jeho hash a při přihlašování zopakovali stejnou operaci a kontrolovali jestli se výsledek shoduje.

Všechno tohle mělo zásadní nevýhodu - pro každou aplikaci se psala tato logika znovu a znovu, pokaždé mohla být trochu jiná, uživatelé si museli pamatovat velké množství loginů a přeřadit zaměstnance s tím, že se vymažou všechny jeho přístupy, bylo značně komplikované. S tím se prostě muselo něco dělat.

Doba integrovaného přihlašování (1990s)

Co kdybychom uživatelské účty centralizovali? V devadesátých letech se to začalo objevovat a to zejména kolem protokolu LDAP. Ten samotný ale řešil primárně přesunutí uživalů ze SELECT password FROM do centrálního systému, takže změna hesla uživatele je operace na jednom místě a podobně. Pracoval i s hierarchií, takže se dalo mluvit o přípravě pro nějakou základní autorizaci. Nicméně zbývala spousta nevyřešených bodů a vybavuji si dva uchazeče o řešení toho všeho - Microsoft Active Directory (první pokusy byly už v NT 3.0) a Novell (někdy z dob Netware 4).

Active Directory na to šlo tak, že vzniklo centrální místo kolem kterého se všechno točí - doménový řadič. V něm přebývají uživatelé s možností je různě kategorizovat do OU nebo/a skupin. Kromě toho si kontroler drží přehled i o zařízeních, které jeho služby chtějí využít. Začleněním počítače do domény dojde k nastavení důvěry mezi počítačem a doménou (a létají tam nějaké secrets nebo pokud chcete i certifikáty) a to umožňuje, že uživateli se stačí přihlásit do počítače a ten může přes doménový řadič řešit přihlašování aplikací. Ty totiž také mají svůj otisk v řadiči a běží typicky na serverech ve správě řadiče. Takže na jednom místě řešíte aplikace, uživatele i jejich zařízení a to včetně automatizace různých politik (GPO - nastavení počítače nebo uživatelského profilu apod.).

Úžasná věc! Jenže v novém tisíciletí se začalo dít to, že ne všechny aplikace už si firma kupuje jako krabicový software a instaluje na svoje servery. Už si bere hotovou webovou aplikaci od nějakého poskytovatele. Navíc firmy začínají mezi sebou stále víc a víc komunikovat a svoje IT systémy propojovat. Nastavit doménový trust je asi v pohodě s dceřinkou, ale okruh spolupracujících subjektů se neustále rozšiřoval na méně a méně důvěryhodné partnery. Nechat je nahlédnout do vašeho AD se vám prostě nechtělo. Bylo potřeba to řešit.

Doba Single-sign on (2000s)

První cloudy na začítku tisíciletí byly o zprostředkování aplikace (SaaS). Ono to bylo vlastně to jednodušší. Řekli jste - proč si kupovat software pro účetnictví, implementovat ho někde u vás, řešit problémy, upgrady, výměny? My vám to celé dáme jako službu, budete platit tolik a tolik a na této URL vaše účetnictví poběží. Skvělé. Nicméně jak se tam budou uživatelé přihlašovat? Zprvu jim poskytovatel vytvořil separátní login, ale to už tu jednou bylo - jakmile toho bude moc, bude to značně nepohodlné a spravovat uživatele začne být noční můra. Využití Active Directory a Kerberos a spol? Značně nepraktické. Buď musíte od poskytovatele natáhnout VPNku aby viděl vaše AD (uff, viděli jste dvakrát jejich obchodníka a to je všechno…opravdu to chcete?) nebo vzít jejich AD a nastavit trust s vaším (ani to není žádný bezpečnostní šlágr). Zkrátka narážíme tady na to, že klasické AD je dělané pro lokální síť (protokoly jsou značně nevhodné přes Internet z bezpečnostních i praktických důvodu…ono to v zásadě nefunguje) a správu buď jednoho subjektu nebo alespoň takových, které si značně věří (mají například stejného vlastníka). Co teď?

Cílem bylo najít něco, co řeší problém single-sign on. Jak zajistím, aby uživatelé měli jednotné přihlašování i u aplikací, které neprovozuji já sám, aniž bych musel provozovateli poskytnout příliš velký přístup k mým identitním systémům. Pro webové aplikace se jako dobré řešení osvědčil SAML, pro ty desktopové sada WS-* protokolů. SAML dodnes žije a dlouho bude (nicméně na nový projekt bych preferoval jinou cestu, kam směřují inovace), WS-* je prakticky mrtvé. Tyto systémy veří prohlášení (claim - je to on a tohle o něm vím), které o uživateli učiní nějaká důvěryhodná “instituce” (IdP)

Všechno začíná vypadat perfektně, tak proč další odstavec? Uživatel se nám krásně přihlašuje do všech aplikací, ale co interakce aplikací mezi sebou? Například máte aplikaci, třeba objednávkový systém, který by chtěl do pro vaše pohodlí do vašeho kalendáře vložit událost, kdy si můžete objednávku vyzvednout. Objednávková aplikace tedy potřebuje přístup do například Office365. Jak na to? Ještě před asi 12 lety jste celkem běžně narazili na to, že ta první aplikace po vás chtěla přihlašovací údaje do té druhé. Zadali jste jméno a heslo třeba na svůj Google účet a ona se do něj přihlašovala (takhle to třeba dělal kdysi Yelp). Bezpečnostně samozřejmě skandální záležitost. Jak jako uživatel můžu dát jedné aplikaci právo mým jménem přistupovat do druhé aplikace, aniž bych té první musel dát svoje heslo? A jak to udělat, abych si mohl řídit, k čemu má mít přístup, tedy v našem případě jen na vytváření schůzek, ale ne například čtení mých emailů?

Doba autorizační, delegační a role sociálních sítí (2010s)

Sociální sítě jsou častou ukázkou požadavků na autorizace. Vemte si například aplikaci Buffer, která vám umožní vytvořit a naplánovat publikaci příspěvků na LinkedInu a Twitteru. Musí být vaším jménem schopna příspěvek založit, ale ne měnit nastavení vašeho profilu apod. Nebo příklad ze světa chytré domácnosti. Máte senzor otevření dveří (nebo chytrý zámek) od jedné firmy. Dále máte chytrou žárovku a chytrou pračku od jiné firmy. Chcete, aby ta první firma rozsvítila světlo, pokud večer přijdete domů, ale nechcete jí dávat heslo do vaší chytré domácnosti ani jí dávat právo na zapnutí pračky. Tohle řeší protokol OAuth2.

Pro zvýšení bezpečnosti přišel OAuth s chytrým nápadem. Spousta věcí se děje v prohlížeči, který alespoň do nedávna neuměl dobře zacházet se secrets, takže nemá kam si rozumně bezpečně uložit token tak, aby s ním aplikace v prohlížeči mohla dobře a bezpečně pracovat (aby například token nešel jako atribut v URL a neuložil se do historie prohlížení, aby ho nedokázala zachytit nějaká extension nebo aby vám nějaký síťový prvek po cestě neukradl redirect a token si nepřečetl apod.). Systém tedy funguje tak, že v browseru běží front channel, který zajišťuje potřebná autorizační kolečka, ale výsledkem všeho není token, ale jen kód na jeho vyzvednutí. Ten poskytnete backend části (serveru) a ten si token vyzvedne bezpečněji (má client secret, tedy dohodu s autorizačním servem, takže nikdo jiný bez znalosti klíče nemůže token vyzvednout). Výborná věc. Jenže s nástupem Single-page aplikací trochu problém, když nemáte ten backend, tak OAuth přidal implicit flow, které pošle token rovnou do browseru (což není bezpečnostně ideální, ale funguje to a aktuálně se pracuje na lepších možnostech s tím, jak se vylepšují prohlížeče). A co nativní mobilní aplikace? Tam byl historicky problém bezpečně uložit client secret, tak se vymyslelo flow, ve kterém se secret dynamicky generuje (něco na způsob hash challange). Následovaly další scénáře - například schopnost administrátora udělit souhlas s autorizací tak, že se to uživatele už neptá nebo flow určené pro zařízení, které neumí redirecty uživatele (v zásadě zjednodušený scénář ala LDAP).

OAuth2 je o autorizacích, nicméně pokud jste schopni získat autorizaci třeba na přístup do uživatelova profilu, tak to vlastně současně znamená, že jste to vy, ten uživatel, protože nikdo jiný souhlas udělit neumí. Tak se začal OAuth2 používat i pro autentizaci, ale nebylo to standardizované (např. Facebook to dělal). Proto vznikla nadstavba OpenID Connect, které standardizuje způsob využití OAuth2 základů i pro autentizaci uživatele (a vznikl ID token).

Suma sumárum tato nová rodina protokolů už má všechny vlastnosti, aby dokázala řešit cross-domain autentizace a SSO stejně tak jako autorizační potřeby a stává se univerzálním a standardním řešením.

No a protože je to tak úspěšné, bezpečné a univerzální, tak se v dalších dílech na OAuth2 a OpenID Connect zaměřím do většího detailu, jak si budu uvedené scénáře zkoušet proti Azure Active Directory. A pokud jako já nejste programátoři, nevadí - vystačíme si s prohlížečem a Postmanem. Tak příště.



Cloud-native Palo Alto firewall jako služba pro Azure Virtual WAN Security
Federované workload identity v AKS - preview bezpečného řešení pro autentizaci služeb bez hesel Security
Azure Firewall Basic - levnější bráška pro malá prostředí nebo distribuované IT Security
Nativní Azure Monitor a Microsoft Sentinel nově umí levnější logy a zabudovanou levnější archivaci - praxe (část 2) Security
Federace tokenů GitHub Actions s Azure Active Directory pro přístup z vaší CI/CD do Azure bez hesel Security AAD