Przejdź do głównej zawartości

Logowanie jednokrotne

Logowanie jednokrotne pozwala zewnętrznemu dostawcy tożsamości (IdP) decydować, kto może zalogować się do serwera Control Center. Obsługiwane są dwa protokoły — SAML 2.0 i OpenID Connect — a oba kończą w tym samym miejscu: świeżo wygenerowanym poświadczeniu urządzenia, którego na żadnym dalszym etapie nie da się odróżnić od zaproszenia ani parowania przez kod QR.

Logowania SAML są realizowane przez przeglądarkę. IdP nigdy nie otwiera połączenia z Twoim serwerem; wszystko przenosi przeglądarka użytkownika:

browser ──> /saml/login ──> IdP ──POST SAMLResponse──> /saml/acs
│ verify
▼
provision user (maybe)
│
▼
browser handoff: device PSK in the URL
fragment (never a query parameter)

Ponieważ to przeglądarka pełni rolę kuriera, serwer za NAT-em działa bez problemu przy logowaniu: localhost, sieć LAN, Tailscale, VPN czy tunel — każde z nich się sprawdzi; jedynie przeglądarka użytkownika musi dotrzeć pod adres ACS URL. Przekaźnik WebSocket używany przez zdalne sterowanie telefonem nie przenosi pełnej wymiany HTTP, dlatego punkty wejścia SSO zawsze wskazują na origin HTTP serwera.

OpenID Connect przebiega tak samo, z wymianą typu authorization code + PKCE; claims są odczytywane z punktu końcowego tokenów wystawcy przez TLS, więc przeglądarka w ogóle nie dostarcza danych tożsamości.

Control Center celowo rozdziela odpowiedzialności:

Element Gdzie Odpowiada za
natywny cc_saml packages/cc_natives/native/saml/ weryfikacja XML-DSig, kanonikalizacja, walidacja profilu SAML — delegowane do przypiętego, czysto-rustowego crate’a saml za bezstanowym ABI C
SamlService / OidcService cc_server_core stan logowania (trackery oczekujących żądań, deduplikacja powtórzeń), parametry polityki walidacji, wspólne wywołanie aprowizacji
SsoProvisioner cc_server_core znajdź-lub-utwórz użytkownika, przypnij podmiot dostawcy, przyznaj członkostwa zgodnie z polityką automatycznego członkostwa
ScimService cc_server_core powierzchnia wypychania SCIM 2.0 (cykl życia aprowizacji i cofania aprowizacji)
SsoSettingsService cc_server_core zapisane wiersze połączeń, ponowne zastosowanie na żywo, token SCIM

Świadomie nie istnieje czysto-dartowe awaryjne rozwiązanie kryptograficzne dla SAML: ręcznie napisane XML-DSig i kanonikalizacja to dokładnie miejsce, w którym żyją podatności typu signature wrapping, więc brak biblioteki cc_saml blokuje zarówno logowanie SAML, jak i rozruch serwera. Moduł natywny jest z założenia bezstanowy — stan między żądaniami mieszka w usługach Darta, jednorazowy i krótkotrwały.

Wewnątrz zweryfikowanego modułu natywnego i usługi, po kolei:

  1. podpis asercji (zawsze wymagany; podpis koperty odpowiedzi jest opcjonalny zależnie od konfiguracji) — strukturalnie odporny na signature wrapping, ponieważ walidowany ładunek jest powiązany ze zweryfikowanym elementem,
  2. wystawca jest zgodny ze skonfigurowanym IdP,
  3. odbiorca wskazuje tego dostawcę usług,
  4. cel to nasz adres ACS URL,
  5. InResponseTo jest zgodne z oczekującym żądaniem AuthnRequest, które wystawiliśmy (niezamówione odpowiedzi inicjowane przez IdP są domyślnie wyłączone),
  6. przedziały ważności mieszczą się w granicach odchylenia zegara (domyślnie 90 s) oraz
  7. identyfikator asercji nie pojawił się wcześniej (pamięć podręczna powtórzeń).

Błędy wracają jako typowane kody — signature, expired, audience, destination, issuer, request-match — a punkty końcowe odpowiadają ogólnymi błędami, więc atakujący nie dowie się, dlaczego fałszerstwo się nie powiodło.

Pierwsze logowanie SSO przypisuje do konta niezmienny podmiot dostawcy (issuer oraz SAML NameID / OIDC sub, albo SCIM externalId). Od tego momentu to podmiot — a nie adres e-mail — identyfikuje logowanie. Jeśli ktoś później poda ten sam adres e-mail z tego samego lub innego IdP, przypisane konto mu odmówi. To właśnie sprawia, że ponownie przydzielony u dostawcy adres e-mail nie staje się przejęciem konta.

Aprowizacja JIT odbywa się przy logowaniu (SsoProvisioner). SCIM to osobna powierzchnia wypychania (ScimService), która przypisuje ten sam podmiot do wiersza użytkownika; nie przyznaje członkostw w obszarach roboczych. Cofanie aprowizacji — SCIM active: false lub DELETE — odmawia, jeśli konto jest właścicielem obszaru roboczego (najpierw przenieś własność). W przeciwnym razie najpierw unieważnia każde poświadczenie urządzenia (sesje wygasają w ciągu kilku sekund dzięki obserwacji urządzeń), usuwa każde członkostwo w obszarze roboczym i oznacza konto jako dezaktywowane. Wiersz użytkownika przetrwa: atrybucja jest trwała. Reaktywacja przywraca logowanie, ale nigdy nie przyznaje członkostw ponownie.

  • Mapowanie grup na role odbywa się przy logowaniu na podstawie atrybutów SAML / claims OIDC — grupy wypychane przez SCIM nie są przechowywane.
  • Rola właściciela jest nieosiągalna z poziomu SSO — ani jako rola domyślna, ani przez mapowanie grup.
  • Przekaźnik WebSocket nigdy nie jest kanałem SSO; telefony, które docierają do serwera wyłącznie przez przekaźnik, nie mogą przeprowadzić przez niego pełnej wymiany realizowanej w przeglądarce.