Choosing an SSO Strategy: SAML vs OAuth2
Możliwe, że logowałeś się do jakiejś aplikacji (mobilnej lub webowej) klikając na przycisk „Zaloguj się przez Facebooka”. Jeśli używasz Spotify, Rdio lub Pinterest, to wiesz o czym mówię.
Jako użytkownik, prawdopodobnie nie dbasz o to, jak działa SSO. Chcesz po prostu korzystać z aplikacji i możesz być wdzięczny za to, że Twoja aplikacja działa płynniej i że musisz pamiętać mniej loginów i haseł.
Aby zapewnić użytkownikowi możliwość jednokrotnego logowania, programista musi wdrożyć rozwiązanie SSO. Przez lata było wiele prób osiągnięcia SSO, ale ten artykuł będzie się skupiał na porównaniu SAML i OAuth2 – niedawnej eksploracji, której się podjęliśmy (na szczęście wyszliśmy z tego bez szwanku, ale z dużą ilością informacji).
Nasza potrzeba SSO
Pracujemy nad platformą, która będzie miała kilka aplikacji klienckich. Niektóre z tych aplikacji będą oparte na sieci, inne będą natywne, jak np. aplikacje mobilne.
Platforma ta będzie dostępna dla kilku różnych klientów (należących do różnych organizacji). Po drodze, dodatkowe aplikacje firm trzecich mają być zbudowane wokół tej platformy.
Platforma jest front-endem do dużego systemu korporacyjnego, który już posiada informacje o tożsamości osób, które będą z nim współdziałać. Zamiast utrzymywania przez każdą aplikację kliencką własnej bazy danych użytkowników z nazwami użytkowników i hasłami, bardziej odpowiednie wydaje się wykorzystanie SSO.
Single sign on pozwoli systemowi korporacyjnemu na bezpieczne przechowywanie i posiadanie wszystkich danych uwierzytelniających użytkownika. Platforma może ustanowić relację zaufania z korporacyjnym serwerem uwierzytelniania, a aplikacje klienckie mogą być budowane w celu wykorzystania zaufanego serwera autoryzacji do uwierzytelniania użytkowników.
Naszym celem było zidentyfikowanie strategii SSO i jej wdrożenie, które mogłoby wesprzeć te potrzeby.
Enter SAML 2.0
Początkowo przyjrzeliśmy się SAML 2.0, który jest zestawem otwartych standardów, z których jeden został zaprojektowany specjalnie dla SSO.
Specyfikacja SAML 2.0 (dalej SAML) zapewnia profil SSO dla przeglądarek internetowych, który opisuje, w jaki sposób pojedyncze logowanie może być osiągnięte dla aplikacji internetowych. Istnieją trzy główne podmioty w SAML:
SAML i OAuth2 używają podobnych terminów dla podobnych koncepcji. Dla porównania formalny termin SAML jest wymieniony z odpowiednikiem OAuth2 w nawiasie.
-
Dostawca usługi (Resource Server) – jest to serwer sieciowy, na którym próbujesz uzyskać dostęp do informacji.
-
Klient – jest to sposób, w jaki użytkownik wchodzi w interakcję z serwerem zasobów, jak aplikacja internetowa obsługiwana przez przeglądarkę.
-
Dostawca tożsamości (Authorization Server) – jest to serwer, który jest właścicielem tożsamości i poświadczeń użytkownika. To z nim użytkownik faktycznie się uwierzytelnia.
Najczęściej spotykany przepływ SAML jest przedstawiony poniżej:
Oto fikcyjny scenariusz opisujący powyższy diagram:
-
A – użytkownik otwiera swoją przeglądarkę internetową i wchodzi na stronę MyPhotos.com, gdzie przechowywane są wszystkie jego zdjęcia. MyPhotos.com nie obsługuje uwierzytelniania.
-
B – aby uwierzytelnić użytkownika MyPhotos.com konstruuje SAML Authnrequest, podpisuje go, opcjonalnie szyfruje i koduje. Następnie przekierowuje przeglądarkę internetową użytkownika do dostawcy usług identyfikacyjnych (IdP) w celu uwierzytelnienia. IdP odbiera żądanie, dekoduje je, w razie potrzeby odszyfrowuje i weryfikuje podpis.
-
C – Z ważnym Authnrequest IdP przedstawi użytkownikowi formularz logowania, w którym może on wprowadzić swoją nazwę użytkownika i hasło.
-
D- Po zalogowaniu się użytkownika IdP generuje token SAML, który zawiera informacje o tożsamości użytkownika (takie jak jego nazwa użytkownika, e-mail itp.). Id bierze token SAML i przekierowuje użytkownika z powrotem do dostawcy usług (MyPhotos.com).
-
E – MyPhotos.com weryfikuje token SAML, odszyfrowuje go w razie potrzeby i wyodrębnia informacje o tożsamości użytkownika, takie jak to, kim są i jakie mogą być ich uprawnienia. MyPhotos.com loguje teraz użytkownika do swojego systemu, przypuszczalnie za pomocą jakiegoś rodzaju pliku cookie i sesji.
Na końcu procesu użytkownik może wchodzić w interakcję z MyPhotos.com jako zalogowany użytkownik. Dane uwierzytelniające użytkownika nigdy nie przeszły przez MyPhotos.com, tylko przez Dostawcę Tożsamości.
Powyższy diagram zawiera więcej szczegółów, ale to jest wysoki poziom tego, co się dzieje.
Gdy po raz pierwszy wprowadzono do SAML, termin „SAML token” pojawiał się w kółko. W rzeczywistości nie jest to termin w specyfikacji SAML, ale ludzie ciągle go używali, a jego znaczenie było nieuchwytne.
Jak się okazuje, termin „SAML token” wydaje się być potocznym sposobem na odniesienie się do asercji SAML, często skompresowanej, zakodowanej, ewentualnie zaszyfrowanej, i zazwyczaj wygląda jak gobbly-gook. A SAML Assertion to po prostu węzeł XML z określonymi elementami.
SAML’s Native App Limitation
SAML wspiera koncepcje wiązań. Są to zasadniczo środki, za pomocą których Dostawca Tożsamości przekierowuje użytkownika z powrotem do Dostawcy Usług. Na przykład, w kroku D powyżej, użytkownik zostaje przekierowany z powrotem do MyPhotos.com, ale jak?
Dwa istotne typy powiązań to HTTP Redirect i HTTP POST zdefiniowane w specyfikacji SAML 2.0. Wiązanie HTTP Redirect użyje HTTP Redirect, aby odesłać użytkownika z powrotem do Service Provider, w przypadku naszego przykładu: MyPhotos.com.
Wiązanie HTTP Redirect jest świetne dla krótkich wiadomości SAML, ale odradza się używanie ich do dłuższych wiadomości, takich jak asercje SAML. Z wikipedii:
Dłuższe wiadomości (np. te zawierające podpisane asercje SAML) powinny być przekazywane za pomocą innych wiązań, takich jak HTTP POST Binding.
Zalecany sposób użycia HTTP POST ma swoje własne dziwactwa. Na przykład specyfikacja SAML zaleca, aby krok D powyżej renderował formularz HTML, w którym akcja wskazuje z powrotem na dostawcę usług.
Możesz albo kazać użytkownikowi kliknąć inny przycisk, aby przesłać ten formularz, albo możesz wykorzystać JavaScript, aby zautomatyzować przesyłanie formularza. Dlaczego istnieje formularz, który musi zostać przesłany? Moim zdaniem, SAML 2.0 pokazuje swój wiek (circa 2005), ponieważ formularz tutaj istnieje tylko po to, aby HTTP POST mógł być użyty do wysłania tokena SAML z powrotem do dostawcy usług. Co w obronie SAML, w 2005 roku, było prawdopodobnie konieczną decyzją w tym czasie.
To jest problem, gdy klient nie jest aplikacją internetową, ale natywną, taką jak aplikacja mobilna. Na przykład, załóżmy, że zainstalowaliśmy aplikację MyPhotos na iPhone. Otwieramy aplikację i chcemy, abyśmy uwierzytelnili się wobec Dostawcy Tożsamości. Gdy już się uwierzytelnimy, Dostawca Tożsamości musi wysłać token SAML z powrotem do aplikacji MyPhotos.
Większość aplikacji mobilnych można uruchomić za pomocą niestandardowego URI, takiego jak „my-photos://authenticate”, i przypuszczalnie Dostawca Tożsamości przesyła formularz zawierający token SAML do tego adresu URL. Nasza aplikacja MyPhotos uruchamia się, ale nie jesteśmy zalogowani. Co się dzieje?
Aplikacje mobilne nie mają dostępu do treści HTTP POST. Mają dostęp tylko do adresu URL, który jest używany do uruchomienia aplikacji. Oznacza to, że nie możemy odczytać tokena SAML.
Na Androidzie: uruchamianie aplikacji z adresu url za pomocą Intents.
Na iOS: uruchamianie aplikacji poprzez rejestrację niestandardowego schematu URI.
Brak tokena SAML, brak uwierzytelnionego użytkownika.
Opracowanie SAML’s HTTP POST Binding
Ograniczenie wiązania HTTP POST dla natywnych aplikacji mobilnych można obejść. Na przykład, możesz użyć wbudowanych widoków sieciowych, w których napiszesz niestandardowy kod, aby obserwować cały proces uwierzytelniania. Na samym końcu procesu zeskrobujesz HTML strony i wyodrębniasz token SAML.
Drugim obejściem jest zaimplementowanie serwera proxy, który może odebrać HTTP POST, wyodrębnić token SAML, a następnie utworzyć adres URL, który zawiera token SAML (np.: „myphotos://authenticate/?SAMLRequest=asdfsdfsdf”) Serwer proxy mógłby następnie użyć przekierowania HTTP Redirect, aby spowodować, że urządzenie otworzy aplikację MyPhotos. A ponieważ token SAML jest częścią adresu URL, aplikacja MyPhotos może go wyodrębnić i użyć do zalogowania się.
Trzecie obejście polegałoby na zignorowaniu zalecenia specyfikacji przeciwko używaniu wiązania HTTP Redirect. Jest to bardzo kuszące, ale trudno pozbyć się wrażenia, że wchodzimy na pole minowe, mając tylko nadzieję, że nie zrobimy jednego złego kroku.
Innym podejściem, które pozwoliło całkowicie uniknąć obejść jest nie poleganie na SAML, ale przyjrzenie się innemu podejściu, jak OAuth 2.0.
Wprowadzenie OAuth 2.0
W przeciwieństwie do SAML, OAuth 2.0 (odtąd OAuth2), jest specyfikacją, której atrament ledwo wysechł (circa late 2012). Ma tę zaletę, że jest aktualna i uwzględnia to, jak świat zmienił się w ciągu ostatnich ośmiu lat.
Urządzenia mobilne i natywne aplikacje są dziś powszechne w sposób, którego SAML nie mógł przewidzieć w 2005 roku.
Podstawowymi graczami OAuth2 są:
SAML i OAuth2 używają podobnych terminów dla podobnych koncepcji. Dla porównania formalny termin OAuth2 jest wymieniony z odpowiednikiem SAML w nawiasie.
-
Serwer zasobów (Service Provider) – jest to serwer sieciowy, na którym użytkownik próbuje uzyskać dostęp do informacji.
-
Klient – jest to sposób, w jaki użytkownik wchodzi w interakcję z serwerem zasobów. Może to być aplikacja internetowa oparta na przeglądarce, natywna aplikacja mobilna, aplikacja desktopowa, aplikacja po stronie serwera.
-
Serwer autoryzacyjny (Identity Provider) – jest to serwer, który jest właścicielem tożsamości i poświadczeń użytkownika. To z nim użytkownik tak naprawdę uwierzytelnia się i autoryzuje.
Na wysokim poziomie, przepływ OAuth2 nie różni się tak bardzo od wcześniejszego przepływu SAML:
Przejdźmy przez ten sam scenariusz, przez który przeszliśmy wcześniej z SAML:
-
A – użytkownik otwiera swoją przeglądarkę internetową i przechodzi do MyPhotos.com, która przechowuje wszystkie jego zdjęcia. MyPhotos.com nie obsługuje uwierzytelniania, więc użytkownik jest przekierowywany do serwera autoryzacji z prośbą o autoryzację. Użytkownik otrzymuje formularz logowania i jest pytany, czy chce zatwierdzić serwer zasobów (MyPhotos.com) do działania w jego imieniu. Użytkownik loguje się i zostaje przekierowany z powrotem na stronę MyPhotos.com.
-
B – klient otrzymuje kod przyznania autoryzacji jako część przekierowania, a następnie przekazuje go klientowi.
-
C – Klient następnie używa tego kodu autoryzacji do zażądania tokena dostępu od serwera autoryzacji.
-
D – jeśli kod autoryzacji jest prawidłowy, serwer autoryzacji przyznaje token dostępu. Token dostępu jest następnie używany przez klienta do żądania zasobów od serwera zasobów (MyPhotos.com).
-
E – MyPhotos.com odbiera żądanie zasobu i otrzymuje token dostępu. Aby upewnić się, że jest to prawidłowy token dostępu, wysyła token bezpośrednio do serwera autoryzacji w celu sprawdzenia jego poprawności. Jeśli jest poprawny, serwer autoryzacji odsyła informacje o użytkowniku.
-
F – po zatwierdzeniu żądania użytkownika MyPhotos.com odsyła żądany zasób do użytkownika.
To jest najbardziej powszechny przepływ OAuth2: przepływ kodu autoryzacji. OAuth2 zapewnia trzy inne przepływy (lub to, co nazywają dotacjami autoryzacji), które działają dla nieco innych scenariuszy, takich jak aplikacje javascript na jedną stronę, natywne aplikacje mobilne, natywne aplikacje desktopowe, tradycyjne aplikacje internetowe i aplikacje po stronie serwera, w których użytkownik nie jest bezpośrednio zaangażowany, ale udzielił ci pozwolenia na zrobienie czegoś w ich imieniu.
Dużą zaletą przepływów OAuth2 jest to, że komunikacja z serwera autoryzacji z powrotem do klienta i serwera zasobów odbywa się za pośrednictwem przekierowań HTTP z informacjami o tokenie dostarczonymi jako parametry zapytania. OAuth2 nie zakłada również, że klient jest przeglądarką internetową, podczas gdy domyślny profil SAML Web Browser SSO Profile robi.
Natywne aplikacje mobilne będą po prostu działać po wyjęciu z pudełka. Nie ma potrzeby stosowania żadnych obejść.
Ulubiony frazes OAuth2: Out of Scope
Specyfikacja OAuth2 nie określa, jak działa komunikacja między serwerem zasobów a serwerem autoryzacji w wielu sytuacjach, takich jak walidacja tokena. Nie mówi też nic o tym, jakie informacje powinny być zwracane o użytkowniku lub w jakim formacie.
Jest sporo miejsc, w których specyfikacja OAuth2 stwierdza, że rzeczy są „poza zakresem tej specyfikacji.” To przyniosło krytykę OAuth2 spec, ponieważ pozostawia wiele rzeczy do wdrożenia, co może prowadzić do niekompatybilnych implementacji w pewnym momencie.
OAuth2, jest wciąż bardzo młody, a już ma szerokie przyjęcie z takich jak Google, Facebook, Salesforce, i Twitter, aby wymienić tylko kilka. Prawdziwym pięknem OAuth2 jest jednak jego prostota. W rzeczywistości, Podstawowy Profil OpenID Connect, który bazuje na OAuth2 wypełnia niektóre z obszarów, których sam specyfik OAuth2 nie definiuje.
OAuth2: Not Requiring Digital Signatures By Default
OAuth2 nie wymaga domyślnie podpisywania wiadomości. Jeśli chcesz to dodać, nie krępuj się, ale po wyjęciu z pudełka spec działa bez tego. Przepisuje, że wszystkie żądania powinny być wykonywane przez SSL/TLS.
To spowodowało zamieszanie w przeszłości:
- OAuth 2.0 (bez podpisów) jest zły dla sieci
- OAuth 2.0 and the Road to Hell
Pracując z OAuth2 i OAuth1 w przeszłości, mogę powiedzieć, że OAuth2 jest znacznie prostszy niż OAuth1 (i przyjemniejszy w pracy). Interoperacyjność i automatyczne odkrywanie usług może być czymś użytecznym w przyszłości, ale w tej chwili nie jest to coś, czego szukamy.
Możemy zostać poproszeni o podpisywanie wiadomości, gdy zespół bezpieczeństwa przedsiębiorstwa przeprowadzi ostateczny audyt implementacji OAuth2, ale na razie OAuth2 pasuje do naszych obecnych celów w bardziej standardowy sposób niż SAML. Jest też o wiele prostszy.
Jeśli każda aplikacja ma zabezpieczony serwer WWW, wtedy podpisywanie działa świetnie, ale kiedy tak nie jest, problem staje się bardziej złożony. Jak bezpiecznie przechowywać klucze w przeglądarce dla aplikacji JS opartych na przeglądarce lub w natywnych aplikacjach mobilnych?
Jeśli google dekompiluje aplikacje na iOS i Androida, twoje serce zatonie. Twoje klucze naprawdę nie są tak bezpieczne, jeśli nie możesz posiadać i zabezpieczyć urządzenia.
OAuth2 jest dla Autoryzacji, nie Uwierzytelniania
„auth” w OAuth oznacza „Autoryzację”, a nie „Uwierzytelnianie”. Pedant w tobie może się uśmiechać. Masz mnie!
Ale – tak, zawsze jest jakieś ale! Nawet jeśli termin OAuth jest dość niedawny, fakt, że „auth” oznaczał autoryzację wydaje się nieco anachroniczny. Jest on już używany do osiągnięcia SSO na wolności (dzięki takim firmom jak Facebook, Twitter, Salesforce i Google oraz tysiącom stron używających ich do uwierzytelniania i autoryzacji użytkowników).
Największą skargą, jaką widziałem, jest brak recepty i obfitość zastosowań „poza zakresem” w specyfikacji OAuth2. Fakt, że podstawowy profil OpenID Connect jest zbudowany bezpośrednio na OAuth2 powinien być wystarczający do obalenia mitu, że OAuth2 nie może być używany do uwierzytelniania.
To, co słowo oznaczało sześć lat temu, jest znacznie mniej ważne niż to, co może obejmować dzisiaj.
Podsumowanie
SAML ma jedną cechę, której brakuje OAuth2: token SAML zawiera informacje o tożsamości użytkownika (z powodu podpisywania). W OAuth2 nie otrzymujemy tego po wyjęciu z pudełka, a zamiast tego Serwer Zasobów musi wykonać dodatkową podróż w obie strony, aby zatwierdzić token z Serwerem Autoryzacji.
Z drugiej strony, w OAuth2 można unieważnić token dostępu na Serwerze Autoryzacji i wyłączyć go z dalszego dostępu do Serwera Zasobów.
Oba podejścia mają fajne cechy i oba będą działać dla SSO. Sprawdziliśmy obie koncepcje w wielu językach i różnych rodzajach aplikacji. Na koniec dnia OAuth2 wydaje się być lepszym rozwiązaniem dla naszych potrzeb (ponieważ nie mamy istniejącej infrastruktury SAML, którą moglibyśmy wykorzystać).
OAuth2 zapewnia prostsze i bardziej ustandaryzowane rozwiązanie, które obejmuje wszystkie nasze obecne potrzeby i pozwala uniknąć stosowania obejść dla interoperacyjności z natywnymi aplikacjami.
Jak to się zacznie rozwijać i będziemy współpracować z różnymi zespołami bezpieczeństwa, zobaczymy, jak daleko to się utrzyma.
Jak na razie jest dobrze.