Jak zbudować własny system SSO w firmie z użyciem popularnych frameworków

1
54
Rate this post

Nawigacja:

Cel wdrożenia firmowego SSO

Intencją wdrożenia systemu Single Sign-On w firmie jest centralne zarządzanie tożsamością, ograniczenie liczby haseł oraz ujednolicenie logowania do wszystkich aplikacji biznesowych.

Drugi cel to uporządkowanie bezpieczeństwa: spójne polityki haseł, MFA, blokady kont oraz centralny audyt logowań, zamiast rozproszonych, różniących się mechanizmów w każdej aplikacji.

Czym jest SSO i kiedy warto je wdrożyć

Definicja SSO w praktyce firmowej

Single Sign-On to mechanizm, w którym użytkownik loguje się raz do centralnego dostawcy tożsamości, a następnie może korzystać z wielu aplikacji bez ponownego podawania loginu i hasła.

W klasycznym scenariuszu firmowym masz kilka paneli administracyjnych, narzędzie CRM, system HR, kilka usług intranetowych oraz panel dla klientów. Bez SSO każdy system trzyma osobną bazę użytkowników i osobne sesje.

Po wdrożeniu centralnego SSO użytkownik przechodzi proces logowania w jednym miejscu (IdP – Identity Provider), a aplikacje tylko ufają informacjom z IdP i nie implementują już własnego formularza logowania.

SSO vs federacja tożsamości vs „wspólna baza”

SSO bywa mylone z kilkoma pokrewnymi pojęciami, które wymagają rozróżnienia.

Wspólna baza użytkowników oznacza, że kilka aplikacji korzysta z tego samego magazynu (np. wspólnej tabeli users w bazie SQL), ale każda nadal implementuje logowanie lokalnie. To nie jest SSO, bo użytkownik i tak podaje dane logowania w każdej aplikacji osobno.

Federacja tożsamości opisuje relację między zewnętrznymi podmiotami, np. Twoja aplikacja SaaS ufa zewnętrznemu IdP klienta (Azure AD, Google Workspace, ADFS). Każda strona zarządza swoimi użytkownikami, a połączenie odbywa się przez standardy typu SAML albo OpenID Connect.

SSO w firmie oznacza zwykle wewnętrzny IdP, który obsługuje logowanie dla wszystkich Twoich aplikacji. Może jednocześnie pełnić rolę punktu federacji wobec innych IdP (np. logowanie służbowym kontem Google).

Typowe scenariusze użycia SSO w organizacji

SSO jest szczególnie sensowne, gdy:

  • pracownicy korzystają z wielu aplikacji webowych w ciągu dnia (panel HR, czas pracy, CRM, helpdesk, wiki),
  • rozwijasz system w architekturze mikroserwisów i masz wiele osobnych frontendów/back-endów,
  • firma ma kilka marek / produktów, ale jedną bazę użytkowników (np. kilka portali dla klientów),
  • chcesz wymusić spójną politykę bezpieczeństwa: MFA, długość haseł, rotacja, blokady.

Mała firma z jedną aplikacją webową rzadko potrzebuje rozbudowanego SSO. Przy dwóch, trzech systemach da się jeszcze funkcjonować. Gdy w organizacji pojawia się kilkanaście aplikacji, a użytkownicy zaczynają gubić hasła, SSO szybko staje się realną oszczędnością czasu i nerwów.

Korzyści biznesowe i koszty wdrożenia

Korzyści UX: mniej logowań, mniej resetów haseł, szybszy dostęp do narzędzi. Dla użytkownika logowanie do jednej aplikacji oznacza dostęp także do pozostałych, o ile ma nadane uprawnienia.

Korzyści bezpieczeństwa: centralne wymuszanie MFA, blokada konta w jednym miejscu blokuje dostęp do wszystkich systemów, spójne logi audytowe, mniejsza powierzchnia do błędów w każdej aplikacji z osobna.

Koszty: złożoność architektoniczna, integracja istniejących aplikacji, konieczność podniesienia kompetencji zespołu w obszarze OAuth2/OIDC lub SAML, dodatkowy element infrastruktury (IdP) do monitorowania i utrzymania.

W praktyce wdrożenie firmowego single sign-on wymusza porządki: ujednolicenie kont, usunięcie dublujących się użytkowników, ustalenie, kto zarządza dostępami. Ten wysiłek organizacyjny jest często większy niż sama konfiguracja narzędzi.

Podstawowe standardy: OAuth2, OpenID Connect, SAML – co wybrać

Rola OAuth2 i OpenID Connect

OAuth2 to protokół autoryzacji. W pierwotnym założeniu służył do nadawania aplikacji trzeciej uprawnień do działania w imieniu użytkownika (np. „połącz z Google i pobierz kontakty”). Nie definiuje, jak jednoznacznie identyfikować użytkownika.

OpenID Connect (OIDC) to warstwa zbudowana na OAuth2, która dodaje uwierzytelnianie. Definiuje standardowy ID Token (zwykle JWT) opisujący użytkownika: jego identyfikator, dane profilowe, czas ważności sesji itp.

W kontekście firmowego SSO bezpiecznym wyborem jest użycie OpenID Connect + OAuth2. OAuth2 zapewnia mechanizmy autoryzacji i wydawania tokenów dostępu (access token), a OIDC dodaje ID Token z informacjami o użytkowniku, z których korzystają aplikacje.

Gdzie nadal używany jest SAML

SAML (Security Assertion Markup Language) to starszy standard, mocno obecny w dużych środowiskach korporacyjnych, integracjach z systemami HR/AD i rozwiązaniach typu „logowanie domenowe”.

Typowe zastosowania:

  • integracja z Active Directory / ADFS w starszych firmach,
  • połączenia B2B między korporacjami (np. klient chce logować się swoim IdP SAML do Twojej aplikacji SaaS),
  • duże systemy legacy obsługujące tylko SAML.

Dla nowych, zielonopolowych wdrożeń single sign-on sensownie jest postawić na OpenID Connect, a SAML traktować jako „most” do starszych systemów, jeśli to konieczne. Wiele IdP (np. Keycloak) obsługuje oba standardy równolegle.

Kryteria wyboru standardu SSO

Wybór protokołu powinien zależeć od kilku czynników technicznych:

  • Typ aplikacji: nowoczesne SPA (React, Angular, Vue) + API – najlepiej OIDC; aplikacje legacy .NET/Java, które już integrują się z SAML – pozostanie przy SAML lub tryb mieszany.
  • Środowisko: chmura, mikroserwisy, kontenery – OIDC; mocno on‑prem, domenowe logowanie Windows, stare IdP – SAML bywa łatwiejszy.
  • Integracje z zewnętrznymi IdP: zdecydowana większość nowoczesnych usług (Auth0, Okta, Azure AD) preferuje OIDC, ale korporacje nadal często wymagają SAML.

Kiedy budujesz nowy system SSO w firmie, bazowy wybór to: OAuth2 + OpenID Connect jako standard podstawowy, z ewentualnym wsparciem SAML przez kompatybilne narzędzie (np. Keycloak lub komercyjny IdP) w ramach integracji zewnętrznych.

Przykładowa macierz decyzji dla różnych typów firm

ScenariuszRekomendowany standardUwagi
Mała firma SaaS (nowy produkt, SPA + API)OAuth2 + OpenID ConnectPostaw na prosty IdP z OIDC, brak potrzeby SAML na starcie.
Średnia firma on‑prem z kilkoma aplikacjami webOpenID Connect (podstawowo), SAML (opcjonalnie)IdP obsługujący oba; OIDC dla nowych aplikacji, SAML dla legacy/ADFS.
Duża korporacja z rozbudowanym AD i systemami HRSAML + OpenID ConnectSAML do integracji z istniejącą infrastrukturą, OIDC dla nowych mikroserwisów i SPA.

Architektura firmowego SSO – komponenty i przepływy

Centralny dostawca tożsamości i aplikacje klienckie

Serce systemu SSO stanowi Identity Provider (IdP). To tutaj użytkownik podaje login i hasło, tu odbywa się MFA, tu też zapada decyzja o tym, czy jest aktywny i do jakich aplikacji ma dostęp.

Każda aplikacja (panel webowy, API, SPA) traktowana jest jako klient (OAuth client / Relying Party). Zamiast samodzielnie weryfikować użytkownika, przekierowuje go do IdP i po powrocie otrzymuje tokeny.

Typowy zestaw tokenów w firmowym SSO opartym na OIDC:

  • ID Token – informacja o tożsamości użytkownika (sub, email, name, role itp.),
  • Access Token – uprawnienia do wywoływania API,
  • Refresh Token – służy do odświeżania wygasających tokenów bez ponownego logowania.

Bezpieczne przepływy: Authorization Code + PKCE

OAuth2 definiuje kilka typów przepływów (grantów). W kontekście firmowego single sign-on i nowoczesnych aplikacji webowych dzisiaj w praktyce stosuje się:

  • Authorization Code Flow + PKCE – dla SPA i aplikacji publicznych,
  • Authorization Code Flow (bez PKCE lub z PKCE) – dla aplikacji backendowych,
  • Client Credentials – dla komunikacji serwer‑serwer (bez użytkownika).

Implicit Flow, kiedyś popularny w SPA, obecnie jest uznawany za przestarzały i niezalecany ze względów bezpieczeństwa. W nowym wdrożeniu single sign-on w firmie nie powinien być używany.

PKCE (Proof Key for Code Exchange) zabezpiecza przepływ Authorization Code w aplikacjach, które nie mogą bezpiecznie przechowywać sekretu (np. przeglądarka lub aplikacja mobilna). Mechanizm polega na powiązaniu zapytania o kod autoryzacyjny z dalszym etapem wymiany na token, przy użyciu tymczasowego code verifier i code challenge.

Sesja użytkownika: gdzie powinna być utrzymywana

W architekturze SSO trzeba zadecydować, gdzie jest utrzymywana sesja użytkownika w sensie „jest zalogowany / nie jest zalogowany”.

Model centralnej sesji w IdP: IdP zarządza sesją użytkownika poprzez cookie HttpOnly na swojej domenie (np. idp.firma.local). Po zalogowaniu się w IdP użytkownik będzie automatycznie rozpoznawany przy kolejnych próbach logowania z innych aplikacji i nie zobaczy ponownie formularza logowania.

Aplikacje klienckie utrzymują jedynie stan lokalny (tokeny). Gdy token access wygasa, SPA lub backend może użyć refresh tokena albo ponownie przekierować do IdP, gdzie użytkownik jest już zalogowany centralnie.

Model, w którym każda aplikacja trzyma własną sesję w cookie i niezależnie zarządza logowaniem, nie daje pełnego SSO – to powrót do wspólnej bazy użytkowników, a nie prawdziwego single sign-on.

Wysokopoziomowy schemat przepływu SSO

Opisowo, dla użytkownika korzystającego z aplikacji A i B:

  1. Użytkownik otwiera appA.firma.local.
  2. Aplikacja A wykrywa brak tokena / sesji i przekierowuje do IdP (idp.firma.local) z parametrami OAuth2/OIDC.
  3. Jeśli użytkownik nie ma jeszcze sesji w IdP, widzi formularz logowania; po zalogowaniu IdP ustawia cookie sesyjne.
  4. IdP przekierowuje użytkownika z powrotem do aplikacji A z kodem autoryzacyjnym.
  5. Aplikacja A (lub jej backend) wymienia kod na tokeny (ID Token + Access Token, opcjonalnie Refresh Token).
  6. Użytkownik pracuje w aplikacji A. Po chwili przechodzi do appB.firma.local.
  7. Aplikacja B też przekierowuje do IdP, ale IdP widzi już aktywną sesję (cookie) i od razu odsyła kod autoryzacyjny bez ponownego logowania.
  8. Aplikacja B wymienia kod na tokeny – użytkownik jest zalogowany także w aplikacji B.

Taki schemat działa zarówno w prostych środowiskach on‑premise, jak i w rozproszonych mikroserwisach w chmurze, o ile komunikacja z IdP jest odpowiednio zabezpieczona (HTTPS, poprawne CORS, właściwe domeny i cookie).

Ekran komputera z komunikatem błędu logowania w systemie uwierzytelniania
Źródło: Pexels | Autor: Markus Spiske

Wybór i porównanie popularnych rozwiązań SSO

Najpopularniejsze serwery tożsamości open source

Budując system SSO w firmie, można skorzystać z gotowych serwerów tożsamości. Kilka najczęściej spotykanych projektów open source:

  • Keycloak – rozbudowany IdP, obsługuje OAuth2/OIDC, SAML, integrację z LDAP/AD, MFA, grupy, role, polityki, panel administracyjny. Dobrze pasuje zarówno on‑prem, jak i w kontenerach.
  • Authentik – nowoczesny, stosunkowo lekki IdP, przyjazny do środowisk domowych i małych/średnich firm, wspiera OIDC, SAML, reverse proxy.
  • Ory Hydra / Ory Kratos – zestaw komponentów do budowania złożonych systemów tożsamości, mocny nacisk na architekturę cloud‑native i mikroserwisy.
  • Dex – prosty IdP, często używany w środowiskach Kubernetes do integracji logowania (np. do panelu Kubernetes Dashboard).
  • IdentityServer (obecnie Duende IdentityServer w modelu komercyjnym) – popularny w ekosystemie .NET.

Do wewnętrznego single sign-on w firmie w większości przypadków na starcie wystarczy Keycloak lub Authentik. Dają one wszystkie kluczowe funkcje: logowanie, tokeny, integrację z katalogiem użytkowników i dobry panel konfiguracyjny.

IdP zarządzane samodzielnie vs usługa w chmurze

Przy wyborze rozwiązania SSO trzeba zdecydować, gdzie będzie działał IdP: lokalnie, w prywatnej chmurze czy jako usługa SaaS.

Samodzielnie zarządzany IdP (on‑prem / własny Kubernetes):

  • pełna kontrola nad danymi i konfiguracją,
  • łatwiejsza integracja z wewnętrznymi systemami (AD, LDAP, HR, CRM),
  • większa odpowiedzialność: SLA, backup, aktualizacje bezpieczeństwa, HA.

IdP jako usługa (Auth0, Okta, Azure AD B2C itp.):

  • mniej pracy operacyjnej, gotowe integracje i szablony,
  • łatwiejsza obsługa federacji z zewnętrznymi partnerami,
  • ograniczenia w customizacji i zależność od dostawcy.

W małej firmie SaaS często opłaca się zacząć od usługi w chmurze. W organizacjach z silnymi wymaganiami compliance (dane w konkretnym kraju, brak danych w chmurze publicznej) częściej wybierany jest własny IdP typu Keycloak.

Porównanie wybranych rozwiązań SSO

RozwiązanieModelMocne stronyPotencjalne ograniczenia
KeycloakOpen source, self‑hostedBogate funkcje, OIDC+SAML, integracja z LDAP/AD, dobra administracjaWymaga opieki DevOps, złożone klastry w dużej skali
AuthentikOpen source, self‑hostedProstszy niż Keycloak, nowoczesny interfejs, reverse proxyMniej „enterprise” funkcji niż Keycloak
Duende IdentityServerKomercyjny, self‑hosted (.NET)Naturalna integracja z ASP.NET Core, duża elastycznośćLicencjonowanie, głównie ekosystem .NET
Auth0SaaSSzybki start, dobre SDK, reguły JavaScript, integracje społecznościoweKoszty przy dużej skali, lock‑in, ograniczenia w customizacji
OktaSaaSSilne funkcje enterprise, integracja z HR, MFA, lifecycle użytkownikówSkupienie na segmencie korporacyjnym, koszt
Azure AD / Entra IDSaaS / hybrydaDobra integracja z Microsoft 365, AD, polityki dostępu warunkowegoNajwygodniejszy głównie przy silnym „stacku” Microsoft

Typowe kryteria wyboru rozwiązania IdP

Przy porównywaniu konkretnych narzędzi warto mieć prostą listę kryteriów. W praktyce najczęściej przewijają się:

  • Obsługiwane protokoły: OIDC, OAuth2, SAML, ewentualnie WS‑Fed.
  • Integracja z katalogami: AD, LDAP, SCIM, import z HR.
  • MFA i polityki haseł: TOTP, WebAuthn, SMS, reguły siły hasła.
  • Delegacja uprawnień: admini domen, właściciele aplikacji, samoobsługa użytkownika.
  • Elastyczność tokenów: możliwość dodawania claimów, mapowania grup/atrybutów.
  • Skalowanie i HA: klastry, replikacja, wsparcie dla kontenerów.
  • Model licencjonowania: koszty roczne, ograniczenia użytkowników/aplikacji.

W mniejszym środowisku lepiej wybrać prostsze narzędzie, niż budować nadmiernie skomplikowany klaster, którego nikt realnie nie utrzyma.

Projekt modelu tożsamości i ról w firmowym SSO

Tożsamość użytkownika: minimalny zestaw atrybutów

IdP musi mieć model użytkownika, który wystarczy do wszystkich aplikacji. Lepiej zacząć od wąskiego zestawu pól i rozszerzać go, niż od razu kopiować cały schemat z systemu HR.

Typowy zestaw atrybutów:

  • unikalny identyfikator (np. userId lub sub),
  • login (np. e‑mail firmowy),
  • imię, nazwisko,
  • adres e‑mail,
  • stan konta (aktywny/zablokowany),
  • lista ról/grup,
  • opcjonalnie: dział, lokalizacja, identyfikator z systemu HR.

Dobrą praktyką jest traktowanie sub (subject) jako niemutowalnego identyfikatora technicznego, a login/emails jako dane zmienne, które można zmienić bez utraty historii.

Role, grupy, uprawnienia – poziomy abstrakcji

W modelu uprawnień warto rozdzielić trzy poziomy:

  • Grupy organizacyjne (np. „Dział sprzedaży”, „IT”, „Zarząd”),
  • Role aplikacyjne (np. appA_admin, appA_user),
  • Uprawnienia szczegółowe (np. can_view_reports, can_approve_payments) – często już po stronie aplikacji.

IdP nie musi znać wszystkich detali uprawnień biznesowych. Zwykle wystarczy, że prześle do aplikacji zestaw ról/grup, na podstawie których backend zdecyduje, co jest dozwolone.

Centralne role vs role definiowane per aplikacja

W małej firmie role można utrzymać centralnie i mapować je do kilku aplikacji. Przy większej skali praktyczniejsze jest podejście, w którym:

  • IdP trzyma rolę z prefiksem aplikacji (np. appB_report_viewer),
  • każda aplikacja zna tylko swoje role i ignoruje obce.

Ułatwia to delegowanie zarządzania uprawnieniami do właścicieli konkretnych systemów. Administrator SSO odpowiada wtedy za spójność katalogu, ale nie musi znać detali dostępu w każdym narzędziu.

Źródło prawdy o użytkownikach

Nawet jeśli IdP trzyma użytkowników lokalnie, w większych firmach pojawia się „system źródłowy” (HR, Active Directory). Nie warto mieć dwóch równorzędnych miejsc, gdzie tworzy się użytkowników.

Najczęstsze wzorce:

  • AD/LDAP jako główne źródło, IdP tylko synchronizuje grupy i identyfikatory,
  • system HR jako źródło, a AD/IdP przejmują konta dopiero przy zatrudnieniu pracownika,
  • czysty IdP jako źródło (częste w małych SaaS bez skomplikowanego HR).

W praktyce kluczowe jest powiązanie cyklu życia konta z cyklem życia w firmie: zatrudnienie, zmiana działu, odejście. SSO musi reagować na te zmiany automatycznie (dezaktywacja konta, aktualizacja ról).

Tokeny jako nośnik tożsamości

Model tożsamości i ról przekładamy na strukturę tokenów:

  • w ID Token lądują dane potrzebne interfejsowi (imię, nazwisko, e‑mail),
  • w Access Token – identyfikator użytkownika, role, grupy, ewentualne atrybuty potrzebne API,
  • w Refresh Token – tylko identyfikator sesji i referencje, bez danych biznesowych.

Nie ma sensu pakować pełnego profilu użytkownika w każdy Access Token. Po stronie API wygodniejsze jest odczytywanie najważniejszych claimów, a resztę – w razie potrzeby – pobierać z dedykowanego serwisu użytkowników.

Implementacja IdP na bazie popularnych frameworków backendowych

Budowa własnego IdP vs konfiguracja gotowego

IdP można zbudować samodzielnie, używając bibliotek OAuth2/OIDC, albo skonfigurować gotowy serwer (np. Keycloak). W większości projektów biznesowych lepiej ograniczyć „kod własny” do integracji i UI niż pisać pełny protokół.

Wyjątki to specyficzne wymagania bezpieczeństwa, bardzo niskopoziomowe integracje lub produkt, który sam w sobie jest IdP dla klientów.

Przykład: ekosystem Java / Spring

W świecie Javy standardowym wyborem jest Spring Security + Spring Authorization Server lub integracja z zewnętrznym IdP.

  • Spring Authorization Server – biblioteka do budowy własnego serwera autoryzacji/OIDC,
  • Spring Security – warstwa bezpieczeństwa w aplikacjach klienckich (Resource Server, OAuth2 Client).

Prosty szkic kroku po kroku przy własnym IdP w Springu:

  1. Tworzysz aplikację Spring Boot z zależnością spring-authorization-server.
  2. Konfigurujesz rejestr klientów (clientId, redirect URI, typy grantów).
  3. Dodajesz endpointy logowania i formularz UI (lub korzystasz z domyślnego).
  4. Definiujesz user details service (np. z bazy danych lub LDAP).
  5. Konfigurujesz wydawanie tokenów (scopes, claimy, podpisywanie JWT).

W praktyce wiele zespołów woli jednak użyć Keycloak i w Springu skonfigurować jedynie spring-boot-starter-oauth2-client oraz spring-boot-starter-oauth2-resource-server.

Przykład: .NET / ASP.NET Core

W .NET naturalnym wyborem jest Duende IdentityServer jako IdP oraz ASP.NET Core Authentication/Authorization w aplikacjach klienckich.

Typowa konfiguracja IdP opiera się na:

  • definicji API (scopes),
  • rejestracji klientów (confidential/public, redirect URIs, granty),
  • implementacji user store (Entity Framework, LDAP, custom),
  • konfiguracji profilu użytkownika (profile service, dodatkowe claimy).

Jeśli firma i tak korzysta z Azure AD, częściej IdP jest „na zewnątrz”, a aplikacje .NET są tylko klientami OIDC, bez własnego serwera autoryzacji.

Przykład: Node.js (NestJS / Express / Fastify)

W ekosystemie Node częściej stosuje się gotowy IdP (np. Keycloak, Auth0), a backend występuje jako klient i resource server. Do integracji przydają się biblioteki:

  • passport + passport-openidconnect / passport-oauth2,
  • oidc-provider – jeśli jednak trzeba zbudować IdP w Node,
  • express-jwt / @fastify/jwt – walidacja tokenów w API.

Dobry kompromis to: IdP jako osobna usługa (np. Keycloak), Node.js tylko sprawdza podpis tokenu i role w claimach.

Przykład: Python (Django / FastAPI)

W Pythonie również rzadko buduje się pełny IdP od zera. Częściej:

  • używa się mozilla-django-oidc lub podobnych pakietów w Django jako klienta OIDC,
  • w FastAPI stosuje się python-jose lub authlib do walidacji JWT,
  • IdP pozostaje „na zewnątrz” (Keycloak, Auth0, Okta).

Jeśli mimo to trzeba zaimplementować IdP w Pythonie, authlib zapewnia klocki do protokołów OAuth2/OIDC, ale pełna implementacja to sporo pracy i testów bezpieczeństwa.

Integracja IdP z katalogiem użytkowników

Bez względu na wybrany framework, IdP musi „wiedzieć”, skąd brać użytkowników. Najczęściej:

  • logowanie hasłem: własna baza użytkowników lub LDAP/AD,
  • logowanie jednokrotne z AD: Kerberos/NTLM (np. ADFS, Azure AD Connect),
  • federacja: OIDC/SAML do zewnętrznych IdP (partnerzy, klientów).

Dla klasycznego wdrożenia firmowego dobrym startem jest integracja IdP z Active Directory: synchronizacja użytkowników i grup oraz konfiguracja logowania z użyciem firmowego konta.

Integracja SSO z aplikacjami webowymi (backend + SPA)

Backend jako klient OIDC

Jeśli aplikacja jest serwerowa (rendering po stronie backendu), typowy wzorzec to:

  1. Użytkownik wchodzi na stronę, backend wykrywa brak sesji.
  2. Backend inicjuje Authorization Code Flow do IdP.
  3. Po powrocie kod jest wymieniany na tokeny, a backend tworzy własną sesję (cookie HttpOnly).

Tokeny można trzymać w sesji po stronie serwera lub w zaszyfrowanym cookie. Dostęp do API następuje z backendu z użyciem Access Token przechowywanego na serwerze, co zmniejsza ryzyko wycieku.

SPA + API: wzorzec z Authorization Code + PKCE

Dla aplikacji typu SPA (React, Angular, Vue) lepsza jest integracja bezpośrednio z IdP, z wykorzystaniem Authorization Code + PKCE.

Typowy scenariusz:

  1. Spa wykrywa brak sesji (brak tokena) i przekierowuje do IdP.
  2. Przechowywanie tokenów w SPA i obsługa sesji

    Przy SPA kluczowe jest, gdzie lądują tokeny. Najbezpieczniej ograniczyć ich ekspozycję w przeglądarce i nie używać localStorage ani sessionStorage do przechowywania Access Tokenów.

    Praktyczny wariant:

  • IdP ustawia SameSite=strict/lax, HttpOnly, Secure cookie sesyjne,
  • SPA utrzymuje tylko minimalny stan (np. flaga „jest zalogowany” oparta o wywołanie backendu),
  • backend posiada Access Token i działa jako pośrednik do API.

Jeśli SPA rozmawia z API bezpośrednio, lepiej trzymać Access Token w pamięci (in‑memory) i odświeżać go przy użyciu silent refresh (iframe lub prompt=none), zamiast zapisywać go trwale po stronie przeglądarki.

Wylogowanie z SSO w aplikacjach webowych

Wylogowanie w środowisku SSO ma dwa poziomy: wylogowanie z konkretnej aplikacji oraz wylogowanie globalne (ze wszystkich aplikacji korzystających z IdP).

Typowy przepływ:

  1. Użytkownik naciska „Wyloguj” w aplikacji.
  2. Aplikacja czyści swoją sesję (cookie, storage) i przekierowuje na endpoint end_session_endpoint IdP.
  3. IdP unieważnia sesję i według konfiguracji:
    • przekierowuje użytkownika do ekranu „Wylogowano”,
    • albo od razu na post logout redirect URI danej aplikacji.

Przy wylogowaniu globalnym można użyć mechanizmu front‑channel logout (iframe’y do aplikacji) lub back‑channel logout (webhooki do backendów), zależnie od możliwości IdP i aplikacji.

Obsługa odświeżania tokenów w SPA

Access Token ma krótki czas życia, więc SPA musi go cyklicznie odświeżać. Dwa częste podejścia:

  • Refresh Token Rotation – SPA posiada refresh token (najlepiej przewożony w HttpOnly cookie) i wymienia go na nowe tokeny,
  • Silent Authorization Code Flow – SPA inicjuje ukryte logowanie (iframe/popup) z prompt=none, korzystając z istniejącej sesji IdP.

Pierwszy wariant jest prostszy, ale wymaga ostrożnej konfiguracji klienta w IdP (PKCE, ograniczone zakresy, rotacja). Drugi zmniejsza ekspozycję refresh tokenów w przeglądarce kosztem większej złożoności.

Mapowanie ról z IdP na uprawnienia w aplikacji

Backend powinien ufać wyłącznie temu, co przychodzi z IdP w tokenie, a nie parametrom przesyłanym z frontu. SPA może jedynie podpowiadać UI (np. schować przycisk), ale ostateczna decyzja należy do serwera.

Prosty, utrzymywalny schemat:

  • IdP wystawia role w claimie roles lub groups, np. ["appA_admin","appA_user"],
  • backend ma prosty middleware / filtr, który mapuje role na polityki (np. ROLE_APP_A_ADMIN → „może edytować wszystko”),
  • reguły autoryzacji są lokalne dla aplikacji i nie wymagają zmian w IdP.

W dużych firmach często powstaje wspólna biblioteka do autoryzacji, dzięki której każda usługa interpretuje role i atrybuty w ten sam sposób.

Obsługa błędów i stanów brzegowych w aplikacjach webowych

Przy SSO typowe problemy to wygasłe sesje, brak uprawnień lub częściowo nieudane logowanie federacyjne.

Praktyczne zasady:

  • przy błędzie invalid_token – wymusić odświeżenie tokena lub pełne logowanie,
  • przy braku wymaganej roli – zwrócić 403 (a nie 401), żeby odróżnić brak uprawnień od braku sesji,
  • przy braku zgody użytkownika na scope (np. e‑mail) – obsłużyć błąd access_denied po stronie aplikacji, nie w IdP.

Prosty ekran z informacją „Brak dostępu” i identyfikatorem żądania bardzo ułatwia wsparcie użytkowników i analizę logów.

SSO a API, mikroserwisy i usługi wewnętrzne

API jako Resource Server

Każde API, które konsumuje tokeny z IdP, pełni rolę Resource Server. Jego zadania to:

  • walidacja podpisu i czasu życia Access Tokena,
  • sprawdzenie audiencji (aud) i issuer (iss),
  • wyciągnięcie claimów (sub, roles, scopes) i przekazanie ich do warstwy logiki.

W praktyce sprowadza się to do skonfigurowania biblioteki w frameworku (np. Spring Resource Server, ASP.NET JWT Bearer) z adresem /.well-known/openid-configuration IdP.

Delegacja uprawnień w mikroserwisach

W architekturze mikroserwisowej nie każdy serwis powinien ufać informacjom o użytkowniku z innego serwisu. Każdy z nich waliduje token samodzielnie, choć często używa tych samych kluczy (JWKS) i konfiguracji.

Model sprawdza się, gdy:

  • Access Token zawiera minimalny zestaw claimów (ID użytkownika, główne role),
  • szczegółowe decyzje (np. dostęp do konkretnego zasobu) zapadają w dedykowanym serwisie autoryzacji lub wewnątrz danego mikroserwisu,
  • mikroserwisy rozmawiają między sobą z użyciem tokenów technicznych (client credentials), a nie „przekazywania” tokenu użytkownika w głąb.

Przekazywanie tokenu użytkownika w łańcuchu wielu usług bywa potrzebne (np. do audytu), ale szybko komplikuje model uprawnień i śledzenie błędów.

Typy tokenów w środowisku usług wewnętrznych

Obok tokenów użytkownika pojawiają się tokeny techniczne. Zwykle wyróżnia się:

  • token użytkownika – reprezentuje konkretną osobę, np. do wywołań API z UI,
  • token serwisowy – reprezentuje aplikację/serwis, wydany w client credentials flow,
  • token delegowany – łączy kontekst użytkownika z serwisem (np. on‑behalf‑of).

Dobrym nawykiem jest trzymanie ich w osobnych scopes oraz rozróżnianie w logach, co ułatwia inspekcję incydentów bezpieczeństwa.

Autoryzacja w API oparta na scopes vs rolach

W API często wygodniej operować na scopes niż na rolach, zwłaszcza gdy jedno API jest używane przez wiele typów klientów.

Praktyczne podejście mieszane:

  • IdP wystawia role „biznesowe” (np. sales_manager),
  • role są mapowane na scopes API (np. sales:read, sales:write),
  • API patrzy tylko na scopes, bez znajomości pełnego modelu ról w firmie.

Mapowanie ról na scopes można utrzymywać centralnie w IdP lub w osobnym serwisie autoryzacji, jeśli konfiguracja staje się zbyt złożona.

Brama API jako centralny punkt egzekwowania SSO

W środowisku z wieloma usługami często pojawia się API Gateway (Kong, NGINX, Traefik, Apigee). To dobre miejsce na część logiki związanej z SSO.

Gateway może:

  • walidować Access Token (podpis, czas, issuer, audience),
  • odrzucać żądania bez odpowiednich scopes,
  • wzbogacać nagłówki przekazywane do usług o ID użytkownika i podstawowe role.

Mikroserwisy dzięki temu dostają już wstępnie przefiltrowany ruch. Nadal jednak powinny sprawdzać kluczowe warunki bezpieczeństwa lokalnie (np. czy użytkownik ma prawo do danego rekordu).

SSO w komunikacji wewnętrznej między usługami

Komunikacja serwis‑serwis z użyciem SSO zazwyczaj bazuje na client credentials flow. Każdy serwis posiada swój klient w IdP i uzyskuje Access Token do wywołań innych usług.

Podstawowe reguły:

  • każda usługa ma własny client_id i sekrety/klucze,
  • tokeny są krótkowieczne i pobierane na żądanie lub z lokalnej pamięci podręcznej,
  • scopes są zdefiniowane wąsko (np. orders.read zamiast admin).

Przy krytycznych operacjach można wprowadzić wzorzec „podwójnego sprawdzenia”: serwis sprawdza zarówno token techniczny, jak i kontekst użytkownika przekazany w osobnym nagłówku lub claimie.

Audit log i śledzenie żądań w środowisku SSO

Jeśli SSO ma wspierać bezpieczeństwo, logowanie zdarzeń musi obejmować nie tylko IdP, lecz także API i mikroserwisy.

Minimalny zestaw danych w logu zdarzenia:

  • unikalne ID żądania (trace ID),
  • subject użytkownika (sub) lub identyfikator klienta serwisowego,
  • scope/role użyte przy żądaniu,
  • adres usługi i operacja (np. GET /orders/{id}),
  • decyzja autoryzacji (allow/deny).

Spójne ID żądania propagowane w nagłówkach (np. X-Request-Id) pozwala prześledzić całą ścieżkę wywołań, od bramy API przez kolejne mikroserwisy, aż do bazy danych.

Tokeny wewnętrzne vs zewnętrzne

Nie zawsze ma sens używanie tego samego formatu tokenów na zewnątrz i wewnątrz organizacji. Częsta praktyka to rozdzielenie:

  • tokeny zewnętrzne – wystawiane użytkownikom, zawierające minimum danych, często JWT,
  • tokeny wewnętrzne – krótkie, referencyjne ID, które są mapowane na pełny kontekst w wewnętrznym serwisie autoryzacji.

Gateway może wymieniać token zewnętrzny na wewnętrzny (token exchange), co pozwala ograniczyć rozprzestrzenianie się danych osobowych i uprościć kontrolę uprawnień w środku.

Bezpieczne propagowanie kontekstu użytkownika

Przy kilku warstwach usług pojawia się pokusa przekazywania całego JWT w nagłówkach do następnych serwisów. To bywa wygodne, ale zwiększa powierzchnię ataku.

Bezpieczniejszy wzorzec:

  • serwis przyjmujący żądanie waliduje token i wyciąga minimalny kontekst (np. ID użytkownika, tenant, główną rolę),
  • do dalszych żądań przekazuje tylko te dane w dedykowanych nagłówkach (X-User-Id, X-Tenant-Id),
  • usługi wewnętrzne nie znają szczegółów tokena i nie polegają na nich w decyzjach bezpieczeństwa.

Dla operacji wymagających pełnego kontekstu można przeprowadzić loklane ponowne sprawdzenie uprawnień przez wywołanie serwisu autoryzacji, zamiast reużywania oryginalnego tokena.

Najczęściej zadawane pytania (FAQ)

Co to jest SSO i czym różni się od „wspólnej bazy użytkowników”?

SSO (Single Sign-On) to mechanizm, w którym użytkownik loguje się raz do centralnego dostawcy tożsamości (IdP), a potem korzysta z wielu aplikacji bez ponownego podawania loginu i hasła. Formularz logowania istnieje tylko w jednym miejscu, a aplikacje ufają tokenom zwracanym przez IdP.

„Wspólna baza użytkowników” oznacza, że kilka systemów czyta tę samą tabelę users, ale każdy ma własne logowanie i sesję. Użytkownik i tak musi logować się osobno do każdej aplikacji, więc nie jest to SSO, nawet jeśli dane leżą w jednym magazynie.

Kiedy w firmie opłaca się wdrożyć SSO, a kiedy to przerost formy?

SSO ma sens, gdy ludzie korzystają z wielu aplikacji webowych dziennie (HR, czas pracy, CRM, helpdesk, wiki), gdy wchodzi architektura mikroserwisowa albo prowadzisz kilka produktów z jedną bazą użytkowników. Wtedy każde dodatkowe osobne logowanie zaczyna być kosztem i źródłem błędów.

Przy jednej, prostej aplikacji firmowej zwykle wystarczy lokalne logowanie. Przy dwóch–trzech systemach da się jeszcze „żyć” bez SSO, choć rośnie liczba resetów haseł. Powyżej kilkunastu aplikacji centralne SSO staje się praktycznie koniecznością organizacyjną.

Co wybrać do nowego firmowego SSO: OAuth2, OpenID Connect czy SAML?

Do nowych wdrożeń SSO standardem de facto jest zestaw OAuth2 + OpenID Connect. OAuth2 odpowiada za autoryzację i wydawanie tokenów dostępu, a OpenID Connect dodaje warstwę uwierzytelniania użytkownika (ID Token), którą wykorzystują Twoje aplikacje.

SAML zostaje głównie tam, gdzie masz integracje z dużymi, starszymi środowiskami korporacyjnymi, Active Directory/ADFS albo systemami legacy, które rozumieją tylko SAML. Częsty układ: OIDC jako domyślny standard dla nowych aplikacji, SAML jako „most” do starych systemów.

Jakie są kluczowe korzyści biznesowe z wdrożenia SSO?

Od strony użytkownika pojawia się jedno logowanie zamiast kilku, mniej resetów haseł i szybszy dostęp do narzędzi. Jeśli ktoś zaloguje się do panelu HR, to przy poprawnej konfiguracji od razu ma dostęp np. do CRM czy helpdesku, bez kolejnych formularzy.

Z perspektywy bezpieczeństwa zyskujesz centralne wymuszanie MFA, spójne polityki haseł, blokadę konta w jednym miejscu oraz jeden, ujednolicony strumień logów audytowych. Administracyjnie upraszcza to zarządzanie dostępami przy wejściach, odejściach i zmianach ról w firmie.

Jak wygląda architektura firmowego SSO opartego na popularnych frameworkach?

Centralnym elementem jest Identity Provider (IdP), np. Keycloak, Auth0, Azure AD lub inny serwer zgodny z OAuth2/OIDC. To on obsługuje logowanie, MFA, blokady kont i wystawia tokeny (ID Token, Access Token, Refresh Token).

Każda aplikacja (panel webowy, SPA, API) działa jako klient OAuth2/Relying Party. Zamiast trzymać własny formularz logowania, przekierowuje użytkownika do IdP, a po powrocie dostaje tokeny, które może zweryfikować podpisem. Integracja zwykle odbywa się przez gotowe biblioteki w danym frameworku (np. Spring Security, ASP.NET, biblioteki dla React/Angular).

Jakie przepływy OAuth2 wybrać dla SPA, backendu i usług technicznych?

Dla nowoczesnych aplikacji webowych (SPA w React/Angular/Vue) standardem jest Authorization Code Flow z PKCE. Chroni to przed przechwyceniem kodu autoryzacyjnego i eliminuje konieczność trzymania sekretnych kluczy po stronie przeglądarki.

Dla klasycznych aplikacji backendowych używa się Authorization Code Flow (z PKCE lub bez, zależnie od zaleceń IdP). Do komunikacji serwis–serwis, gdzie nie ma użytkownika, stosuje się Client Credentials Flow, który służy wyłącznie do autoryzacji aplikacji technicznych.

Jakie są typowe problemy przy wdrażaniu SSO w istniejącej organizacji?

Najczęściej wyzwania są organizacyjne: trzeba ujednolicić konta, usunąć duplikaty użytkowników, ustalić właścicieli poszczególnych systemów i proces nadawania uprawnień. Samo „postawienie” IdP jest zwykle łatwiejsze niż te porządki.

Technicznie największą pracą bywa integracja starych aplikacji, które nie znają OAuth2/OIDC ani SAML. Czasem wymaga to dobudowania warstwy pośredniej (np. bramka reverse proxy rozumiejąca tokeny) albo stopniowej modernizacji kodu aplikacji.

1 KOMENTARZ

  1. Ten artykuł na temat budowania własnego systemu SSO w firmie z użyciem popularnych frameworków okazał się być niezwykle pomocny i klarowny. Dzięki niemu dowiedziałem się, jakie kroki należy podjąć, aby skutecznie zaimplementować takie rozwiązanie oraz jakie korzyści może przynieść dla firmy. Bardzo doceniam praktyczne wskazówki oraz przykłady zastosowania różnych frameworków. Teraz mam pewność, że mogę przystąpić do budowy systemu SSO w mojej firmie z większą pewnością siebie i wiedzą na ten temat. Dziękuję autorowi za cenne informacje i inspirację do działania!

Tylko zalogowani mogą dodać komentarz.