Mechanizm pojedynczego uwierzytelnienia, czyli Single Sign-On
Mechanizm pojedynczego uwierzytelnienia – czyli Single Sign-On, w skrócie SSO – to obszerny temat. Wyobraźmy sobie, że udostępniamy użytkownikom wiele odrębnych aplikacji, z których każda wymaga uwierzytelnienia. Czy nie byłoby dobrze, gdyby dało się używać ich wszystkich podając swój identyfikator i hasło (albo inne dane uwierzytelniające) tylko jednokrotnie? Z pewnością wygodniej niż gdybyśmy mieli to robić dla każdej aplikacji z osobna.
W dzisiejszym artykule opiszę swą wizję SSO dla środowiska złożonego z aplikacji WWW. SSO nie żyje jednak w próżni i same dla siebie, przeciwnie, jest częścią ogólnej architektury bezpieczeństwa dla systemów klasy korporacyjnej (ang. enterprise). Przynajmniej ja tak to widzę i tak też o SSO będę pisał. Zacznijmy od spojrzenia na poniższy diagram ilustrujący proces uwierzytelnienia i pokazujący kluczowe komponenty.

Na szczególną uwagę zasługuje komponent nazwany na powyższym diagramie serwerem bezpieczeństwa. Otóż mój pomysł na implementacje kompleksowego systemu bezpieczeństwa dla przedsiębiorstwa polega na tym, że wszystkie decyzje dotyczące bezpieczeństwa, tj. autoryzacja i uwierzytelnienie podejmowane są przez wyspecjalizowany komponent/serwer, nie przez każdą z aplikacji z osobna. Nie jest więc tak, że na potrzeby autoryzacji aplikacje pobierają listę ról przypisanych do bieżącej tożsamości i konfrontują tą listę z rolami przypisanymi do danego zasobu. Aplikacje wysyłają do serwera bezpieczeństwa zapytanie autoryzacyjne podając identyfikatory zasobów i identyfikator kontekstu a to serwer podejmuje decyzje na podstawie sobie tylko znanych kryteriów. Przede wszystkim, nie wydaje mi się być dobrym pomysłem zaszywanie w aplikacji informacji o związku zasobów z rolami. Ale jest to dyskusja na oddzielny artykuł. Wróćmy do SSO.
Filtr weryfikacji tożsamości to filtr servletowy, który sprawdza czy w żądaniu HTTP zostało przekazane ciasteczko o odpowiedniej nazwie. Jeśli ciasteczko jest dostępne to pobiera z niego identyfikator kontekstu bezpieczeństwa i przekazuje go do aplikacji, np. jako atrybut żądania HTTP (ang. HTTP request). Ewentualnie, filtr może uprzednio wywołać funkcję weryfikacji identyfikatora udostępnianą przez serwer bezpieczeństwa. Aplikacja (a dokładnie jej moduł autoryzacji) wysyła do serwera bezpieczeństwa zapytanie o autoryzację dostępu dla żądanego zasobu i identyfikatora kontekstu. Na podstawie wyniku podejmuje odpowiednie kroki – zwraca żądany zasób lub komunikat błędu. Serwer bezpieczeństwa pobiera z kontekstu dane o uwierzytelnionej tożsamości i przypisanych jej rolach. Zasoby opisane są odpowiednimi identyfikatorami. Jeśli role przypisane do uwierzytelnionej tożsamości zezwalają na uzyskanie dostępu do opisanego zasobu serwer udziela odpowiedzi pozytywnej. Oczywiście, jeśli przekazany do serwera bezpieczeństwa identyfikator kontekstu nie identyfikuje poprawnie żadnego kontekstu zwracany jest komunikat błędu. Serwer bezpieczeństwa może również odpowiedzieć, że użytkownik ma prawo do uzyskania dostępu, ale pod jakimś określonym warunkiem, np. podania poprawnego hasła jednorazowego.
Jeśli filtr weryfikacji tożsamości nie znajdzie w żądaniu odpowiedniego ciasteczka HTTP, to uruchomiona zostaje procedura uwierzytelniania. Rozpoczyna się ona przekierowaniem do aplikacji uwierzytelniającej. Żądania skierowane do tej aplikacji są filtrowane przez kolejny filtr servletowy – filtr uwierzytelniający. To właśnie ten filtr wykonuje główną pracę. Sprawdza on, czy w żądaniu HTTP znajdują się odpowiednie parametry, tj. identyfikator użytkownika i hasło. Jeśli tak, to są one weryfikowane, jeśli nie, to żądanie jest przekazywane do aplikacji uwierzytelniającej – wyświetlana jest w przeglądarce strona z formularzem uwierzytelniania. Po wypełnieniu i wysłaniu formularza żądanie znowu trafia do filtra. Identyfikator użytkownika i hasło są weryfikowane z użyciem serwera bezpieczeństwa. Poprawna weryfikacja powoduje utworzenie na tym serwerze kontekstu (sesji) bezpieczeństwa. Odsyłany jest identyfikator tego kontekstu. Filtr uwierzytelniający przekierowuje z powrotem do oryginalnie żądanego zasobu ustawiając jednocześnie ciasteczko z identyfikatorem utworzonego kontekstu. Od tej pory filtr weryfikacji tożsamości, niezależnie od tego, jaką aplikację zabezpiecza będzie posiadał prawidłowe informacje o uwierzytelnionym użytkowniku. Tym oto sposobem otrzymujemy efekt uwierzytelnienia do pracy z przeglądarką, niezależnie od tego, jaką aplikację w tej przeglądarce aktualnie użytkujemy – oczywiście pod warunkiem, że wszystkie one używają tej samej infrastruktury bezpieczeństwa. Implementacja opisanych tu mechanizmów już wkrótce – oczywiście, jak nie zabraknie czasu i zapału.