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

1
158
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,
  • o