Pular para o conteúdo

Diagrama de fluxo SAML SSO: login iniciado pelo SP e pelo IdP

Como funciona o login único com SAML 2.0: os fluxos iniciados pelo SP e pelo IdP, o que uma resposta SAML contém, o que o seu app precisa verificar e onde ele quebra.

· Fundador e desenvolvedor

Publicado em

Diagrama de sequência: usuário, navegador, provedor de serviço e provedor de identidade. O app redireciona ao IdP com um AuthnRequest; um fragmento opcional mostra login e MFA; o IdP devolve um formulário que envia a SAMLResponse para a URL ACS; o app a valida e define um cookie.

O primeiro cliente grande que assinar um contrato vai pedir login único com o provedor de identidade dele, e muitas vezes isso significa SAML 2.0. O padrão é de 2005, transporta XML por redirecionamentos do navegador e envios de formulário, e as mensagens de erro vão do vago ao silencioso. A maioria dos bugs de SAML, inclusive falhas de segurança graves, vem de não saber exatamente qual mensagem vai para onde e o que o provedor de serviço precisa verificar.

Este post percorre o fluxo iniciado pelo SP mensagem por mensagem com um diagrama de sequência, depois a variante iniciada pelo IdP e seus riscos, a anatomia de uma resposta SAML, a checklist de validação para o seu app, metadados e rotação de certificados, e como o SAML se compara ao OpenID Connect.

As três partes

Parte Em termos de SAML Exemplos
O navegador do usuário Agente do usuário Qualquer navegador
A sua aplicação Provedor de serviço (SP) O seu app SaaS
O sistema de login do cliente Provedor de identidade (IdP) Microsoft Entra ID, Okta, Google Workspace, AD FS

No perfil comum Web Browser SSO, o SP e o IdP nunca falam diretamente um com o outro. Toda mensagem passa pelo navegador, como um redirecionamento ou um formulário enviado automaticamente. O que eles compartilham é configuração, trocada uma vez como metadados: o entity ID de cada lado, a URL de login do IdP, a URL do Assertion Consumer Service (ACS) do SP e o certificado de assinatura do IdP.

O fluxo iniciado pelo SP, passo a passo

O usuário começa no seu app:

  1. O usuário abre https://app.example.com/dashboard sem sessão.
  2. O seu app cria um AuthnRequest com um ID único, o entity ID dele e a URL ACS, guarda o ID no estado de login pendente e redireciona o navegador para o IdP. Com o binding HTTP-Redirect, a requisição vai na query string como SAMLRequest (comprimida com deflate e codificada em base64), ao lado de um valor RelayState que lembra para onde o usuário queria ir.
  3. O IdP autentica o usuário: senha e MFA, ou uma sessão do IdP já existente, caso em que o usuário não vê nada.
  4. O IdP devolve uma página HTML com um formulário que envia por POST uma SAMLResponse assinada e o mesmo RelayState para a sua URL ACS. Esse é o binding HTTP-POST, e um pequeno script envia o formulário automaticamente.
  5. O seu app valida a resposta, cria o próprio cookie de sessão e redireciona o usuário para a página guardada em RelayState.

Dali em diante, é a sessão do próprio app que decide quem é o usuário. O SAML só volta a entrar em cena quando essa sessão expira.

A especificação de bindings limita o RelayState a 80 bytes, então guarde a URL de retorno real no servidor e envie uma chave curta.

O que uma resposta SAML contém

Reduzida às partes que o seu app lê, uma resposta fica assim:

<samlp:Response ID="_r81c" InResponseTo="_req42" Destination="https://app.example.com/saml/acs">
  <saml:Assertion ID="_a77e">
    <saml:Issuer>https://idp.customer.com/entity</saml:Issuer>
    <ds:Signature>…</ds:Signature>
    <saml:Subject>
      <saml:NameID>ana@customer.com</saml:NameID>
      <saml:SubjectConfirmationData InResponseTo="_req42"
        Recipient="https://app.example.com/saml/acs" NotOnOrAfter="2026-11-02T09:05:00Z"/>
    </saml:Subject>
    <saml:Conditions NotBefore="2026-11-02T08:59:30Z" NotOnOrAfter="2026-11-02T09:05:00Z">
      <saml:AudienceRestriction><saml:Audience>https://app.example.com</saml:Audience></saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AttributeStatement>…email, name, groups…</saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>

A asserção é a declaração assinada: quem é o usuário (NameID), quem afirma isso (Issuer), para quem (Audience), por quanto tempo e em resposta a qual requisição (InResponseTo).

A checklist de validação

O seu endpoint ACS é onde a segurança do SAML dá certo ou falha. Ele precisa:

  1. Verificar a assinatura com o certificado dos metadados do IdP, nunca com um certificado embutido na própria mensagem.
  2. Ler só o que a assinatura cobre. Ataques de XML signature wrapping inserem uma segunda asserção, sem assinatura, na esperança de que o código verifique um elemento e leia outro. Pesquisadores encontraram essa falha em 11 de 14 grandes frameworks SAML em 2012, e ela continua voltando: o ruby-saml corrigiu em 2024 um bypass de assinatura com CVSS 10.0 (CVE-2024-45409) e em 2025 dois bypasses por diferença entre parsers (CVE-2025-25291 e CVE-2025-25292).
  3. Verificar o Issuer em relação ao entity ID do IdP desse cliente.
  4. Verificar o Audience em relação ao seu próprio entity ID.
  5. Verificar Destination e Recipient em relação à sua URL ACS.
  6. Verificar NotBefore e NotOnOrAfter com uma tolerância de um ou dois minutos para diferença de relógio.
  7. Casar o InResponseTo com um ID de AuthnRequest que você emitiu para esse navegador e ainda não usou.
  8. Rejeitar replays guardando os IDs das asserções até elas expirarem.
  9. Tratar o RelayState como não confiável. Redirecione só para caminhos relativos ou para uma lista de permissões, ou você terá um open redirect.

A lição de uma década de vulnerabilidades em SAML: use uma biblioteca mantida, fixe a versão, aplique os patches rápido e nunca escreva a sua própria verificação de assinatura XML.

SSO iniciado pelo IdP e por que ele é mais arriscado

No fluxo iniciado pelo IdP, o usuário começa no IdP, normalmente clicando no bloco do seu app em um painel como o portal da Okta ou o Microsoft My Apps. O IdP envia por POST uma resposta não solicitada para a sua URL ACS. Não houve AuthnRequest, então não há InResponseTo para casar.

Iniciado pelo SP Iniciado pelo IdP
Começa em O seu app O portal do IdP
AuthnRequest Sim Não
Verificação do InResponseTo Sim Impossível
Proteção contra CSRF de login Embutida Exige cuidado extra
Deep links Pelo RelayState Costuma cair em uma página padrão

Sem o InResponseTo, um atacante que obtém uma resposta válida, ou que faz o navegador de uma vítima enviar uma, consegue logar a vítima na conta do atacante ou repetir uma resposta roubada dentro da janela de validade. Se os clientes precisam de blocos no painel, o padrão mais seguro é um bloco que abre a URL de login do seu app, que então inicia um fluxo normal iniciado pelo SP. Se você precisar aceitar respostas não solicitadas, mantenha a validade curta, exija IDs de asserção de uso único e libere isso por cliente, e não de forma global.

Metadados, certificados e ambientes multi-tenant

O IdP de cada cliente é uma relação de confiança separada. Guarde por tenant: o entity ID do IdP, a URL de login, os certificados de assinatura e o mapeamento de atributos. O diagrama de arquitetura SaaS multi-tenant mostra onde essa configuração por tenant costuma ficar.

Certificados de assinatura expiram, e um certificado expirado ou trocado é a causa mais comum de um cliente inteiro de repente não conseguir entrar. Aceite dois certificados por IdP durante uma troca, leia a URL de metadados do IdP periodicamente, se ele publicar uma, e dispare alertas semanas antes do vencimento.

O SAML autentica; ele não mantém a sua lista de usuários sincronizada. Criar contas no primeiro login é fácil, mas remover o acesso quando alguém sai exige provisionamento, normalmente SCIM 2.0 (RFC 7644). Sem isso, um funcionário desativado continua com qualquer sessão que o seu app já tenha emitido.

SAML ou OpenID Connect?

SAML 2.0 OpenID Connect
Formato Asserções XML com assinaturas XML JSON, com ID tokens JWT
Transporte Redirecionamentos do navegador e envios de formulário Redirecionamentos mais uma requisição de token por back-channel
Apps mobile e SPAs Desajeitado Projetado para eles
Uso típico SSO corporativo em apps SaaS Login de consumidores, APIs, SSO corporativo moderno

Apps novos podem começar com OpenID Connect, mas os compradores corporativos vão continuar pedindo SAML, por isso a maioria dos produtos B2B suporta os dois. O diagrama de fluxo do OAuth 2.0 cobre o protocolo sobre o qual o OpenID Connect é construído.

O diagrama de SAML SSO

Diagrama de sequência: usuário, navegador, provedor de serviço e provedor de identidade. O app redireciona ao IdP com um AuthnRequest; um fragmento opcional mostra login e MFA; o IdP devolve um formulário que envia a SAMLResponse para a URL ACS; o app a valida e define um cookie.

6 componentes · 11 conexões

Abrir no Archboard
Conteúdo do diagrama
  • User
  • Browser
  • Service provider (your app)
  • Identity provider
  • no IdP session yet
  • 1. Open the app
  • 2. GET /dashboard (no session)
  • 3. 302 to IdP: SAMLRequest + RelayState
  • 4. GET /sso?SAMLRequest=…&RelayState=… (HTTP-Redirect)
  • 5. Login page
  • 6. Password + MFA
  • 7. HTML form: signed SAMLResponse + RelayState
  • 8. POST /saml/acs (HTTP-POST, auto-submit)
  • 9. 302 /dashboard + session cookie
  • 10. GET /dashboard (cookie)
  • 11. 200 OK
Login único SAML iniciado pelo SP. O app redireciona o navegador para o provedor de identidade com um AuthnRequest; o IdP autentica o usuário e envia por POST uma resposta assinada para a URL ACS do app, que a valida antes de criar a própria sessão.

Como ler:

  • Quatro participantes. O usuário, o navegador, o seu app como provedor de serviço e o provedor de identidade. O tempo corre para baixo.
  • O redirecionamento leva o AuthnRequest e o RelayState do seu app até o IdP, pelo navegador.
  • O fragmento opcional é a etapa de login. Com uma sessão do IdP já existente, ele é pulado e o usuário só vê um redirecionamento rápido.
  • O envio do formulário entrega a SAMLResponse assinada à URL ACS. O seu app a valida e define o próprio cookie de sessão.
  • O bloco Markdown lista as verificações que o endpoint ACS precisa fazer.

Desenhar fluxos de SSO que ajudam a depurar

  • Desenhe o navegador como um participante próprio. O SAML é um protocolo de front-channel; esconder o navegador esconde onde as mensagens podem ser interceptadas ou repetidas.
  • Escreva o binding em cada seta: redirecionamento ou POST, e o nome do parâmetro. A maioria dos erros de configuração é uma URL ou um binding errado.
  • Coloque os IDs nas mensagens. Mostrar que o InResponseTo repete o ID da requisição explica por que ele é verificado.
  • Desenhe o fluxo iniciado pelo IdP separadamente, com o risco anotado, em vez de como um ramo do diagrama principal.

O exemplo de diagrama de sequência cobre participantes, fragmentos e rótulos com mais detalhe, e o diagrama de arquitetura zero trust mostra onde o provedor de identidade fica em um modelo de acesso mais amplo.

Monte no Archboard

  1. Entre com Google ou GitHub e crie um diagrama.
  2. Adicione um Ator do pack Sequência para o usuário e depois três nós Linha de vida: Browser, Service provider e Identity provider.
  3. Desenhe as mensagens de cima para baixo como arestas entre as linhas de vida: a primeira requisição, o redirecionamento com SAMLRequest e RelayState, a requisição ao IdP, o formulário com SAMLResponse, o POST na URL ACS e o redirecionamento final com o cookie de sessão.
  4. Adicione um Fragmento combinado do pack Sequência com o operador opt em volta da etapa de login e MFA.
  5. Adicione um bloco Markdown do pack Básico com a checklist de validação.

O exemplo usa 6 nós de diagrama e fica dentro do plano Free.

Perguntas frequentes

Qual é a diferença entre SSO iniciado pelo SP e iniciado pelo IdP? O login iniciado pelo SP começa no seu app, que envia um AuthnRequest ao IdP. O login iniciado pelo IdP começa no portal do IdP, que envia por POST uma resposta não solicitada ao seu app. O segundo não tem uma requisição para casar com a resposta, o que enfraquece a proteção contra replay e CSRF de login.

O que é uma URL ACS? A URL do Assertion Consumer Service é o endpoint do seu app que recebe a resposta SAML por HTTP POST. Ela é configurada no IdP e precisa bater com os valores Destination e Recipient de cada resposta.

Para que serve o RelayState? Ele carrega o lugar que o usuário queria acessar, para que o seu app o leve até lá depois do login. É limitado a 80 bytes e é uma entrada não confiável, então use-o como chave para um estado guardado no servidor ou valide-o contra uma lista de permissões.

O SAML está ultrapassado? Ele é mais antigo que o OpenID Connect e mais difícil de implementar com segurança, mas continua sendo o padrão que muitos provedores de identidade e compradores corporativos esperam. A maioria dos produtos B2B suporta os dois.

O SAML remove usuários quando eles saem da empresa? Não. O SAML só autentica no login. O desprovisionamento precisa de SCIM ou de outra integração de provisionamento, além de durações de sessão razoáveis no seu app.

Comece grátis — um assento, sem cartão de crédito.

Artigos relacionados

← Voltar ao blog

Abra um canvas em um minuto

Entre com Google ou GitHub. Grátis para um assento. Faça upgrade quando a equipe entrar.