#Gość #OAuth #Security #Architecture
“OAuth nie jest protokołem uwierzytelniania” - Marek Grabarz zaczyna od rozwiewania największego mitu wokół OAuth 2.0. Bo jeśli myślisz, że generowanie tokenów JWT to używanie OAuth, jesteś w świetnym towarzystwie… razem z 90% deweloperów.
Łukasz wprost: “Generowanie tokenów JWT, tych JSON Web Tokenów, to nie jest używanie OAuth”. OAuth to autoryzacja, OpenID Connect to uwierzytelnianie - a ludzie ciągle mylą te pojęcia. Szymon dorzuca swoje: “Payload w JWT można normalnie odkodować po przechwyceniu tokenu. Podpis służy wyłącznie do weryfikacji” - ile razy widziałeś wrażliwe dane w tokenie, które ktoś traktował jak zaszyfrowany sejf?
Marek prowadzi przez Authorization Code Grant, Client Credentials, PKCE i tłumaczy dlaczego Implicit Flow jest eliminowany w OAuth 2.1. Rozmowa schodzi na public vs confidential clients, refresh tokeny, access tokeny i fundamentalny problem: “Ukradziony token jest ukradzionym tokenem. Możemy próbować to zabezpieczyć, ale zawsze znajdzie się jakaś luka”.
Czy przechowywanie tokenów w localStorage to ryzyko, które akceptujesz świadomie, czy po prostu nie zdajesz sobie z niego sprawy?
Linki i ciekawe znaleziska
Transkrypcja
Szymon Warda: Cześć, słuchacie Patoarchitektów. Prowadzą Szymon Warda…
Łukasz Kałużny: I Łukasz Kałużny.
Marek Grabarz I gościnnie Marek Grabarz.
Łukasz Kałużny: Tak, w dzisiejszym odcinku gościmy Marka, który jest specjalistą w kilku dziedzinach chmurowych, w tym bardzo w tożsamości od strony aplikacyjnej i dzisiaj wspomoże nas z tym tematem. Wszystkie linki do tego odcinka znajdziecie na Patoarchitekci.io/26. I Marku, jako że jesteś u nas gościem i zwykle zaczynamy odcinek od linków, to czy przygotowałeś coś dla nas?
Marek Grabarz Tak, jak najbardziej. Przygotowałem dla Was 2 linki. Link, o którym będę mówił trochę później, to jest link związany z draftem OAutha 2.1. Tak że ten link mam nadzieję Panowie wrzucicie również do materiałów pod podcastem, pod odcinkiem. Natomiast z rzeczy, które gdzieś tam na bieżąco mi się przewijały na twitterach, to jest link ukradziony z profilu nwoja. I link traktuje o kontrolowaniu ruchu wychodzącego z platformy Kubernetes. I ja generalnie lubię sobie czytać tego typu artykuły. Po pierwsze, kontrolowanie ruchu wychodzącego jest niezwykle istotne. Chociażby Łukasz, pamiętam, wrzuciłeś ostatnio link gdzieś tam na naszych wewnętrznych dyskusjach odnośnie wysyłania requestów poprzez DNS-a. I to jest taki przykład. Należy kontrolować ruch. Rzeczy, które są z tym związane, to jest chociażby Zero Trust Network i link, który Wam zostawiam, to jest historia jak jedna z firm podeszła do tego tematu i jak się zabezpieczają przed eksfiltracją danych na zewnątrz ich klastra.
Łukasz Kałużny: Tak, to jest dobry akurat przykład, bo pokazuje fajnie wizualnie, jak wygląda ta eksfiltracja i co trzeba w którym miejscu zastosować. Więc dobry prowadzący przykład za rękę, żeby zacząć, jak podejść do takiego zabezpieczenia sieciowego tego.
Marek Grabarz Tak jest.
Szymon Warda: Dobrze teraz…
Łukasz Kałużny: Szymonie.
Szymon Warda: Ja się wtrącę z moim linkiem. Ja mam całkiem ciekawą historię, taką trochę na pograniczu IT, a trochę na pograniczu takiego horror story i bezpieczeństwa. To właściwie 3 częściowy opis inwestygacji i firmy w to jak to się stało, że za pomocą zdjęcia, normalnego zdjęcia Scarlett Johansson nagle Postgres zaczął mine’ować cryptocurrency. I całkiem ciekawa analiza jak to się stało, jak do tego doszło, w jaki sposób jpeg, który dla nas wygląda normalnie, normalnie się otwiera, powoduje to, że nagle nasze serwery zaczynają szaleć i baza zamiast zwracać dane tak naprawdę, to w tle sobie tłucze i liczy kasę tak naprawdę. Bardzo fajnie opisany, fajnie zwizualizowany artykuł, w kilku częściach. Warto zapoznać się, chociażby zobaczyć w jaki sposób można przejąć kontrolę nad silnikami bazy danych. Czyli coś, czego byśmy się często nie spodziewali.
Łukasz Kałużny: Tak, to jest niezły mindfuck, że można wysłać obrazek na serwer, a zaczynać robić cryptomining.
Szymon Warda: Tak, naprawdę przerażające.
Łukasz Kałużny: Pięknie przeprowadzony atak.
Szymon Warda: U Ciebie Łukaszu?
Łukasz Kałużny: U mnie też w sumie, w ogóle nie rozmawialiśmy ze sobą na temat, to co wrzucał u mnie też trochę z bezpieczeństwem i z tym co Marek powiedział na temat eksfiltracji. Narzędzie DNS Teal, albo jak kto woli Steal. Pokazany taki proof of concept do kradzenia danych tak naprawdę, wysyłania plików poprzez DNS-a, poprzez pakiety dnsowe zrobione w jednym pliku pythonowym, w którym właśnie to, co Marek powiedział o zabezpieczaniu, może pokazać w praktyce. Ja sprawdziłem, skrypt ma 254 linie i potrafi wysłać plik poprzez DNS-a.
Marek Grabarz To jest Łukasz dokładnie to, co powiedziałem przed chwilą nawiązując do artykułu, że wrzuciłeś linka. Fajnie, że wrzuciłeś go również tutaj. A jest to niesamowicie małe, ale jednocześnie ciekawe narzędzie.
Szymon Warda: To ja pamiętam jeszcze jak była sytuacja właśnie, że w ramach rekordów DNS wpisywane były po prostu wirusy jako ataki. To też była dość ciekawa sytuacja. Tak że DNS-y, na które kiedyś nie patrzyliśmy, teraz nagle stały się dość ciekawym wektorem ataku. Bezpieczeństwo będzie rosło na wadze coraz bardziej. Dobrze.
Łukasz Kałużny: Ale metody są ciekawe właśnie, tak jak przez pakietem DNS-owym.
Marek Grabarz Tak, na porcie 53. Ktoś myśli: przecież tam tylko DNS jest. Ale niekoniecznie.
Łukasz Kałużny: Znaczy jeszcze jest VPN over ping, z takich ciekawostek.
Szymon Warda: Dobrze panowie, przechodzimy chyba do głównego tematu. Mianowicie będziemy rozmawiali o czym? O OAuth’ie. Dlatego też właśnie Marek jako gość. Więc zacznijmy od standardowego naszego pytania, czyli czym jest OAuth? W dwóch zdaniach Marku.
Marek Grabarz Ja bym powiedział, że OAuth… Albo najważniejsza informacja, która z OAuth’em się kojarzy, a nie jest prawdą, to jest to, że OAuth nie jest protokołem od uwierzytelniania nikogo. Jest to protokół czysto autoryzacyjny. To jest pierwsza najważniejsza rzecz. Jest to drugie wcielenie tego protokołu, ponieważ pierwsza wersja OAuth’a była, tak jak powiedziałem, czysto autoryzacyjna. Natomiast wersja druga uświadomiła sobie, że jednak ten element uwierzytelniania będzie potrzebny. I zamiast korzystać z zewnętrznego protokołu, doklejony został do OAuth2.0 protokół uwierzytelniający, który nazywa się OpenID Connect, w skrócie OIDC. Często taki skrót gdzieś tam funkcjonuje. I w dużym uproszczeniu OAuth jest, albo najprościej można powiedzieć opisuje sposoby i metody pozyskiwania tokenów na potrzeby naszych rozwiązań, naszych aplikacji. I w zależności jaką aplikację będziemy chcieli zintegrować z OAuth’em, tak te metody pozyskiwania tokenów mogą być różne. I to w dużym uproszczeniu tyle. Wynikowym tokenem może być jakiś opaque token, może być JWT token i sam proces autoryzacji to już jest tak naprawdę odpowiedzialność po stronie odbiorcy tego tokena. To tak, tyle w dużym skrócie.
Łukasz Kałużny: Dobra, powiedziałeś może o tokenach i to jest chyba taki największy… To w mojej opinii mindfuck, który jest robiony, bo wygenerowanie tokenów JWT, tych JSON Web Tokenów, to raczej nie jest używanie OAuth’a.
Marek Grabarz Tak, zdecydowanie. Jeżeli chodzi o generowanie tokenów, to możemy… Widzisz Łukasz, moglibyśmy wchodząc do OAuth’a podzielić tak naprawdę odpowiedzialności albo tak naprawdę aktorów w całym tym procesie pozyskiwania tokenów. I mamy tutaj do dyspozycji tak naprawdę kilka różnych rzeczy. Po pierwsze, mamy jakiś zasób, do którego będziemy uzyskiwać autoryzacje. Przypuśćmy jest to skrzynka jakaś pocztowa. Z drugiej strony, mamy właściciela tej skrzynki, czyli możesz to być Ty. Z trzeciej strony, mamy klienta, czyli aplikację, która reprezentuje tego właściciela. I z czwartej strony, mamy authorization server, czyli tak na prawdę serwer, który podejmuje decyzję czy Ty, Łukasz Kałużny, zgadzasz się na to, żeby aplikacja działająca na Twoim desktopie czy może komórce mogła dostać się do skrzynki, czyli do resource’u. I teraz rzeczywiście proces generowania tokenów zachodzi i on zachodzi na authorization server’ze w oparciu o poświadczenia i w oparciu o pewne elementy wymagane poprzez wybrany przez Ciebie sposób pozyskiwania tokenów. Więc jak najbardziej tokeny JWT są generowane, są podpisywane. Pewne claimy czy też właściwości zapisane w tokenie są do niego dodawane w tym procesie.
Szymon Warda: To ja się dopytam, doprecyzujmy, bo generalnie tokeny JWT obecnie są bardzo często używane. Do czego powinny służyć tokeny JWT? To sobie zdefiniujmy tak trochę dokładniej.
Marek Grabarz To jest dość dobre pytanie i w sumie w dużym uproszczeniu tokeny JWT to nie jest rzecz albo element, który jest jeden do jednego powiązany z OAuth’em. Oczywiście OAuth może używać tokenów JWT, ale niekoniecznie jest to wymagane. Tak naprawdę forma tokenu jest troszkę uwolniony, powiedziałbym tutaj, więc zdarzały się takie implementacje, że token jest opaque, jest po prostu stanowo przechowywany po drugiej stronie. I ta relacja też nie jest w drugą stronę jeden do jednego, dlatego że JWT jest niezależnym standardem. I tak jak może być używany w OAuth, tak samo może być używany do przenoszenia dowolnego typu innej informacji. Jeżeli oczywiście spełniamy te wymogi, czyli mamy jakiś algorytm do podpisu, wykonujemy ten podpis, to ten środkowy JSON, czyli payload, może nam służyć do przenoszenia dowolnej informacji między systemami.
Szymon Warda: Dotknąłeś tego, o co mi głównie chodziło, że JWT tak naprawdę służy do tego, żeby zweryfikować czy zestaw danych, które przesyłamy, jest podpisany, czyli nikt go nie modyfikował po drodze. To jest ten największy plus JWT jaki widzę. A teraz idąc dalej. Które dane, bo to często właśnie widuję jako błąd, które dane byś umieszczał w tokenie JWT? Jakieś identity zakładam, że tak. Czy umieszczałbyś tam dane wrażliwe nazwijmy to?
Marek Grabarz Generalnie jest parę sposobów, parę metod albo parę możliwości jak to wygląda. Najczęściej widywaną wersją jest, że dane użytkownika, które reprezentuje token, jak najbardziej są do niego wyrenderowane. Czyli widzimy imię, nazwisko, email, czasem członkostwo w grupach na przykład domenowych. I to jest bardzo częsty przypadek. Z drugiej strony i tutaj może ja jestem troszkę zbiasowany na temat tego, jak do tego podchodzi Azure, jak do tego podchodzi Microsoft, patrząc na innych dostawców takich tożsamości, uwierzytelniania, IAM-u, CIAM-u, to wygląda całkiem różnie. Jedną z metod jest przekazywanie naprawdę podstawowych informacji, chociażby ID użytkownika i nic więcej. I access token służy między innymi do tego, żeby go użyć względem czegoś, co się nazywa introspection endpoint. Czyli możemy sprawdzić czy token jest ważny w oparciu o tą introspekcję. Dodatkowo jest coś takiego jak user info endpoint i też taki access token mógłby służyć temu, żebyśmy poszli do user info i z user info uzyskali pełny zestaw informacji na temat użytkownika. Tak że jest o tyle to dobre, że w momencie kiedy access token zostanie przechwycony i być może on już będzie nieważny, to te dane w nim zawarte nic nie mówią o użytkowniku i jednocześnie nie da się go użyć do tego, żeby sczytać dane użytkownika.
Marek Grabarz Tak, jeszcze dochodzi trzeci element, JWT jako standard. Ma standard rozszerzony o nazwie JWE, JSON Web Encryption i to możemy w ogóle szyfrować jeszcze tak naprawdę na wierzchu.
Szymon Warda: O to właśnie mi chodziło, tak.
Łukasz Kałużny: Wiesz co, to Marku jeszcze do zawartości, chciałbym wrócić do tokenu. Jakbyś mógł wyjaśnić czym są claimsy? Bo trochę po drodze zacząłeś wyjaśniać i powiedzieć czym jest claims w tokenie?
Marek Grabarz Jeżeli w ogóle mówimy o tokenie JWT, to jak na niego spojrzycie, to są tak naprawdę trzy JSON-y połączone kropeczką. I te trzy JSON-y, każdy z nich jest zamieniony na base64, czyli tak naprawdę to jest base64.base64.base64. Pierwszy base64 po zdekodowaniu z powrotem do JSON-a zobaczymy, że jest to taka powiedziałbym preambuła tego tokena. Tam jest wyspecyfikowany chociażby algorytm, za pomocą którego został wykonany podpis. No i mamy tam też coś, co jest bardzo istotne w ogóle w procesie weryfikacji podpisu, czyli KID, czyli Key ID, identyfikator klucza publicznie wystawionego. Możemy sobie, że tak powiem, z czegoś, co się nazywa JSON Web Key Store, JWKS, ściągnąć ten klucz publiczny do weryfikacji podpisu. Drugi element to jest faktyczny payload i o tym za chwilę będziemy Łukasz pewnie rozmawiać. W tym payload mamy kolejny JSON Document, ale tym razem mamy już tam konkretne wartości, konkretne metadane, konkretne properties’y i one są zwane claimami w tej nomenklaturze. No i mamy trzeci JSON, który jest zakodowanym podpisem zawartości payloadu w oparciu o algorytm opisany w nagłówku. I teraz jeżeli chodzi o claimy, to w zależności czy ten JWT jest używany chociażby przez OAuth2, czy używany jest jako ID token przez OIDC, te claimy mogą być różne. Mogą być niektóre z nich wymagane, niektóre z nich mogą być opcjonalne. Tak naprawdę jest też w ramach standardu utrzymywana lista claimów albo well knownów takich powiedziałbym, znanych nazw claimów, które mogą być używane w standardzie. Natomiast w dużym uproszczeniu claimy to nic więcej jak JSON-owe property czy też jakiś tam element w JSON-ie o jakieś konkretnej wartości stringowej.
Łukasz Kałużny: Który wydał ten authorization server po prostu wydając ten token.
Marek Grabarz Tak jest, tak jest. Więc kiedy na przykład się gdzieś zalogujemy, to wynikowo możemy się spodziewać, że w takim tokenie znajdzie się claim o nazwie ISS, czyli issuer, czyli kto go wystawił. Będzie claim prawdopodobnie OID, czyli tam Object ID, jakiś identyfikator użytkownika. Jeżeli mówimy o access tokenie, to pewnie się pojawi audience, AUD, czyli dla kogo czy jaki resource tak naprawdę jest odbiorcą tego tokena. Subject, tutaj sprawa jest troszkę bardziej skomplikowana, bo z jednej strony subjectem może być aplikacja, która dostała token, a może być to kombinacja aplikacji i użytkownika, którego ona będzie reprezentować. I niezwykle kluczowe to jest Issue Add, IAD i expiry, czyli te dwa elementy czasowe, które nam pozwalają zweryfikować czas trwania czy też ważność tokena.
Łukasz Kałużny: Dobra, dziękuję. To Szymonie.
Szymon Warda: Dotknąłeś tego, ja bym może takim z uporem będę to podkreślał, że tak naprawdę ten payload, który jest w JWT, on otrzymując albo przechwytując token JWT można normalnie go odkodować, że podpis służy tylko do tego, żeby zweryfikować czy nikt payloadu nie modyfikował. Ja to podkreślam za każdym razem, bo często patrząc na token JWT ludzie myślą: okej, to zostało zaszyfrowane. Nie, nie zostało zaszyfrowane, ale ruszyłeś temat właśnie tego, że tokeny JWT można w ten payload szyfrować. Jak? Mógłbyś rozwinąć temat?
Marek Grabarz Tak jak wspomniałem, tym elementem szyfrującym w tokenach JWT jest standard JWE, czyli JSON Web Encryption. I rzeczywiście takie tokeny przekazywane po kabelku zwykle są przekazywane poprzez https, TLS. Czyli mamy transport security, ale dodatkowo mamy rzeczywiście możliwość zakodowania tego tokena mając go, że tak powiem, at rest. Czyli jeżeli ktoś go zobaczy, to zobaczy, że jest zaszyfrowany. Natomiast problem z takim czymś jest taki, że to nie zawsze ma zastosowanie. Czasami, kiedy na przykład rozmawiamy o aplikacji frontendowej chociażby, to ten token sam w sobie nie może być zaszyfrowany, ponieważ nie mamy za bardzo możliwości go odszyfrować po swojej stronie bez dostępu do secretu. Jeżeli z kolei mamy secret, to wszyscy inni też go mają, bo mamy JavaScript wyrenderowany do przeglądarki i tak dalej. Więc to nie są takie jakby rzeczy oczywiste. I tak jak powiedziałbym, tak jak wspomniałem, moim zdaniem lepszą metodą zamiast przekazywać dane wewnątrz tokena albo go szyfrować, jest przekazywać minimalną ilość danych, a wystawić user profile, żeby można było te poszczególne dane sczytywać używając tego tokena. Kiedy on wygasa, dostęp do user profile’u jest niestety już niemożliwy.
Szymon Warda: Jasne. Łukasz.
Łukasz Kałużny: Idąc dalej trochę będę teraz wchodził, odchodząc może trochę, w sumie token będzie padał, ale troszeczkę. Mówiłeś o refresh kodzie. Mamy jeszcze ID tokeny, authorization code, czyli już te zabawki, które leżą w samej implementacji OAutha.
Marek Grabarz Jest tego trochę. I tutaj jakby chciałbym Was teraz odesłać do linka, który opisuje draft protokołu OAuth, czyli wersję 2.1. Mówię o tym dlatego, że historycznie, kiedy OAuth2.0 został opublikowany, on przewidywał cztery typy powiedziałbym przepływów czy też tak zwanych grantów, które pozwalały nam uzyskać token. Były to Authorization Code Grant, Implicite, Client Credentials Grant i Resource Owner, Password Credentials Grant. To też ja tutaj celowo mówię grant, bo często gęsto pojawia się takie określenie jak flow. No i tak jak istnieje Implicite Flow i Authorization Code Flow, tak na przykład Client Credentials Flow nie występuje. A ta różnica wynika z tego, że o ile C to są flowy, czyli protokoły powiedziałbym przepływów, uwierzytelniania. Natomiast OAuth w dalszym ciągu jest autoryzacją, więc tutaj mamy granty. One często gęsto są sklejone w jeden przepływ taki, powiedziałbym OIDC przepływa i kończy się grantem. Ale warto odróżnić. Dobra, wracając do tych czterech grantów, które pierwotnie wspomniałem, każdy z nich miał jakieś swoje specyficzne zastosowanie. Natomiast z upływem czasu okazało się, że pojawiło się coś, co się nazywa Operation Code Grand Pixie, czyli PKCE. Tak to wymawiają ludzie z zagranicy. No i ten Pixie jest w dużej mierze w stanie zastąpić Implicite. Stąd nagle się okazało, że ten Implicite Grant, mimo że on jest dość bezpieczny, ale jest niestety bardzo podatny na błędy ludzkie. W związku z tym został stopniowo poprzez rekomendacje wyeliminowany albo jest eliminowany dość skutecznie. No i drugi grant, który został wyeliminowany, to jest Resource Owner Password Credential Grant. Dla mnie on jest mega niebezpieczny. On jest takim troszkę, że tak powiem, przedłużeniem takiego legacy, gdzie mieliśmy jakieś tam uwierzytelnianie poprzez formularz, login, hasło wpisywane bezpośrednio na stronce. No i chyba on powstał, żeby zapełnić tę dziurę. Natomiast na dzień dzisiejszy on moim zdaniem ma już bardzo niszowe zastosowanie, w szczególności takie, kiedy byśmy chcieli symulować użytkownika w jakimś teście automatycznym czy tego typu rzeczach. Stąd też tendencja taka, żeby zostać tylko z tymi dwoma granatami, czyli Authorization Code Grant i Client Credentials. I teraz panowie, nie wiem, czy to jest miejsce na to, żeby je opisywać głębiej i opisywać ich zastosowanie, ale to Wam zostawiam decyzję.
Szymon Warda: Wydaje mi się, że zdecydowanie jak najbardziej.
Marek Grabarz Tak.
Łukasz Kałużny: Jak najbardziej. Jakbyś zaczął od flow, bo to jest chyba w ogóle taki, z którym się spotykamy na co dzień, prawie wszędzie w internecie.
Marek Grabarz Czyli Code Granty, o tym mówisz?
Łukasz Kałużny: Tak, mówię o zwykłym… Raczej Implicite Flow.
Marek Grabarz Implicite Flow. To jest ten, którego już OAuth2.1 będzie starał się eliminować. W dużym uproszczeniu Implicite Flow pierwotnie był… Albo pomysłem na użycie Implicite Flow było używanie go w aplikacjach typu SPA, czyli Single Page Application, mamy JavaScript. W związku z tym, że to działa nam, że tak powiem, cały kod w ramach jednego adresu, nie chcemy robić żadnych redirect’ów, przekierowań. Więc cała mechanika polega na tym, że jest używany iframe i przekierowanie z iframe jest tak zwane na URL segment, czyli mamy po # na przykład loggedin, authenticated czy tego typu rzeczy. I cały Implicite Grant polega na tym, w odróżnieniu od pozostałych, że tutaj prosimy użytkownika o podanie loginu i hasła. Czyli w iframe wyświetla się okienko logowanie czy to z Googla, czy z jakiegoś Facebooka, czy może z Microsoftu. Użytkownik wpisuje login i hasło. I tutaj nie ma żadnej wymiany dodatkowej, jakiś tam authorization kodów czy innych rzeczy. Po prostu natychmiast jest otrzymywany token bezpośrednio do przeglądarki. On jest krótko żyjący, zwykle około godziny. Nie mamy żadnego refresh tokena, czyli nie możemy przedłużać tej sesji i nie możemy… Czy nie możemy. Możemy, ale to troszkę inaczej działa. Natomiast refresh tokena bezpośrednio nie dostaniemy. I rekomendacje są takie, że oczywiście możemy w dalszym ciągu uwierzytelnić tak użytkowników. Natomiast nie powinniśmy tego uzyskanego access tokena używać względem jakichś backendowych API. Tak to w dużym uproszczeniu wygląda, ponieważ jest to uznawane za dość podatne na błędy ludzkie, na błędy w bibliotekach, których używamy i tak dalej. To jest raz. Drugim dużym, powiedziałbym, grantem czy flowem jest Authorization Code Grant. On jest ze swojej natury o wiele bardziej skomplikowany. Mówimy tutaj już o takich dwóch klasycznych endpointach. Jeden to jest authorization endpoint, drugi token endpoint. No i proces mniej więcej wygląda następująco. Po pierwsze, użytkownik jest przekierowany do strony logowania, która gdzieś tam jest hostowana w tym nazwijmy to Google czy Microsofcie. Tam użytkownik wpisuje swoje poświadczenia. I w oparciu o te poświadczenia może się pojawić taki element tak zwanych scope’ów, czyli takich uprawnień dla aplikacji. Pamiętacie? Wspomniałem na początku, że mamy tego użytkownika, tego Resource Ownera i mamy aplikację, która próbuje uzyskać dostęp do zasobów w kontekście tego użytkownika. Chociażby klient poczty próbuje zgodzić się ze mną, żeby dostać się do mojej poczty. Więc scope’y to jest coś, co czasem pewnie widzieliście, wyskakuje takie na ekranie: czy zgadzasz się, żeby aplikacja Mój Mail czytała Twoją pocztę, Twój profil i zapisywała zmiany i wysyłała maile w Twoim imieniu na przykład.
Szymon Warda: Popularne w Google’u i teraz też w aplikacjach pozostałych.
Marek Grabarz To są te scope’y.
Łukasz Kałużny: Czy jak ktoś w Facebookiem się loguje, żeby Twoja aplikacja przeczytała maila albo mogła publikować na Twoim wallu?
Marek Grabarz Tak. I tutaj się odbywa coś, co się nazywa autoryzacja. Czyli ten authorization server mając moje poświadczenia, dowiadując się poprzez protokół OIDC, że ja jestem ja, teraz mnie pyta czy ja wyrażam zgodę, żeby na tym tokenie takie scope’y, czy też taki dostęp do resource został im udzielony, tak. Jeżeli ja się zgodzę, to do tego inicjatora, czyli do tej aplikacji klienckiej wraca coś, co się nazywa authorization code. To jest coś, co jest używane tylko jednorazowo. Jego ważność jest zwykle około minuty. I teraz ta nasza aplikacja kliencka musi z tym authrization code’m szybko wrócić do serwera, żeby zamienić go na access token, który będzie trwał godzinę chociażby. I tak mniej więcej w dużym uproszczeniu, czyli w takich dwóch krokach dużych, jest ten dostęp uzyskiwany albo pozyskiwany ten token. I teraz to, co zwykle było pierwotnie w Authorization Code Grancie, że ten drugi call musiał być wykonywany z Client ID Secret tej aplikacji, która go wykonuje, co automatycznie skutkowało tym, że ona nie miała zastosowania, albo ten flow nie miał, czy grant nie miał zastosowania dla tak zwanych public klientów. I teraz mała dygresja. Czym są public client versus confidential client? To jest bardzo prosty podział. Public client to taka aplikacja, która nie jest w stanie bezpiecznie trzymać swoich secretów. Nie ma ich. Nie może ich trzymać w kodzie, w konfiguracji, w jakimś tam JavaScripcie. Nie ma takiej możliwości, bo zawsze ktoś może zrobić dekompilację, prześledzić kod, przepływ i tak dalej. Więc public client to typowy JavaScript, to typowa aplikacja desktopowa, to typowa aplikacja mobilna. Choćbyśmy nie wiem jak się starali, nie ukryjemy tego secreta do końca, prawda.
Łukasz Kałużny: Czyli wszystko co jest client facing po prostu z założenia, jeżeli klient ma dostęp ze swojego urządzenia.
Marek Grabarz Tak, w dużym uproszczeniu tak. Wszystko to, co działa bezpośrednio na urządzeniu klienta. Natomiast te confidential aplikacje to są takie, które mają backend. To jest zwykle jakieś API, to jest zwykle jakaś nasza, że tak powiem, demo, aplikacja konsolowa, aplikacja webowa renderowana po stronie serwera. To są confidential appy. I teraz wracając, co się zmieniło? Więc ACG był pierwotnie dla confidential aplikacji i poprzez pojawienie się tego extension do OAutha o nazwie Pixi, PKC, Proof Code Exchange, nagle się okazało, że Authorization Code Grand znalazł zastosowanie w aplikacjach tych, że tak powiem, public client. I stopniowo poprzez zwiększone bezpieczeństwo zaczął wypierać Omplicite Granta, czy też Implicite Flow. I to jest właśnie w tym momencie zakres tej rekomendacji 2.1, OAutha2.1. Czyli zapominamy o implicite, używamy Code Granta w aplikacjach publicznych z rozszerzeniem Pixi. Używamy Code Granta bez rozszerzenia Pixi w aplikacjach Confidential. I w dużym uproszczeniu zaczyna nam się bardzo upraszczać świat i zostaje w naszym, że tak powiem, naszej dyskusji, tylko coś, co się nazywa Client Credential Grant, a to jest zupełnie inne zwierzę. Tak jak wcześniej w Implicite i w Code Grancie mówiliśmy o flow, mówiliśmy o grancie, ponieważ jest tam proces uwierzytelniania, pojawia się dlatego flow, dlatego OIDC. Tak klient Credential Grant jest to API do API, maszyna do maszyny. Czyli tutaj nie mamy uwierzytelniania, mamy jakiegoś tam Client ID Secret, rozmawiają ze sobą i dostają uprawnienia, tak. Mówimy, że, nie wiem, proces, jakiś daemon, który potrzebuje przemielić jakieś tam skrzynki pocztowe, potrzebuje dostępu do tych skrzynek i je dostaje. Nie ma kontekstu użytkownika, to jest zupełnie inny przepływ. Jest bardzo prosty.
Szymon Warda: Jasne i trochę właśnie ruszyłeś temat, powiedzieliśmy dość sporo w kontekście właśnie takich usług klienckich, które uzyskują granty, właśnie aplikacje webowe i tak dalej. A jak się to wszystko ma, jeżeli mamy taką typową aplikację backendową tak naprawdę, jak w tym momencie wygląda cały OAuth? Czy się nadaje, czy się stosuje i co się zmienia?
Marek Grabarz Jak najbardziej. I tutaj jest dość ważny element, który poruszyłeś Szymon, to… Należy w ogóle spojrzeć na OAutha w dwóch kontekstach. Oczywiście jeden z tych wymiarów, o których mówiłem, to są te publiczne aplikacje względem Confidential App. Ale drugi wymiar, być może prostopadły do tego pierwszego, jest taki co ten OAuth ma, kogo ma reprezentować? Pamiętaj, że wspomniałem o tym resource owner’ze, czyli właścicielu zasobów. I tak jak mamy właścicieli skrzynek poszczególnych mailowych, to tutaj w ogóle te przepływy są tak jak opisałem, czyli delegujemy dostęp albo wyrażamy zgodę, żeby aplikacja nas reprezentowała w jakiś sposób. To jest jedna z możliwości. Natomiast może być też tak, że jakiś admin naszej organizacji jest takim współwłaścicielem wszystkich skrzynek mailowych. I on nagle nie reprezentuje sobą swojej skrzynki, tylko chciałby mieć dostęp taki back office do wszystkich skrzynek mailowych jednocześnie, nie wiem, chciałby ustawicznie raz na miesiąc oczyszczać spamboxy na przykład, albo robić jakiś monitoring czy tam załączników ludzie nie wysyłają na zewnątrz organizacji. No nie wiem, no różne mogą być zastosowania w takim miejscu. I wtedy, jeżeli patrzymy na właściciela jako takiego całościowego właściciela, to rzeczywiście mamy tutaj zupełnie inne przepływy. I tym zupełnie innym przepływem jest właśnie wspomniany Client Credential Grant tym razem, bo nie uwierzytelniamy człowieka, bo to człowiek jeden nie jest właścicielem, tylko jest jakaś tam aplikacja, jakiś backend próbuje się dostać. I ten przepływ jest trywialnie prosty. Tam podajemy Client ID, jakiś tam client secret, czyli poświadczenia takiego, powiedziałbym, konta technicznego, podajemy na co to się ma autoryzować i w dużym uproszczeniu tyle. Dostajemy token, który to token nie ma żadnych danych o użytkowniku, nie ma jego maila, imienia, nazwiska, bo nie prezentuje żadnego człowieka. To jest po prostu rozmowa maszyny z maszyną. I tutaj jest zastosowanie tego drugiego dużego grantu, czyli właśnie Client Credential.
Szymon Warda: Jasne.
Łukasz Kałużny: Wiesz co, Marek, to jeszcze jedną rzecz, bo mówiłeś właśnie, podałeś o Client ID w kontekście aplikacji, bo one są przechowywane, mają swój rejestr, można powiedzieć, swoje dane na authorization serverze.
Marek Grabarz Tak jest, każda aplikacja, każdy element naszej układanki powinien być identyfikowany jako Client ID. Przykładowo mamy 5 backendów, czyli 5 jakichś API, mamy API wystawione do świata chociażby, ale też wewnętrznie w naszej organizacji. Więc ja bym się spodziewał, że każde z tych API będzie miało swoje Client ID. To po pierwsze. Po drugie, każda aplikacja, czy to jest aplikacja frontendowa, typowo taki, nie wiem, stronka na przykład www, czy jakaś apka mobilna, czy może właśnie jakiś tam konsolowy proces odpalany cyklicznie przez administratora, znowu każdy z tych elementów układanki powinien mieć swoje Client ID. I teraz w zależności jak będzie chciał pozyskać dostęp, do ktorego API, za pomocą jakich tokenów, tak ten Client ID będzie odpowiednio skonfigurowany, żeby miał secret, albo nie miał secret, żeby używał takiego przepływu, albo innego przepływu i żeby uzyskiwał odpowiednie uprawnienia. Chociażby można takie uprawnienia, dostępy zaklikać, można te scope’y zaklikać. W dużym uproszczeniu każda aplikacja w naszym scenariuszu powinna mieć swoje Client ID.
Szymon Warda: Jasne. To tak powoli już wrapując ten odcinek, to dużo mówimy o OAuthie, dużo mówimy o tym kiedy stosować. Ale brakuje mi tego, kiedy OAutha nie stosować, kiedy powiedzieć ok, tu się nie nadaje po prostu, korzystamy z czegoś innego. Są takie przypadki?
Marek Grabarz Znaczy generalnie ja myślę, że OAuth jest odpowiedzią taką bieżącą na większość problemów, które się pojawiają w temacie uwierzytelniania. Natomiast są pewne elementy, gdzie ten OAuth nie pasuje. Trudno mi jest wynurzyć takie, że tak powiem, z marszu. Natomiast tak, mamy systemy legacy, które po prostu nie umieją komunikować się za pomocą OIDC i OAutha. Bardzo często na przykład robiona jest federacja między systemami i w dalszym ciągu w tym obszarze króluje chociażby SAML albo jakiś tam WS-Fed chociażby, bardziej skomplikowany, rzadszy o wiele. Myślę, że ten SAML jest głównym tutaj elementem, takim federacyjnym. Oczywiście można to robić poprzez OIDC, ale niektóre systemy tego nie wspierają. Więc są systemy legacy. Z drugiej strony mamy obszary jakichś tam dużych organizacji, które nie czują się komfortowo z OAuthem, albo generalnie nie czują się komfortowo z tokenami, szczególnie w zastosowaniach takich, powiedziałbym, uwierzytelniania klientów, frontendy, tego typu rzeczy. Dlaczego? Dlatego, tak jak wspomniałeś, po pierwsze, ten token gdzieś musi być przechowywany w przeglądarce. Zwykle jest to localstorage. Ale taki sposób przechowywania jest dość mocno podatny na jakieś cross-site’y tego typu rzeczy, możemy go zawsze z JavaScriptu wyciągnąć. I jeżeli nasza strona www ma jakieś podatności, to ten token może zostać wyciągnięty z tego localstorage i użyty w dość niepoprawny albo niepopularny sposób, powiedziałbym tak. Stąd też w niektórych obszarach, takich bardzo wrażliwych, ten OAuth może być już niewystarczający. Te tokeny JWT mogą być niewystarczające. I pojawiają się nowe protokoły uwierzytelniania, które są albo mają, że tak powiem, ambicje tego, żeby zastąpić tego OAutha. Również pojawiają się jakieś rozszerzenia, jak chociażby token binding, który przez moment by wyglądał jak fajny pomysł, ale z czasem chyba nie będzie miał pełnej adopcji, żeby zabezpieczyć się przed tym wyciekiem tokenu, który moim zdaniem najbardziej spędza sen z powiek wielu osobom w bezpieczeństwie IT.
Szymon Warda: Ok, to już trochę zahaczyłeś o kolejne moje pytanie, to właśnie co niesie przyszłość tak naprawdę? Gdzie pójdą właśnie tego typu protokoły? Gdzie pójdzie sam OAuth? Co się może zmienić i na co powinniśmy uważać?
Marek Grabarz Więc po pierwsze, rzeczywiście cały czas panuje takie przeświadczenie, że ten OAuth rzeczywiście, kiedy ucieka nam token, jesteśmy wystawieni na duże niebezpieczeństwo. Stąd też zmniejsza się czas trwania tego tokenu i jego ważności i tak dalej. I cała masa inicjatyw idzie w kierunku zabezpieczenia użycia tego tokenu, żeby ukradziony token nie dało się użyć. Więc na przykład jest tam zaspawany adres IP, chociażby ten wspomniany token binding, czyli taki, powiedziałbym, odcisk palca tunelu TLS, za pomocą którego został on pozyskany, w związku z tym nie może być używany przez kogoś innego, bo ten ktoś inny nie będzie w stanie nawiązać połączenia SSL w odpowiedni sposób. To wiąże się z tym cała masa różnych problemów. Natomiast wydaje mi się, że to są takie, powiedziałbym, próby zaczarowania świata, czyli rozwiązania problemu, który jest nierozwiązywalny, tego, o którym mówiłem. Czyli ukradziony token jest ukradzionym tokenem i możemy próbować to zabezpieczyć, ale zawsze znajdzie się jakaś dziura, która nam pozwoli ten token użyć. W związku z tym musimy sobie chyba zdać sprawę, że taka jest przypadłość tego naszego, tych naszych tokenów. Musimy sobie zdać sprawę, że musimy minimalizować ryzyko, ale niekoniecznie powiedzieć, że jesteśmy w 100% bezpieczni. I pojawiają się nowe metody, stopniowo zyskują popularność, żeby nie operować na takich tokenach, jak chociażby WebAuthn, który też pewnie wymaga troszkę zgłębienia, bo być może jest to kierunek, który będzie coraz bardziej popularny w przyszłości.
Szymon Warda: Jasne, dzięki. Łukasz, jakieś pytania? Czy zwijamy odcinek?
Łukasz Kałużny: Zostało takie, wiesz co, taka jedna rzecz na podsumowanie, bo w sumie nie zadaliśmy tego pytania, a padło kilka razy. Bo OAuth jest do autoryzacji tylko i wyłącznie, do wystawienia tej części autoryzacyjnej. A nakładką na to jest OpenID Connect, który załatwia nam całe te flow i całą tą zabawę, o którą rozmawialiśmy. Jak to wygląda Marku?
Marek Grabarz Tak, że tak jak już wspomniałem parę razy, ja tu staram się też podkreślać, że jak mówimy o flow, to są rzeczy związane z OIDC. Jak mówimy o grantach, to jest autoryzacja. I tak naprawdę OIDC zostało wspawane albo wmontowane w OAutha2.0. Jest to jedna z podstawowych różnic względem OAutha1. I to wspawanie polega na tym, że za każdym razem, kiedy rozmawiamy w kontekście impersonacji człowieka albo działania w imieniu człowieka, jak już wspomniałem, jest ta skrzynka magiczna mailowa, jestem jej właścicielem, a apka jakaś próbuje w moim imieniu do tej skrzynki się dostać, odebrać moje maile. To za każdym razem, kiedy mamy tutaj w kontekście jakiegoś tam człowieka albo właściciela, który może się zalogować w sposób interaktywny, uwierzytelnić w sposób interaktywny, to tutaj wchodzi właśnie wspomniany OIDC i wspomniany Implicite Flow lub też Authorization Code. Oczywiście tam są jeszcze jakieś przez OIDC definiowane mix mode’y tego uwierzytelniania. Natomiast też nie ma co tam wchodzić w szczegóły, bo to jest dość rozbudowany standard. Do tego dochodzą elementy związane chociażby z utrzymywaniem sesji, jakieś SSO, czyli Single Sign-On. Cała masa elementów, które nam po prostu ułatwiają życie, żebyśmy się nie musieli po dziesięć czy sto razy uwierzytelniać. To OIDC oczywiście trzyma całą tą informację po swojej stronie i wpina się do OAuth w sposób taki, że strzela do Authorization Endpointu i że tak powiem, udziela tych autoryzacji na pozyskanie tokena przez aplikację.
Szymon Warda: To ja się wtrącę, bo znowu będziemy mieli uwagi a propos używania skrótów. Mówiąc OIDC masz na myśli właśnie OpenID Connect?
Marek Grabarz Tak, to już mówiłem parę razy na początku.
Szymon Warda: Rozwijam, żeby mieć pewność. Dobrze, to wrapujemy odcinek. Tyle. Dziękuję pięknie.
Marek Grabarz Dziękuję uprzejmie za zaproszenie.
Szymon Warda: Na razie.

Wypełnij poniższy formularz, aby być na bieżąco ze wszystkimi
odcinkami Patoarchitektów
i uzyskać dostęp do dodatkowych
materiałów.