Hoppa till innehåll

Enkel inloggning

Enkel inloggning låter en extern identitetsleverantör (IdP) avgöra vem som får logga in på din Control Center-server. Två protokoll stöds — SAML 2.0 och OpenID Connect — och båda landar på samma ställe: en nyutfärdad enhetsuppgift som inte går att skilja från en inbjudan eller QR-parkoppling någonstans nedströms.

SAML-inloggningar förmedlas via webbläsaren. IdP:n öppnar aldrig en anslutning till din server; användarens webbläsare fraktar allt:

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

Eftersom webbläsaren är kuriren fungerar en server bakom NAT utmärkt för inloggningar: localhost, LAN, Tailscale, VPN eller en tunnel duger alla — det är bara användarens webbläsare som måste nå ACS-URL:en. WebSocket-reläet som fjärrstyrningen från telefon använder kan inte frakta HTTP-rundturen, och därför riktar SSO-ingångarna sig alltid mot serverns HTTP-origin.

OpenID Connect följer samma form med en rundtur med auktoriseringskod + PKCE; claims läses från utfärdarens token-endpoint över TLS, så webbläsaren tillhandahåller aldrig några identitetsdata alls.

Control Center delar medvetet upp ansvaret:

Del Var Ansvarar för
Native-biblioteket cc_saml packages/cc_natives/native/saml/ XML-DSig-verifiering, kanonisering, validering av SAML-profilen — delegerat till den fastnålade saml-craten i ren Rust bakom ett tillståndslöst C-ABI
SamlService / OidcService cc_server_core inloggningstillstånd (spårare för väntande förfrågningar, dedup av replay), rattar för valideringspolicyn, det delade provisioneringsanropet
SsoProvisioner cc_server_core hitta eller skapa användaren, fäst leverantörens subjekt, bevilja medlemskap enligt policyn för automatiskt medlemskap
ScimService cc_server_core SCIM 2.0-pushytan (livscykeln för provisionering och avprovisionering)
SsoSettingsService cc_server_core de sparade anslutningsraderna, omtillämpning i realtid, SCIM-token

Det finns medvetet ingen kryptografisk SAML-reservväg i ren Dart: handrullad XML-DSig/kanonisering är precis där sårbarheter för signaturinpackning håller till, så ett saknat cc_saml-bibliotek avvisar både SAML-inloggning och serverstart. Native-modulen är tillståndslös av design — tillstånd mellan förfrågningar ligger i Dart-tjänsterna, för engångsbruk och kortlivat.

Inne i den verifierade native-modulen och tjänsten, i tur och ordning:

  1. assertionens signatur (alltid obligatorisk; svarskuvertets är valfri per konfiguration) — strukturellt motståndskraftig mot signaturinpackning eftersom den validerade nyttolasten är bunden till det verifierade elementet,
  2. utfärdaren matchar den konfigurerade IdP:n,
  3. målgruppen namnger den här tjänsteleverantören,
  4. destinationen är vår ACS-URL,
  5. InResponseTo matchar en väntande AuthnRequest som vi har utfärdat (oombedda, IdP-initierade svar är avstängda som standard),
  6. giltighetsfönstren håller sig inom klockavvikelsen (90 s som standard) och
  7. assertion-id:t har aldrig setts förut (replay-cachen).

Fel kommer tillbaka som typade koder — signature, expired, audience, destination, issuer, request-match — och endpoints svarar med generiska fel, så en angripare får inte veta varför en förfalskning misslyckades.

Den första SSO-inloggningen fäster leverantörens oföränderliga subjekt (issuer plus SAML NameID / OIDC sub, eller SCIM externalId) vid kontot. Från och med då är det subjektet — inte e-postadressen — som identifierar inloggningen. Om någon annan senare uppger samma e-postadress från samma eller en annan IdP avvisar det fastnålade kontot dem. Det är detta som hindrar att en återanvänd e-postadress hos en leverantör blir ett kontoövertagande.

JIT-provisionering sker vid inloggning (SsoProvisioner). SCIM är en separat pushyta (ScimService) som fäster samma subjekt på användarraden; den beviljar inte några arbetsytemedlemskap. Avprovisionering — SCIM active: false eller DELETE — vägrar om kontot är ägare av en arbetsyta (överför först). Annars återkallar den först alla enhetsuppgifter (sessioner faller inom sekunder via enhetsbevakningen), tar bort varje arbetsytemedlemskap och stämplar kontot som inaktiverat. Användarraden består: attributionen är permanent. Återaktivering återställer inloggningen men beviljar aldrig medlemskapen igen.

  • Mappningen grupp→roll sker vid inloggning från SAML-attributen / OIDC-claimen — grupper som pushas via SCIM lagras inte.
  • Ägarrollen går inte att nå från SSO — varken som standardroll eller genom en gruppmappning.
  • WebSocket-reläet är aldrig en SSO-kanal; telefoner som bara når servern via reläet kan inte slutföra en webbläsarrundtur mot den.