Tovább a tartalomhoz

Egyszeri bejelentkezés

Az egyszeri bejelentkezés (SSO) lehetővé teszi, hogy egy külső identitásszolgáltató (IdP) döntse el, ki jelentkezhet be a Control Center szerverére. Két protokoll támogatott — a SAML 2.0 és az OpenID Connect —, és mindkettő ugyanoda fut ki: egy frissen kiállított eszközhitelesítő adatba, amely a továbbiakban mindenhol megkülönböztethetetlen egy meghívótól vagy egy QR-párosítástól.

A SAML-bejelentkezések böngészőn keresztül zajlanak. Az IdP soha nem nyit kapcsolatot a szerveréhez; mindent a felhasználó böngészője visz:

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

Mivel a böngésző a küldönc, a NAT mögötti szerver is kiválóan működik a bejelentkezésekhez: a localhost, a LAN, a Tailscale, a VPN vagy egy alagút egyaránt megfelel — csak a felhasználó böngészőjének kell elérnie az ACS URL-t. A telefonos távoli vezérlés által használt WebSocket-relay nem képes átvinni az HTTP-körfordulót, ezért az SSO belépési pontok mindig a szerver HTTP-originjét célozzák.

Az OpenID Connect ugyanezt a formát követi egy engedélyezési kód + PKCE körfordulóval; a claim-eket a kibocsátó tokenvégpontjáról olvassuk TLS-en keresztül, így a böngésző egyáltalán nem szolgáltat identitásadatot.

A Control Center szándékosan osztja szét a felelősséget:

Elem Hol Felelőssége
cc_saml natív packages/cc_natives/native/saml/ XML-DSig-ellenőrzés, kanonikalizálás, SAML-profil érvényesítése — a rögzített, tiszta Rust saml crate-re bízva egy állapotmentes C ABI mögött
SamlService / OidcService cc_server_core bejelentkezési állapot (függő kérések követése, replay-kiszűrés), az érvényesítési szabályzat kapcsolói, a közös provisionálási hívás
SsoProvisioner cc_server_core a felhasználó megkeresése vagy létrehozása, a szolgáltatói alany rögzítése, tagságok adása az automatikus tagsági szabályzat szerint
ScimService cc_server_core a SCIM 2.0 push-felület (provisionálás/deprovisionálás életciklus)
SsoSettingsService cc_server_core a mentett kapcsolatsorok, az élő újraalkalmazás, a SCIM-token

Szándékosan nincs tiszta Dart SAML-kriptográfiai tartalék megoldás: a kézzel írt XML-DSig/kanonikalizálás pont az a hely, ahol az aláírás-becsomagolási sebezhetőségek élnek, ezért egy hiányzó cc_saml könyvtár a SAML-bejelentkezést és a szerver indítását is megtagadja. A natív rész tervezésénél fogva állapotmentes — a kéréseken átívelő állapot a Dart-szolgáltatásokban él, egyszer használatosan és rövid élettartammal.

Az ellenőrzött natív részen és a szolgáltatáson belül, sorrendben:

  1. az állítás aláírása (mindig kötelező; a válaszborítéké konfigurációtól függően opcionális) — szerkezetileg ellenáll az aláírás-becsomagolásnak, mert az érvényesített hasznos teher a hitelesített elemhez van kötve,
  2. a kibocsátó megegyezik a beállított IdP-vel,
  3. a célközönség ezt a szolgáltatót nevezi meg,
  4. a célállomás a mi ACS URL-ünk,
  5. az InResponseTo egy általunk kiadott, függőben lévő AuthnRequesttel egyezik (a kéretlen, IdP által kezdeményezett válaszok alapértelmezés szerint ki vannak kapcsolva),
  6. az élettartam-ablakok az óraeltérésen belül maradnak (alapértelmezés: 90s) és
  7. az állítás azonosítóját korábban soha nem láttuk (replay-gyorsítótár).

A hibák típusos kódokként jönnek vissza — signature, expired, audience, destination, issuer, request-match —, a végpontok pedig általános hibákkal válaszolnak, így a támadó semmit nem tud meg arról, miért bukott meg egy hamisítvány.

Az első SSO-bejelentkezés rögzíti a szolgáltató megváltoztathatatlan alanyát (issuer, valamint a SAML NameID / az OIDC sub, illetve a SCIM externalId) a fiókhoz. Onnantól az alany — nem az e-mail-cím — azonosítja a bejelentkezést. Ha később valaki más ugyanazzal az e-mail-címmel jelentkezik ugyanattól vagy egy másik IdP-től, a rögzített fiók elutasítja. Ez az, ami megakadályozza, hogy egy szolgáltatónál újrahasznosított e-mail-cím fiókátvétellé váljon.

A JIT-provisionálás bejelentkezéskor történik (SsoProvisioner). A SCIM egy külön push-felület (ScimService), amely ugyanazt az alanyt rögzíti a felhasználói soron; munkaterület-tagságokat nem ad. A deprovisionálás — SCIM active: false vagy DELETE — megtagadja a műveletet, ha a fiók egy munkaterület tulajdonosa (előbb adja át a tulajdonjogot). Ellenkező esetben először visszavon minden eszközhitelesítő adatot (a munkamenetek másodperceken belül megszakadnak az eszközfigyelésen keresztül), eltávolít minden munkaterület-tagságot, és a fiókot deaktiváltként jelöli meg. A felhasználói sor megmarad: a hozzárendelés végleges. Az újraaktiválás helyreállítja a bejelentkezést, de soha nem adja vissza a tagságokat.

  • A csoport→szerep leképezés bejelentkezéskor történik a SAML-attribútumokból / az OIDC claim-ekből — a pusholt SCIM-csoportokat nem tároljuk.
  • A tulajdonos szerep az SSO-ból nem érhető el — sem alapértelmezett szerepként, sem csoportleképezésen keresztül.
  • A WebSocket-relay soha nem SSO-csatorna; azok a telefonok, amelyek a szervert csak a relayen keresztül érik el, nem tudnak vele böngészős körfordulót lebonyolítani.