Início de sessão único
O início de sessão único permite que um fornecedor de identidade (IdP) externo decida quem pode iniciar sessão no seu servidor do Control Center. São suportados dois protocolos — SAML 2.0 e OpenID Connect — e ambos acabam no mesmo sítio: uma credencial de dispositivo acabada de emitir, indistinguível de um convite ou de um emparelhamento por QR em todo o percurso a jusante.
A forma de um início de sessão
Secção intitulada “A forma de um início de sessão”Os inícios de sessão SAML são intermediados pelo navegador. O IdP nunca abre uma ligação ao seu servidor; é o navegador do utilizador que transporta tudo:
browser ──> /saml/login ──> IdP ──POST SAMLResponse──> /saml/acs │ verify ▼ provision user (maybe) │ ▼ browser handoff: device PSK in the URL fragment (never a query parameter)Como é o navegador que faz de mensageiro, um servidor atrás de NAT funciona bem para inícios de sessão: localhost, LAN, Tailscale, VPN ou um túnel servem todos — só o navegador do utilizador tem de alcançar o URL ACS. O retransmissor WebSocket usado pelo controlo remoto do telemóvel não consegue transportar a ida e volta HTTP, e é por isso que os pontos de entrada de SSO apontam sempre para a origem HTTP do servidor.
O OpenID Connect segue a mesma forma, com uma ida e volta de código de autorização + PKCE; as afirmações são lidas no endpoint de tokens do emissor por TLS, pelo que o navegador nunca fornece dados de identidade.
Os adaptadores
Secção intitulada “Os adaptadores”O Control Center divide a responsabilidade de forma deliberada:
| Componente | Onde | Responsabilidade |
|---|---|---|
cc_saml nativo |
packages/cc_natives/native/saml/ |
verificação de XML-DSig, canonicalização e validação do perfil SAML — delegadas na crate saml em Rust puro e com versão fixada, atrás de uma ABI C sem estado |
SamlService / OidcService |
cc_server_core |
estado de início de sessão (registadores de pedidos pendentes, deduplicação de repetições), parâmetros da política de validação, a chamada de provisionamento partilhada |
SsoProvisioner |
cc_server_core |
localizar ou criar o utilizador, fixar o sujeito do fornecedor, conceder pertenças segundo a política de membro automático |
ScimService |
cc_server_core |
a superfície de envio do SCIM 2.0 (ciclo de vida de provisionamento/desprovisionamento) |
SsoSettingsService |
cc_server_core |
as linhas de ligação guardadas, reaplicação em tempo real, o token SCIM |
Não existe deliberadamente qualquer alternativa de criptografia SAML em Dart
puro: a XML-DSig/canonicalização feitas à mão são exatamente o sítio onde
vivem as vulnerabilidades de encapsulamento de assinatura, pelo que a ausência
da biblioteca cc_saml recusa tanto o início de sessão SAML como o arranque do
servidor. O nativo é, por conceção, sem estado — o estado entre pedidos vive nos
serviços Dart, é de utilização única e de curta duração.
O que um início de sessão verifica
Secção intitulada “O que um início de sessão verifica”Dentro do nativo verificado e do serviço, pela ordem seguinte:
- a assinatura da asserção (sempre obrigatória; a do envelope de resposta é opcional conforme a configuração) — estruturalmente resistente ao encapsulamento de assinatura, porque o payload validado está vinculado ao elemento verificado,
- o emissor coincide com o IdP configurado,
- a audiência nomeia este fornecedor de serviço,
- o destino é o nosso URL ACS,
InResponseTocoincide com um AuthnRequest pendente que emitimos (as respostas não solicitadas, iniciadas pelo IdP, estão desativadas por predefinição),- as janelas de tempo de vida mantêm-se dentro do desvio de relógio (predefinição 90s) e
- o id da asserção nunca foi visto antes (cache de repetições).
As falhas regressam como códigos tipados — signature, expired, audience, destination, issuer, request-match — e os endpoints respondem com erros genéricos, para que um atacante não fique a saber por que razão uma falsificação falhou.
Contas e fixação do sujeito
Secção intitulada “Contas e fixação do sujeito”O primeiro início de sessão por SSO fixa o sujeito imutável do fornecedor
(issuer e o NameID SAML / sub OIDC, ou o externalId SCIM) na conta. A partir
daí, é o sujeito — e não o email — que identifica o início de sessão. Se outra
pessoa apresentar mais tarde o mesmo email a partir do mesmo IdP ou de outro, a
conta fixada recusa essa pessoa. É isto que impede que um email reciclado num
fornecedor se transforme num apoderamento de conta.
Provisionamento e desprovisionamento
Secção intitulada “Provisionamento e desprovisionamento”O provisionamento JIT acontece no início de sessão (SsoProvisioner). O SCIM é
uma superfície de envio separada (ScimService) que fixa o mesmo sujeito na
linha do utilizador; não concede pertenças a espaços de trabalho. O
desprovisionamento — SCIM active: false ou DELETE — é recusado se a conta
for proprietária de um espaço de trabalho (transfira primeiro). Caso contrário,
revoga primeiro todas as credenciais dos dispositivos (as sessões terminam em
segundos através da vigilância dos dispositivos), remove todas as pertenças a
espaços de trabalho e marca a conta como desativada. A linha do utilizador
sobrevive: a atribuição é permanente. A reativação restaura o início de sessão,
mas nunca volta a conceder pertenças.
O que fica de fora
Secção intitulada “O que fica de fora”- O mapeamento grupo→função acontece no início de sessão, a partir dos atributos SAML / das afirmações OIDC — os grupos enviados por SCIM não são armazenados.
- A função de proprietário é inalcançável a partir do SSO — nem como função predefinida nem através de um mapeamento de grupos.
- O retransmissor WebSocket nunca é um canal de SSO; os telemóveis que só alcançam o servidor através do retransmissor não conseguem concluir uma ida e volta pelo navegador contra ele.